Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support ssz devnet #418

Draft
wants to merge 7 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
261 changes: 118 additions & 143 deletions Cargo.lock

Large diffs are not rendered by default.

9 changes: 7 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ default-members = ["cli"]
[workspace.dependencies]
# consensus
ssz_types = "0.7.0"
ethereum_ssz_derive = "0.6.0"
ethereum_ssz = "0.6.0"
ethereum_ssz_derive = "0.5.4"
ethereum_ssz = "0.5.4"
tree_hash_derive = "0.7.0"
tree_hash = "0.7.0"
sha2 = "0.9"
Expand Down Expand Up @@ -111,6 +111,11 @@ rand = "0.8.5"

[patch.crates-io]
ethereum_hashing = { git = "https://github.com/ncitron/ethereum_hashing", rev = "7ee70944ed4fabe301551da8c447e4f4ae5e6c35" }
ssz_types = { git = "https://github.com/ncitron/ssz_types", branch = "stable-container" }
ethereum_ssz = { git = "https://github.com/ncitron/ethereum_ssz", branch = "stable-container" }
ethereum_ssz_derive = { git = "https://github.com/ncitron/ethereum_ssz", branch = "stable-container" }
tree_hash = { git = "https://github.com/ncitron/tree_hash", branch = "stable-container" }
tree_hash_derive = { git = "https://github.com/ncitron/tree_hash", branch = "stable-container" }

######################################
# Profiles
Expand Down
1 change: 1 addition & 0 deletions ethereum/consensus-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ superstruct.workspace = true
thiserror.workspace = true
tracing.workspace = true
zduny-wasm-timer.workspace = true
serde_json.workspace = true

[target.'cfg(target_arch = "wasm32")'.dependencies]
getrandom = { version = "0.2", features = ["js"] }
Expand Down
42 changes: 28 additions & 14 deletions ethereum/consensus-core/src/consensus_core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,17 +31,19 @@ pub fn verify_bootstrap<S: ConsensusSpec>(
checkpoint: B256,
forks: &Forks,
) -> Result<()> {
if !is_valid_header::<S>(&bootstrap.header, forks) {
if !is_valid_header::<S>(&bootstrap.header(), forks) {
return Err(ConsensusError::InvalidExecutionPayloadProof.into());
}

let committee_valid = is_current_committee_proof_valid(
&bootstrap.header.beacon(),
&bootstrap.current_sync_committee,
&bootstrap.current_sync_committee_branch,
bootstrap.header().beacon(),
bootstrap.current_sync_committee(),
bootstrap.current_sync_committee_branch(),
bootstrap.header().beacon().slot / S::slots_per_epoch(),
forks,
);

let header_hash = bootstrap.header.beacon().tree_hash_root();
let header_hash = bootstrap.header().beacon().tree_hash_root();
let header_valid = header_hash == checkpoint;

if !header_valid {
Expand Down Expand Up @@ -93,10 +95,10 @@ pub fn apply_bootstrap<S: ConsensusSpec>(
bootstrap: &Bootstrap<S>,
) {
*store = LightClientStore {
finalized_header: bootstrap.header.clone(),
current_sync_committee: bootstrap.current_sync_committee.clone(),
finalized_header: bootstrap.header().clone(),
current_sync_committee: bootstrap.current_sync_committee().clone(),
next_sync_committee: None,
optimistic_header: bootstrap.header.clone(),
optimistic_header: bootstrap.header().clone(),
previous_max_active_participants: 0,
current_max_active_participants: 0,
best_valid_update: None,
Expand Down Expand Up @@ -296,9 +298,11 @@ pub fn verify_generic_update<S: ConsensusSpec>(
}

let is_valid = is_finality_proof_valid(
&update.attested_header.beacon(),
&finalized_header.beacon(),
update.attested_header.beacon(),
finalized_header.beacon(),
finality_branch,
update.attested_header.beacon().slot / S::slots_per_epoch(),
forks,
);

if !is_valid {
Expand All @@ -312,9 +316,11 @@ pub fn verify_generic_update<S: ConsensusSpec>(
if let Some(next_sync_committee) = &update.next_sync_committee {
if let Some(next_sync_committee_branch) = &update.next_sync_committee_branch {
let is_valid = is_next_committee_proof_valid(
&update.attested_header.beacon(),
update.attested_header.beacon(),
next_sync_committee,
next_sync_committee_branch,
update.attested_header.beacon().slot / S::slots_per_epoch(),
forks,
);

if !is_valid {
Expand Down Expand Up @@ -457,7 +463,9 @@ fn has_sync_update<S: ConsensusSpec>(update: &GenericUpdate<S>) -> bool {
}

fn has_finality_update<S: ConsensusSpec>(update: &GenericUpdate<S>) -> bool {
update.finalized_header.is_some() && update.finality_branch.is_some()
let normal = update.finalized_header.is_some() && update.finality_branch.is_some();
let genesis = update.finalized_header.is_none() && update.finality_branch.is_some();
normal || genesis
}

fn verify_sync_committee_signture(
Expand Down Expand Up @@ -488,6 +496,7 @@ fn is_valid_header<S: ConsensusSpec>(header: &LightClientHeader, forks: &Forks)
let execution_branch = header.execution_branch().unwrap();

let valid_execution_type = match execution {
ExecutionPayloadHeader::Electra(_) => epoch >= forks.electra.epoch,
ExecutionPayloadHeader::Deneb(_) => epoch >= forks.deneb.epoch,
ExecutionPayloadHeader::Capella(_) => {
epoch >= forks.capella.epoch && epoch < forks.deneb.epoch
Expand All @@ -497,8 +506,13 @@ fn is_valid_header<S: ConsensusSpec>(header: &LightClientHeader, forks: &Forks)
}
};

let proof_valid =
is_execution_payload_proof_valid(&header.beacon(), execution, execution_branch);
let proof_valid = is_execution_payload_proof_valid(
header.beacon(),
execution,
execution_branch,
epoch,
forks,
);

proof_valid && valid_execution_type
} else {
Expand Down
21 changes: 21 additions & 0 deletions ethereum/consensus-core/src/consensus_spec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,11 @@ use typenum::Unsigned;
pub trait ConsensusSpec: 'static + Default + Sync + Send + Clone + Debug + PartialEq {
type MaxProposerSlashings: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxAttesterSlashings: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxAttesterSlashingsElectra: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxAttestations: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxAttestationsElectra: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxValidatorsPerSlot: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxCommitteesPerSlot: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxDeposits: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxVoluntaryExits: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxBlsToExecutionChanged: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
Expand All @@ -16,6 +20,9 @@ pub trait ConsensusSpec: 'static + Default + Sync + Send + Clone + Debug + Parti
type SlotsPerEpoch: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type EpochsPerSyncCommiteePeriod: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type SyncCommitteeSize: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxWithdrawalRequests: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxDepositRequests: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;
type MaxConsolidationRequests: Unsigned + Default + Debug + Sync + Send + Clone + PartialEq;

fn slots_per_epoch() -> u64 {
Self::SlotsPerEpoch::to_u64()
Expand All @@ -40,7 +47,11 @@ pub struct MainnetConsensusSpec;
impl ConsensusSpec for MainnetConsensusSpec {
type MaxProposerSlashings = typenum::U16;
type MaxAttesterSlashings = typenum::U2;
type MaxAttesterSlashingsElectra = typenum::U1;
type MaxAttestations = typenum::U128;
type MaxAttestationsElectra = typenum::U8;
type MaxCommitteesPerSlot = typenum::U64;
type MaxValidatorsPerSlot = typenum::U131072;
type MaxDeposits = typenum::U16;
type MaxVoluntaryExits = typenum::U16;
type MaxBlsToExecutionChanged = typenum::U16;
Expand All @@ -50,6 +61,9 @@ impl ConsensusSpec for MainnetConsensusSpec {
type SlotsPerEpoch = typenum::U32;
type EpochsPerSyncCommiteePeriod = typenum::U256;
type SyncCommitteeSize = typenum::U512;
type MaxDepositRequests = typenum::U8192;
type MaxWithdrawalRequests = typenum::U16;
type MaxConsolidationRequests = typenum::U1;
}

#[derive(Serialize, Deserialize, Default, Clone, Debug, PartialEq)]
Expand All @@ -58,7 +72,11 @@ pub struct MinimalConsensusSpec;
impl ConsensusSpec for MinimalConsensusSpec {
type MaxProposerSlashings = typenum::U16;
type MaxAttesterSlashings = typenum::U2;
type MaxAttesterSlashingsElectra = typenum::U1;
type MaxAttestations = typenum::U128;
type MaxAttestationsElectra = typenum::U8;
type MaxCommitteesPerSlot = typenum::U4;
type MaxValidatorsPerSlot = typenum::U8192;
type MaxDeposits = typenum::U16;
type MaxVoluntaryExits = typenum::U16;
type MaxBlsToExecutionChanged = typenum::U16;
Expand All @@ -68,4 +86,7 @@ impl ConsensusSpec for MinimalConsensusSpec {
type SlotsPerEpoch = typenum::U8;
type EpochsPerSyncCommiteePeriod = typenum::U8;
type SyncCommitteeSize = typenum::U32;
type MaxDepositRequests = typenum::U4;
type MaxWithdrawalRequests = typenum::U2;
type MaxConsolidationRequests = typenum::U1;
}
54 changes: 46 additions & 8 deletions ethereum/consensus-core/src/proof.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,57 +4,95 @@ use tree_hash::TreeHash;

use crate::{
consensus_spec::ConsensusSpec,
types::{BeaconBlockHeader, ExecutionPayloadHeader, SyncCommittee},
types::{BeaconBlockHeader, ExecutionPayloadHeader, Forks, SyncCommittee},
};

pub fn is_finality_proof_valid(
attested_header: &BeaconBlockHeader,
finality_header: &BeaconBlockHeader,
finality_branch: &[B256],
current_epoch: u64,
forks: &Forks,
) -> bool {
let (index, depth) = if current_epoch >= forks.electra.epoch {
(41, 9)
} else {
(41, 6)
};

is_proof_valid(
attested_header.state_root,
finality_header,
finality_branch,
6,
41,
depth,
index,
)
}

pub fn is_next_committee_proof_valid<S: ConsensusSpec>(
attested_header: &BeaconBlockHeader,
next_committee: &SyncCommittee<S>,
next_committee_branch: &[B256],
current_epoch: u64,
forks: &Forks,
) -> bool {
let (index, depth) = if current_epoch >= forks.electra.epoch {
(23, 8)
} else {
(23, 5)
};

is_proof_valid(
attested_header.state_root,
next_committee,
next_committee_branch,
5,
23,
depth,
index,
)
}

pub fn is_current_committee_proof_valid<S: ConsensusSpec>(
attested_header: &BeaconBlockHeader,
current_committee: &SyncCommittee<S>,
current_committee_branch: &[B256],
current_epoch: u64,
forks: &Forks,
) -> bool {
let (index, depth) = if current_epoch >= forks.electra.epoch {
(22, 8)
} else {
(22, 5)
};

is_proof_valid(
attested_header.state_root,
current_committee,
current_committee_branch,
5,
22,
depth,
index,
)
}

pub fn is_execution_payload_proof_valid(
attested_header: &BeaconBlockHeader,
execution: &ExecutionPayloadHeader,
execution_branch: &[B256],
current_epoch: u64,
forks: &Forks,
) -> bool {
is_proof_valid(attested_header.body_root, execution, execution_branch, 4, 9)
let (index, depth) = if current_epoch >= forks.electra.epoch {
(9, 7)
} else {
(9, 4)
};

is_proof_valid(
attested_header.body_root,
execution,
execution_branch,
depth,
index,
)
}

fn is_proof_valid<T: TreeHash>(
Expand Down
Loading