From 40cbabc12463128a665c1a19baec0fd2851e944e Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Sat, 13 Jan 2024 00:39:29 +0900 Subject: [PATCH 1/7] cargo fmt and move some types into beacon.rs Signed-off-by: Jun Kimura --- crates/consensus/src/beacon.rs | 29 ++++++++++++++++++++++++++++- crates/consensus/src/capella.rs | 33 +++------------------------------ 2 files changed, 31 insertions(+), 31 deletions(-) diff --git a/crates/consensus/src/beacon.rs b/crates/consensus/src/beacon.rs index 1c80d76..d4665ab 100644 --- a/crates/consensus/src/beacon.rs +++ b/crates/consensus/src/beacon.rs @@ -1,7 +1,7 @@ use crate::{ bls::{PublicKey, Signature}, internal_prelude::*, - types::{serde_hex, Bytes32, H256, U64}, + types::{serde_hex, Address, Bytes32, H256, U64}, }; use ssz_rs::{Bitlist, Deserialize, List, Sized, Vector}; use ssz_rs_derive::SimpleSerialize; @@ -194,3 +194,30 @@ pub struct VoluntaryExit { pub epoch: Epoch, pub validator_index: ValidatorIndex, } + +#[derive( + Clone, Debug, PartialEq, Eq, Default, SimpleSerialize, serde::Serialize, serde::Deserialize, +)] +pub struct Withdrawal { + pub index: U64, + pub validator_index: ValidatorIndex, + pub address: Address, + pub amount: Gwei, +} + +#[derive( + Clone, Debug, PartialEq, Eq, Default, SimpleSerialize, serde::Serialize, serde::Deserialize, +)] +pub struct BlsToExecutionChange { + pub validator_index: ValidatorIndex, + pub from_bls_public_key: PublicKey, + pub to_execution_address: Address, +} + +#[derive( + Clone, Debug, PartialEq, Eq, Default, SimpleSerialize, serde::Serialize, serde::Deserialize, +)] +pub struct SignedBlsToExecutionChange { + message: BlsToExecutionChange, + signature: Signature, +} diff --git a/crates/consensus/src/capella.rs b/crates/consensus/src/capella.rs index 07ba9e1..df16507 100644 --- a/crates/consensus/src/capella.rs +++ b/crates/consensus/src/capella.rs @@ -1,11 +1,11 @@ use crate::{ beacon::{ - Attestation, AttesterSlashing, BeaconBlockHeader, Deposit, Eth1Data, Gwei, - ProposerSlashing, Root, SignedVoluntaryExit, Slot, ValidatorIndex, + Attestation, AttesterSlashing, BeaconBlockHeader, Deposit, Eth1Data, ProposerSlashing, + Root, SignedBlsToExecutionChange, SignedVoluntaryExit, Slot, ValidatorIndex, Withdrawal, BLOCK_BODY_EXECUTION_PAYLOAD_LEAF_INDEX, }, bellatrix::EXECUTION_PAYLOAD_TREE_DEPTH, - bls::{PublicKey, Signature}, + bls::Signature, compute::hash_tree_root, errors::Error, execution::BlockNumber, @@ -147,23 +147,6 @@ pub struct BeaconBlockBody< pub bls_to_execution_changes: List, } -#[derive( - Clone, Debug, PartialEq, Eq, Default, SimpleSerialize, serde::Serialize, serde::Deserialize, -)] -pub struct BlsToExecutionChange { - pub validator_index: ValidatorIndex, - pub from_bls_public_key: PublicKey, - pub to_execution_address: Address, -} - -#[derive( - Clone, Debug, PartialEq, Eq, Default, SimpleSerialize, serde::Serialize, serde::Deserialize, -)] -pub struct SignedBlsToExecutionChange { - message: BlsToExecutionChange, - signature: Signature, -} - // Execution /// https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#executionpayload @@ -271,16 +254,6 @@ pub struct ExecutionPayloadHeader< pub withdrawals_root: Root, } -#[derive( - Clone, Debug, PartialEq, Eq, Default, SimpleSerialize, serde::Serialize, serde::Deserialize, -)] -pub struct Withdrawal { - pub index: U64, - pub validator_index: ValidatorIndex, - pub address: Address, - pub amount: Gwei, -} - /// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientbootstrap #[derive(Clone, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] pub struct LightClientBootstrap< From 87b1a7c67bc08139ea70e8f96a67cf19b9bda33a Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Sat, 13 Jan 2024 00:41:11 +0900 Subject: [PATCH 2/7] add deneb types Signed-off-by: Jun Kimura --- crates/consensus/src/deneb.rs | 429 ++++++++++++++++++++++++++++++++++ crates/consensus/src/lib.rs | 1 + 2 files changed, 430 insertions(+) create mode 100644 crates/consensus/src/deneb.rs diff --git a/crates/consensus/src/deneb.rs b/crates/consensus/src/deneb.rs new file mode 100644 index 0000000..5254038 --- /dev/null +++ b/crates/consensus/src/deneb.rs @@ -0,0 +1,429 @@ +use crate::{ + beacon::{ + Attestation, AttesterSlashing, BeaconBlockHeader, Deposit, Eth1Data, ProposerSlashing, + Root, SignedBlsToExecutionChange, SignedVoluntaryExit, Slot, ValidatorIndex, Withdrawal, + }, + bls::Signature, + compute::hash_tree_root, + errors::Error, + execution::BlockNumber, + internal_prelude::*, + sync_protocol::{ + SyncAggregate, SyncCommittee, CURRENT_SYNC_COMMITTEE_DEPTH, EXECUTION_PAYLOAD_DEPTH, + FINALIZED_ROOT_DEPTH, NEXT_SYNC_COMMITTEE_DEPTH, + }, + types::{Address, ByteList, ByteVector, Bytes32, H256, U256, U64}, +}; +use ssz_rs::{Deserialize, List, Merkleized, Sized}; +use ssz_rs_derive::SimpleSerialize; + +/// Beacon Block +/// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblock +#[derive( + Clone, Debug, PartialEq, Eq, Default, SimpleSerialize, serde::Serialize, serde::Deserialize, +)] +pub struct BeaconBlock< + const MAX_PROPOSER_SLASHINGS: usize, + const MAX_VALIDATORS_PER_COMMITTEE: usize, + const MAX_ATTESTER_SLASHINGS: usize, + const MAX_ATTESTATIONS: usize, + const DEPOSIT_CONTRACT_TREE_DEPTH: usize, + const MAX_DEPOSITS: usize, + const MAX_VOLUNTARY_EXITS: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, + const MAX_BYTES_PER_TRANSACTION: usize, + const MAX_TRANSACTIONS_PER_PAYLOAD: usize, + const MAX_WITHDRAWALS_PER_PAYLOAD: usize, + const MAX_BLS_TO_EXECUTION_CHANGES: usize, + const SYNC_COMMITTEE_SIZE: usize, + const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, +> { + pub slot: Slot, + pub proposer_index: ValidatorIndex, + pub parent_root: Root, + pub state_root: Root, + pub body: BeaconBlockBody< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + DEPOSIT_CONTRACT_TREE_DEPTH, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + MAX_BLS_TO_EXECUTION_CHANGES, + SYNC_COMMITTEE_SIZE, + MAX_BLOB_COMMITMENTS_PER_BLOCK, + >, +} + +impl< + const MAX_PROPOSER_SLASHINGS: usize, + const MAX_VALIDATORS_PER_COMMITTEE: usize, + const MAX_ATTESTER_SLASHINGS: usize, + const MAX_ATTESTATIONS: usize, + const DEPOSIT_CONTRACT_TREE_DEPTH: usize, + const MAX_DEPOSITS: usize, + const MAX_VOLUNTARY_EXITS: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, + const MAX_BYTES_PER_TRANSACTION: usize, + const MAX_TRANSACTIONS_PER_PAYLOAD: usize, + const MAX_WITHDRAWALS_PER_PAYLOAD: usize, + const MAX_BLS_TO_EXECUTION_CHANGES: usize, + const SYNC_COMMITTEE_SIZE: usize, + const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, + > + BeaconBlock< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + DEPOSIT_CONTRACT_TREE_DEPTH, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + MAX_BLS_TO_EXECUTION_CHANGES, + SYNC_COMMITTEE_SIZE, + MAX_BLOB_COMMITMENTS_PER_BLOCK, + > +{ + pub fn to_header(self) -> BeaconBlockHeader { + BeaconBlockHeader { + slot: self.slot, + proposer_index: self.proposer_index, + parent_root: self.parent_root, + state_root: self.state_root, + body_root: hash_tree_root(self.body).unwrap(), + } + } +} + +/// Beacon Block Body +/// https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#beaconblockbody +#[derive( + Clone, Debug, PartialEq, Eq, Default, SimpleSerialize, serde::Serialize, serde::Deserialize, +)] +pub struct BeaconBlockBody< + const MAX_PROPOSER_SLASHINGS: usize, + const MAX_VALIDATORS_PER_COMMITTEE: usize, + const MAX_ATTESTER_SLASHINGS: usize, + const MAX_ATTESTATIONS: usize, + const DEPOSIT_CONTRACT_TREE_DEPTH: usize, + const MAX_DEPOSITS: usize, + const MAX_VOLUNTARY_EXITS: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, + const MAX_BYTES_PER_TRANSACTION: usize, + const MAX_TRANSACTIONS_PER_PAYLOAD: usize, + const MAX_WITHDRAWALS_PER_PAYLOAD: usize, + const MAX_BLS_TO_EXECUTION_CHANGES: usize, + const SYNC_COMMITTEE_SIZE: usize, + const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, +> { + pub randao_reveal: Signature, + pub eth1_data: Eth1Data, + pub graffiti: Bytes32, + pub proposer_slashings: List, + pub attester_slashings: + List, MAX_ATTESTER_SLASHINGS>, + pub attestations: List, MAX_ATTESTATIONS>, + pub deposits: List, MAX_DEPOSITS>, + pub voluntary_exits: List, + pub sync_aggregate: SyncAggregate, + pub execution_payload: ExecutionPayload< + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + >, + pub bls_to_execution_changes: List, + pub blob_kzg_commitments: List, +} + +pub type KzgCommitment = ByteVector<48>; + +// Execution + +/// https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#executionpayload +#[derive( + Clone, Debug, PartialEq, Eq, Default, SimpleSerialize, serde::Serialize, serde::Deserialize, +)] +pub struct ExecutionPayload< + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, + const MAX_BYTES_PER_TRANSACTION: usize, + const MAX_TRANSACTIONS_PER_PAYLOAD: usize, + const MAX_WITHDRAWALS_PER_PAYLOAD: usize, +> { + /// Execution block header fields + pub parent_hash: H256, + pub fee_recipient: Address, + pub state_root: H256, + pub receipts_root: H256, + pub logs_bloom: ByteVector, + /// 'difficulty' in the yellow paper + pub prev_randao: H256, + /// 'number' in the yellow paper + pub block_number: BlockNumber, + pub gas_limit: U64, + pub gas_used: U64, + pub timestamp: U64, + pub extra_data: ByteList, + pub base_fee_per_gas: U256, + /// Extra payload fields + /// Hash of execution block + pub block_hash: H256, + pub transactions: List, MAX_TRANSACTIONS_PER_PAYLOAD>, + pub withdrawals: List, + pub blob_gas_used: U64, + pub excess_blob_gas: U64, +} + +impl< + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, + const MAX_BYTES_PER_TRANSACTION: usize, + const MAX_TRANSACTIONS_PER_PAYLOAD: usize, + const MAX_WITHDRAWALS_PER_PAYLOAD: usize, + > + ExecutionPayload< + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + > +{ + pub fn to_header( + mut self, + ) -> ExecutionPayloadHeader { + ExecutionPayloadHeader { + parent_hash: self.parent_hash, + fee_recipient: self.fee_recipient, + state_root: self.state_root, + receipts_root: self.receipts_root, + logs_bloom: self.logs_bloom, + prev_randao: self.prev_randao, + block_number: self.block_number, + gas_limit: self.gas_limit, + gas_used: self.gas_used, + timestamp: self.timestamp, + extra_data: self.extra_data, + base_fee_per_gas: self.base_fee_per_gas, + block_hash: self.block_hash, + transactions_root: Root::from_slice( + self.transactions.hash_tree_root().unwrap().as_bytes(), + ), + withdrawals_root: Root::from_slice( + self.withdrawals.hash_tree_root().unwrap().as_bytes(), + ), + blob_gas_used: self.blob_gas_used, + excess_blob_gas: self.excess_blob_gas, + } + } +} + +/// https://github.com/ethereum/consensus-specs/blob/dev/specs/bellatrix/beacon-chain.md#executionpayloadheader +#[derive( + Clone, Debug, PartialEq, Eq, Default, SimpleSerialize, serde::Serialize, serde::Deserialize, +)] +pub struct ExecutionPayloadHeader< + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, +> { + /// Execution block header fields + pub parent_hash: H256, + pub fee_recipient: Address, + pub state_root: H256, + pub receipts_root: H256, + pub logs_bloom: ByteVector, + /// 'difficulty' in the yellow paper + pub prev_randao: H256, + /// 'number' in the yellow paper + pub block_number: U64, + pub gas_limit: U64, + pub gas_used: U64, + pub timestamp: U64, + pub extra_data: ByteList, + pub base_fee_per_gas: U256, + /// Extra payload fields + /// Hash of execution block + pub block_hash: H256, + pub transactions_root: Root, + pub withdrawals_root: Root, + pub blob_gas_used: U64, + pub excess_blob_gas: U64, +} + +/// https://github.com/ethereum/consensus-specs/blob/dev/specs/altair/light-client/sync-protocol.md#lightclientbootstrap +#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub struct LightClientBootstrap< + const SYNC_COMMITTEE_SIZE: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, +> { + pub header: LightClientHeader, + /// Current sync committee corresponding to `beacon_header.state_root` + pub current_sync_committee: SyncCommittee, + pub current_sync_committee_branch: [H256; CURRENT_SYNC_COMMITTEE_DEPTH], +} + +#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub struct LightClientUpdate< + const SYNC_COMMITTEE_SIZE: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, +> { + /// Header attested to by the sync committee + pub attested_header: LightClientHeader, + /// Next sync committee corresponding to `attested_header.state_root` + pub next_sync_committee: Option<( + SyncCommittee, + [H256; NEXT_SYNC_COMMITTEE_DEPTH], + )>, + /// Finalized header corresponding to `attested_header.state_root` + pub finalized_header: LightClientHeader, + pub finality_branch: [H256; FINALIZED_ROOT_DEPTH], + /// Sync committee aggregate signature + pub sync_aggregate: SyncAggregate, + /// Slot at which the aggregate signature was created (untrusted) + pub signature_slot: Slot, +} + +#[derive(Clone, Debug, Default, PartialEq, Eq, serde::Serialize, serde::Deserialize)] +pub struct LightClientHeader { + /// Header matching the requested beacon block root + pub beacon: BeaconBlockHeader, + pub execution: ExecutionPayloadHeader, + pub execution_branch: [H256; EXECUTION_PAYLOAD_DEPTH], +} + +// TODO each fork's prover implementation is redundant + +pub fn gen_execution_payload_proof< + const MAX_PROPOSER_SLASHINGS: usize, + const MAX_VALIDATORS_PER_COMMITTEE: usize, + const MAX_ATTESTER_SLASHINGS: usize, + const MAX_ATTESTATIONS: usize, + const DEPOSIT_CONTRACT_TREE_DEPTH: usize, + const MAX_DEPOSITS: usize, + const MAX_VOLUNTARY_EXITS: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, + const MAX_BYTES_PER_TRANSACTION: usize, + const MAX_TRANSACTIONS_PER_PAYLOAD: usize, + const MAX_WITHDRAWALS_PER_PAYLOAD: usize, + const MAX_BLS_TO_EXECUTION_CHANGES: usize, + const SYNC_COMMITTEE_SIZE: usize, + const MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, +>( + body: &BeaconBlockBody< + MAX_PROPOSER_SLASHINGS, + MAX_VALIDATORS_PER_COMMITTEE, + MAX_ATTESTER_SLASHINGS, + MAX_ATTESTATIONS, + DEPOSIT_CONTRACT_TREE_DEPTH, + MAX_DEPOSITS, + MAX_VOLUNTARY_EXITS, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + MAX_BYTES_PER_TRANSACTION, + MAX_TRANSACTIONS_PER_PAYLOAD, + MAX_WITHDRAWALS_PER_PAYLOAD, + MAX_BLS_TO_EXECUTION_CHANGES, + SYNC_COMMITTEE_SIZE, + MAX_BLOB_COMMITMENTS_PER_BLOCK, + >, +) -> Result<(Root, Vec), Error> { + let tree = rs_merkle::MerkleTree::::from_leaves(&[ + hash_tree_root(body.randao_reveal.clone()).unwrap().0, + hash_tree_root(body.eth1_data.clone()).unwrap().0, + body.graffiti.0, + hash_tree_root(body.proposer_slashings.clone()).unwrap().0, + hash_tree_root(body.attester_slashings.clone()).unwrap().0, + hash_tree_root(body.attestations.clone()).unwrap().0, + hash_tree_root(body.deposits.clone()).unwrap().0, + hash_tree_root(body.voluntary_exits.clone()).unwrap().0, + hash_tree_root(body.sync_aggregate.clone()).unwrap().0, + hash_tree_root(body.execution_payload.clone()).unwrap().0, + hash_tree_root(body.bls_to_execution_changes.clone()) + .unwrap() + .0, + hash_tree_root(body.blob_kzg_commitments.clone()).unwrap().0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ]); + Ok(( + H256(tree.root().unwrap()), + tree.proof(&[9]) + .proof_hashes() + .into_iter() + .map(|h| H256::from_slice(h)) + .collect(), + )) +} + +pub fn gen_execution_payload_fields_proof< + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, +>( + payload: &ExecutionPayloadHeader, + leaf_indices: &[usize], +) -> Result<(Root, Vec), Error> { + let tree = rs_merkle::MerkleTree::::from_leaves(&[ + payload.parent_hash.0, + hash_tree_root(payload.fee_recipient.clone()).unwrap().0, + payload.state_root.0, + payload.receipts_root.0, + hash_tree_root(payload.logs_bloom.clone()).unwrap().0, + payload.prev_randao.0, + hash_tree_root(payload.block_number).unwrap().0, + hash_tree_root(payload.gas_limit).unwrap().0, + hash_tree_root(payload.gas_used).unwrap().0, + hash_tree_root(payload.timestamp).unwrap().0, + hash_tree_root(payload.extra_data.clone()).unwrap().0, + hash_tree_root(payload.base_fee_per_gas.clone()).unwrap().0, + payload.block_hash.0, + payload.transactions_root.0, + payload.withdrawals_root.0, + hash_tree_root(payload.blob_gas_used).unwrap().0, + hash_tree_root(payload.excess_blob_gas).unwrap().0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ]); + assert_eq!(tree.leaves_len(), 32); + Ok(( + H256(tree.root().unwrap()), + tree.proof(leaf_indices) + .proof_hashes() + .into_iter() + .map(|h| H256::from_slice(h)) + .collect(), + )) +} diff --git a/crates/consensus/src/lib.rs b/crates/consensus/src/lib.rs index 8b43440..8c4a49b 100644 --- a/crates/consensus/src/lib.rs +++ b/crates/consensus/src/lib.rs @@ -14,6 +14,7 @@ pub mod capella; pub mod compute; pub mod config; pub mod context; +pub mod deneb; pub mod errors; pub mod execution; pub mod fork; From 5d43b4d923a2883209cc205072df1eafce870647 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Sat, 13 Jan 2024 00:50:01 +0900 Subject: [PATCH 3/7] update preset for deneb Signed-off-by: Jun Kimura --- crates/consensus/src/preset.rs | 1 + crates/consensus/src/preset/mainnet.rs | 24 ++++++++++++++++++++++++ crates/consensus/src/preset/minimal.rs | 24 ++++++++++++++++++++++++ 3 files changed, 49 insertions(+) diff --git a/crates/consensus/src/preset.rs b/crates/consensus/src/preset.rs index a47e2b2..8c25d71 100644 --- a/crates/consensus/src/preset.rs +++ b/crates/consensus/src/preset.rs @@ -27,6 +27,7 @@ pub struct Preset { pub MAX_DEPOSITS: usize, pub MAX_VOLUNTARY_EXITS: usize, pub MAX_BLS_TO_EXECUTION_CHANGES: usize, + pub MAX_BLOB_COMMITMENTS_PER_BLOCK: usize, /// Execution /// --------------------------------------------------------------- diff --git a/crates/consensus/src/preset/mainnet.rs b/crates/consensus/src/preset/mainnet.rs index 9add58c..ce5e3ba 100644 --- a/crates/consensus/src/preset/mainnet.rs +++ b/crates/consensus/src/preset/mainnet.rs @@ -25,6 +25,7 @@ pub const PRESET: Preset = Preset { BYTES_PER_LOGS_BLOOM: 256, MAX_EXTRA_DATA_BYTES: 32, MAX_WITHDRAWALS_PER_PAYLOAD: 16, + MAX_BLOB_COMMITMENTS_PER_BLOCK: 4096, }; pub type BellatrixBeaconBlock = crate::bellatrix::BeaconBlock< @@ -68,3 +69,26 @@ pub type CapellaExecutionPayloadHeader = crate::capella::ExecutionPayloadHeader< { PRESET.BYTES_PER_LOGS_BLOOM }, { PRESET.MAX_EXTRA_DATA_BYTES }, >; + +pub type DenebBeaconBlock = crate::deneb::BeaconBlock< + { PRESET.MAX_PROPOSER_SLASHINGS }, + { PRESET.MAX_VALIDATORS_PER_COMMITTEE }, + { PRESET.MAX_ATTESTER_SLASHINGS }, + { PRESET.MAX_ATTESTATIONS }, + { PRESET.DEPOSIT_CONTRACT_TREE_DEPTH }, + { PRESET.MAX_DEPOSITS }, + { PRESET.MAX_VOLUNTARY_EXITS }, + { PRESET.BYTES_PER_LOGS_BLOOM }, + { PRESET.MAX_EXTRA_DATA_BYTES }, + { PRESET.MAX_BYTES_PER_TRANSACTION }, + { PRESET.MAX_TRANSACTIONS_PER_PAYLOAD }, + { PRESET.MAX_WITHDRAWALS_PER_PAYLOAD }, + { PRESET.MAX_BLS_TO_EXECUTION_CHANGES }, + { PRESET.SYNC_COMMITTEE_SIZE }, + { PRESET.MAX_BLOB_COMMITMENTS_PER_BLOCK }, +>; + +pub type DenebExecutionPayloadHeader = crate::deneb::ExecutionPayloadHeader< + { PRESET.BYTES_PER_LOGS_BLOOM }, + { PRESET.MAX_EXTRA_DATA_BYTES }, +>; diff --git a/crates/consensus/src/preset/minimal.rs b/crates/consensus/src/preset/minimal.rs index 2f7cbab..765cc95 100644 --- a/crates/consensus/src/preset/minimal.rs +++ b/crates/consensus/src/preset/minimal.rs @@ -25,6 +25,7 @@ pub const PRESET: Preset = Preset { BYTES_PER_LOGS_BLOOM: 256, MAX_EXTRA_DATA_BYTES: 32, MAX_WITHDRAWALS_PER_PAYLOAD: 4, + MAX_BLOB_COMMITMENTS_PER_BLOCK: 16, }; pub type BellatrixBeaconBlock = crate::bellatrix::BeaconBlock< @@ -68,3 +69,26 @@ pub type CapellaExecutionPayloadHeader = crate::capella::ExecutionPayloadHeader< { PRESET.BYTES_PER_LOGS_BLOOM }, { PRESET.MAX_EXTRA_DATA_BYTES }, >; + +pub type DenebBeaconBlock = crate::deneb::BeaconBlock< + { PRESET.MAX_PROPOSER_SLASHINGS }, + { PRESET.MAX_VALIDATORS_PER_COMMITTEE }, + { PRESET.MAX_ATTESTER_SLASHINGS }, + { PRESET.MAX_ATTESTATIONS }, + { PRESET.DEPOSIT_CONTRACT_TREE_DEPTH }, + { PRESET.MAX_DEPOSITS }, + { PRESET.MAX_VOLUNTARY_EXITS }, + { PRESET.BYTES_PER_LOGS_BLOOM }, + { PRESET.MAX_EXTRA_DATA_BYTES }, + { PRESET.MAX_BYTES_PER_TRANSACTION }, + { PRESET.MAX_TRANSACTIONS_PER_PAYLOAD }, + { PRESET.MAX_WITHDRAWALS_PER_PAYLOAD }, + { PRESET.MAX_BLS_TO_EXECUTION_CHANGES }, + { PRESET.SYNC_COMMITTEE_SIZE }, + { PRESET.MAX_BLOB_COMMITMENTS_PER_BLOCK }, +>; + +pub type DenebExecutionPayloadHeader = crate::deneb::ExecutionPayloadHeader< + { PRESET.BYTES_PER_LOGS_BLOOM }, + { PRESET.MAX_EXTRA_DATA_BYTES }, +>; From 743a119126e2712f8bf2123b448442b28ce09e02 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Sat, 13 Jan 2024 00:57:09 +0900 Subject: [PATCH 4/7] add light client update types of deneb Signed-off-by: Jun Kimura --- crates/light-client-verifier/src/updates.rs | 1 + .../src/updates/deneb.rs | 123 ++++++++++++++++++ 2 files changed, 124 insertions(+) create mode 100644 crates/light-client-verifier/src/updates/deneb.rs diff --git a/crates/light-client-verifier/src/updates.rs b/crates/light-client-verifier/src/updates.rs index d563fc2..d1431ec 100644 --- a/crates/light-client-verifier/src/updates.rs +++ b/crates/light-client-verifier/src/updates.rs @@ -11,6 +11,7 @@ use ethereum_consensus::{ }; pub mod bellatrix; pub mod capella; +pub mod deneb; pub trait LightClientBootstrap: core::fmt::Debug + Clone + PartialEq + Eq diff --git a/crates/light-client-verifier/src/updates/deneb.rs b/crates/light-client-verifier/src/updates/deneb.rs new file mode 100644 index 0000000..b7ae598 --- /dev/null +++ b/crates/light-client-verifier/src/updates/deneb.rs @@ -0,0 +1,123 @@ +pub use super::bellatrix::ExecutionUpdateInfo; +use super::{ConsensusUpdate, LightClientBootstrap}; +use core::ops::Deref; +use ethereum_consensus::{ + beacon::{BeaconBlockHeader, Slot}, + compute::hash_tree_root, + deneb::LightClientUpdate, + sync_protocol::{ + SyncAggregate, SyncCommittee, CURRENT_SYNC_COMMITTEE_DEPTH, EXECUTION_PAYLOAD_DEPTH, + FINALIZED_ROOT_DEPTH, NEXT_SYNC_COMMITTEE_DEPTH, + }, + types::H256, +}; + +#[derive(Clone, Debug, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)] +#[serde(transparent)] +pub struct LightClientBootstrapInfo< + const SYNC_COMMITTEE_SIZE: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, +>( + pub ethereum_consensus::deneb::LightClientBootstrap< + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + >, +); + +impl< + const SYNC_COMMITTEE_SIZE: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, + > Deref + for LightClientBootstrapInfo +{ + type Target = ethereum_consensus::deneb::LightClientBootstrap< + SYNC_COMMITTEE_SIZE, + BYTES_PER_LOGS_BLOOM, + MAX_EXTRA_DATA_BYTES, + >; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl< + const SYNC_COMMITTEE_SIZE: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, + > LightClientBootstrap + for LightClientBootstrapInfo +{ + fn beacon_header(&self) -> &BeaconBlockHeader { + &self.0.header.beacon + } + fn current_sync_committee(&self) -> &SyncCommittee { + &self.0.current_sync_committee + } + fn current_sync_committee_branch(&self) -> [H256; CURRENT_SYNC_COMMITTEE_DEPTH] { + self.0.current_sync_committee_branch.clone() + } +} + +#[derive(Clone, Debug, PartialEq, Eq, Default, serde::Serialize, serde::Deserialize)] +pub struct ConsensusUpdateInfo< + const SYNC_COMMITTEE_SIZE: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, +>(pub LightClientUpdate); + +impl< + const SYNC_COMMITTEE_SIZE: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, + > Deref + for ConsensusUpdateInfo +{ + type Target = + LightClientUpdate; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +impl< + const SYNC_COMMITTEE_SIZE: usize, + const BYTES_PER_LOGS_BLOOM: usize, + const MAX_EXTRA_DATA_BYTES: usize, + > ConsensusUpdate + for ConsensusUpdateInfo +{ + fn attested_beacon_header(&self) -> &BeaconBlockHeader { + &self.attested_header.beacon + } + fn next_sync_committee(&self) -> Option<&SyncCommittee> { + self.next_sync_committee.as_ref().map(|c| &c.0) + } + fn next_sync_committee_branch(&self) -> Option<[H256; NEXT_SYNC_COMMITTEE_DEPTH]> { + self.next_sync_committee.as_ref().map(|c| c.1.clone()) + } + fn finalized_beacon_header(&self) -> &BeaconBlockHeader { + &self.finalized_header.beacon + } + fn finalized_beacon_header_branch(&self) -> [H256; FINALIZED_ROOT_DEPTH] { + self.finality_branch.clone() + } + fn finalized_execution_root(&self) -> H256 { + hash_tree_root(self.finalized_header.execution.clone()) + .unwrap() + .0 + .into() + } + fn finalized_execution_branch(&self) -> [H256; EXECUTION_PAYLOAD_DEPTH] { + self.finalized_header.execution_branch.clone() + } + fn sync_aggregate(&self) -> &SyncAggregate { + &self.sync_aggregate + } + fn signature_slot(&self) -> Slot { + self.signature_slot + } +} From c02536dadc077cfd27ac5a77051e91af6358fd47 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Sat, 13 Jan 2024 10:45:42 +0900 Subject: [PATCH 5/7] enable deneb fork for minimal preset Signed-off-by: Jun Kimura --- crates/consensus/src/config/minimal.rs | 6 +++++- crates/consensus/src/deneb.rs | 1 + 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/crates/consensus/src/config/minimal.rs b/crates/consensus/src/config/minimal.rs index 68b9405..6fcc234 100644 --- a/crates/consensus/src/config/minimal.rs +++ b/crates/consensus/src/config/minimal.rs @@ -13,9 +13,13 @@ pub fn get_config() -> Config { fork_parameters: ForkParameters::new( Version([0, 0, 0, 1]), vec![ - ForkParameter::new(Version([4, 0, 0, 1]), U64(u64::MAX)), + // deneb + ForkParameter::new(Version([4, 0, 0, 1]), U64(0)), + // capella ForkParameter::new(Version([3, 0, 0, 1]), U64(0)), + // belatrix ForkParameter::new(Version([2, 0, 0, 1]), U64(0)), + // altair ForkParameter::new(Version([1, 0, 0, 1]), U64(0)), ], ), diff --git a/crates/consensus/src/deneb.rs b/crates/consensus/src/deneb.rs index 5254038..83dc294 100644 --- a/crates/consensus/src/deneb.rs +++ b/crates/consensus/src/deneb.rs @@ -366,6 +366,7 @@ pub fn gen_execution_payload_proof< Default::default(), Default::default(), ]); + assert_eq!(tree.leaves_len(), 16); Ok(( H256(tree.root().unwrap()), tree.proof(&[9]) From 5d534ae5e8ad4be16ec884c67aff6bc0b811e053 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Sat, 13 Jan 2024 11:38:10 +0900 Subject: [PATCH 6/7] improve compile check for merkle leaf number Signed-off-by: Jun Kimura --- crates/consensus/src/bellatrix.rs | 79 +++++++++++--------- crates/consensus/src/capella.rs | 83 +++++++++++---------- crates/consensus/src/deneb.rs | 117 ++++++++++++++++-------------- crates/consensus/src/merkle.rs | 3 + 4 files changed, 152 insertions(+), 130 deletions(-) diff --git a/crates/consensus/src/bellatrix.rs b/crates/consensus/src/bellatrix.rs index 5a7947b..2b8908b 100644 --- a/crates/consensus/src/bellatrix.rs +++ b/crates/consensus/src/bellatrix.rs @@ -8,6 +8,7 @@ use crate::{ errors::Error, execution::BlockNumber, internal_prelude::*, + merkle::MerkleTree, sync_protocol::{ SyncAggregate, SyncCommittee, CURRENT_SYNC_COMMITTEE_DEPTH, EXECUTION_PAYLOAD_DEPTH, FINALIZED_ROOT_DEPTH, NEXT_SYNC_COMMITTEE_DEPTH, @@ -291,24 +292,27 @@ pub fn gen_execution_payload_proof< SYNC_COMMITTEE_SIZE, >, ) -> Result<(Root, [H256; EXECUTION_PAYLOAD_DEPTH]), Error> { - let tree = rs_merkle::MerkleTree::::from_leaves(&[ - hash_tree_root(body.randao_reveal.clone()).unwrap().0, - hash_tree_root(body.eth1_data.clone()).unwrap().0, - body.graffiti.0, - hash_tree_root(body.proposer_slashings.clone()).unwrap().0, - hash_tree_root(body.attester_slashings.clone()).unwrap().0, - hash_tree_root(body.attestations.clone()).unwrap().0, - hash_tree_root(body.deposits.clone()).unwrap().0, - hash_tree_root(body.voluntary_exits.clone()).unwrap().0, - hash_tree_root(body.sync_aggregate.clone()).unwrap().0, - hash_tree_root(body.execution_payload.clone()).unwrap().0, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - ]); + let tree = MerkleTree::from_leaves( + ([ + hash_tree_root(body.randao_reveal.clone()).unwrap().0, + hash_tree_root(body.eth1_data.clone()).unwrap().0, + body.graffiti.0, + hash_tree_root(body.proposer_slashings.clone()).unwrap().0, + hash_tree_root(body.attester_slashings.clone()).unwrap().0, + hash_tree_root(body.attestations.clone()).unwrap().0, + hash_tree_root(body.deposits.clone()).unwrap().0, + hash_tree_root(body.voluntary_exits.clone()).unwrap().0, + hash_tree_root(body.sync_aggregate.clone()).unwrap().0, + hash_tree_root(body.execution_payload.clone()).unwrap().0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ] as [_; 16]) + .as_ref(), + ); let mut branch = [Default::default(); EXECUTION_PAYLOAD_DEPTH]; branch.copy_from_slice( tree.proof(&[BLOCK_BODY_EXECUTION_PAYLOAD_LEAF_INDEX]) @@ -328,24 +332,27 @@ pub fn gen_execution_payload_field_proof< payload: &ExecutionPayloadHeader, leaf_index: usize, ) -> Result<(Root, [H256; EXECUTION_PAYLOAD_TREE_DEPTH]), Error> { - let tree = rs_merkle::MerkleTree::::from_leaves(&[ - payload.parent_hash.0, - hash_tree_root(payload.fee_recipient.clone()).unwrap().0, - payload.state_root.0, - payload.receipts_root.0, - hash_tree_root(payload.logs_bloom.clone()).unwrap().0, - payload.prev_randao.0, - hash_tree_root(payload.block_number).unwrap().0, - hash_tree_root(payload.gas_limit).unwrap().0, - hash_tree_root(payload.gas_used).unwrap().0, - hash_tree_root(payload.timestamp).unwrap().0, - hash_tree_root(payload.extra_data.clone()).unwrap().0, - hash_tree_root(payload.base_fee_per_gas.clone()).unwrap().0, - payload.block_hash.0, - payload.transactions_root.0, - Default::default(), - Default::default(), - ]); + let tree = MerkleTree::from_leaves( + ([ + payload.parent_hash.0, + hash_tree_root(payload.fee_recipient.clone()).unwrap().0, + payload.state_root.0, + payload.receipts_root.0, + hash_tree_root(payload.logs_bloom.clone()).unwrap().0, + payload.prev_randao.0, + hash_tree_root(payload.block_number).unwrap().0, + hash_tree_root(payload.gas_limit).unwrap().0, + hash_tree_root(payload.gas_used).unwrap().0, + hash_tree_root(payload.timestamp).unwrap().0, + hash_tree_root(payload.extra_data.clone()).unwrap().0, + hash_tree_root(payload.base_fee_per_gas.clone()).unwrap().0, + payload.block_hash.0, + payload.transactions_root.0, + Default::default(), + Default::default(), + ] as [_; 16]) + .as_ref(), + ); let mut branch = [Default::default(); EXECUTION_PAYLOAD_TREE_DEPTH]; branch.copy_from_slice( tree.proof(&[leaf_index]) diff --git a/crates/consensus/src/capella.rs b/crates/consensus/src/capella.rs index df16507..04e547b 100644 --- a/crates/consensus/src/capella.rs +++ b/crates/consensus/src/capella.rs @@ -10,6 +10,7 @@ use crate::{ errors::Error, execution::BlockNumber, internal_prelude::*, + merkle::MerkleTree, sync_protocol::{ SyncAggregate, SyncCommittee, CURRENT_SYNC_COMMITTEE_DEPTH, EXECUTION_PAYLOAD_DEPTH, FINALIZED_ROOT_DEPTH, NEXT_SYNC_COMMITTEE_DEPTH, @@ -332,26 +333,29 @@ pub fn gen_execution_payload_proof< SYNC_COMMITTEE_SIZE, >, ) -> Result<(Root, [H256; EXECUTION_PAYLOAD_DEPTH]), Error> { - let tree = rs_merkle::MerkleTree::::from_leaves(&[ - hash_tree_root(body.randao_reveal.clone()).unwrap().0, - hash_tree_root(body.eth1_data.clone()).unwrap().0, - body.graffiti.0, - hash_tree_root(body.proposer_slashings.clone()).unwrap().0, - hash_tree_root(body.attester_slashings.clone()).unwrap().0, - hash_tree_root(body.attestations.clone()).unwrap().0, - hash_tree_root(body.deposits.clone()).unwrap().0, - hash_tree_root(body.voluntary_exits.clone()).unwrap().0, - hash_tree_root(body.sync_aggregate.clone()).unwrap().0, - hash_tree_root(body.execution_payload.clone()).unwrap().0, - hash_tree_root(body.bls_to_execution_changes.clone()) - .unwrap() - .0, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - ]); + let tree = MerkleTree::from_leaves( + ([ + hash_tree_root(body.randao_reveal.clone()).unwrap().0, + hash_tree_root(body.eth1_data.clone()).unwrap().0, + body.graffiti.0, + hash_tree_root(body.proposer_slashings.clone()).unwrap().0, + hash_tree_root(body.attester_slashings.clone()).unwrap().0, + hash_tree_root(body.attestations.clone()).unwrap().0, + hash_tree_root(body.deposits.clone()).unwrap().0, + hash_tree_root(body.voluntary_exits.clone()).unwrap().0, + hash_tree_root(body.sync_aggregate.clone()).unwrap().0, + hash_tree_root(body.execution_payload.clone()).unwrap().0, + hash_tree_root(body.bls_to_execution_changes.clone()) + .unwrap() + .0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ] as [_; 16]) + .as_ref(), + ); let mut branch = [Default::default(); EXECUTION_PAYLOAD_DEPTH]; branch.copy_from_slice( tree.proof(&[BLOCK_BODY_EXECUTION_PAYLOAD_LEAF_INDEX]) @@ -371,24 +375,27 @@ pub fn gen_execution_payload_field_proof< payload: &ExecutionPayloadHeader, leaf_index: usize, ) -> Result<(Root, [H256; EXECUTION_PAYLOAD_TREE_DEPTH]), Error> { - let tree = rs_merkle::MerkleTree::::from_leaves(&[ - payload.parent_hash.0, - hash_tree_root(payload.fee_recipient.clone()).unwrap().0, - payload.state_root.0, - payload.receipts_root.0, - hash_tree_root(payload.logs_bloom.clone()).unwrap().0, - payload.prev_randao.0, - hash_tree_root(payload.block_number).unwrap().0, - hash_tree_root(payload.gas_limit).unwrap().0, - hash_tree_root(payload.gas_used).unwrap().0, - hash_tree_root(payload.timestamp).unwrap().0, - hash_tree_root(payload.extra_data.clone()).unwrap().0, - hash_tree_root(payload.base_fee_per_gas.clone()).unwrap().0, - payload.block_hash.0, - payload.transactions_root.0, - payload.withdrawals_root.0, - Default::default(), - ]); + let tree = MerkleTree::from_leaves( + ([ + payload.parent_hash.0, + hash_tree_root(payload.fee_recipient.clone()).unwrap().0, + payload.state_root.0, + payload.receipts_root.0, + hash_tree_root(payload.logs_bloom.clone()).unwrap().0, + payload.prev_randao.0, + hash_tree_root(payload.block_number).unwrap().0, + hash_tree_root(payload.gas_limit).unwrap().0, + hash_tree_root(payload.gas_used).unwrap().0, + hash_tree_root(payload.timestamp).unwrap().0, + hash_tree_root(payload.extra_data.clone()).unwrap().0, + hash_tree_root(payload.base_fee_per_gas.clone()).unwrap().0, + payload.block_hash.0, + payload.transactions_root.0, + payload.withdrawals_root.0, + Default::default(), + ] as [_; 16]) + .as_ref(), + ); let mut branch = [Default::default(); EXECUTION_PAYLOAD_TREE_DEPTH]; branch.copy_from_slice( tree.proof(&[leaf_index]) diff --git a/crates/consensus/src/deneb.rs b/crates/consensus/src/deneb.rs index 83dc294..776536f 100644 --- a/crates/consensus/src/deneb.rs +++ b/crates/consensus/src/deneb.rs @@ -8,6 +8,7 @@ use crate::{ errors::Error, execution::BlockNumber, internal_prelude::*, + merkle::MerkleTree, sync_protocol::{ SyncAggregate, SyncCommittee, CURRENT_SYNC_COMMITTEE_DEPTH, EXECUTION_PAYLOAD_DEPTH, FINALIZED_ROOT_DEPTH, NEXT_SYNC_COMMITTEE_DEPTH, @@ -346,27 +347,29 @@ pub fn gen_execution_payload_proof< MAX_BLOB_COMMITMENTS_PER_BLOCK, >, ) -> Result<(Root, Vec), Error> { - let tree = rs_merkle::MerkleTree::::from_leaves(&[ - hash_tree_root(body.randao_reveal.clone()).unwrap().0, - hash_tree_root(body.eth1_data.clone()).unwrap().0, - body.graffiti.0, - hash_tree_root(body.proposer_slashings.clone()).unwrap().0, - hash_tree_root(body.attester_slashings.clone()).unwrap().0, - hash_tree_root(body.attestations.clone()).unwrap().0, - hash_tree_root(body.deposits.clone()).unwrap().0, - hash_tree_root(body.voluntary_exits.clone()).unwrap().0, - hash_tree_root(body.sync_aggregate.clone()).unwrap().0, - hash_tree_root(body.execution_payload.clone()).unwrap().0, - hash_tree_root(body.bls_to_execution_changes.clone()) - .unwrap() - .0, - hash_tree_root(body.blob_kzg_commitments.clone()).unwrap().0, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - ]); - assert_eq!(tree.leaves_len(), 16); + let tree = MerkleTree::from_leaves( + ([ + hash_tree_root(body.randao_reveal.clone()).unwrap().0, + hash_tree_root(body.eth1_data.clone()).unwrap().0, + body.graffiti.0, + hash_tree_root(body.proposer_slashings.clone()).unwrap().0, + hash_tree_root(body.attester_slashings.clone()).unwrap().0, + hash_tree_root(body.attestations.clone()).unwrap().0, + hash_tree_root(body.deposits.clone()).unwrap().0, + hash_tree_root(body.voluntary_exits.clone()).unwrap().0, + hash_tree_root(body.sync_aggregate.clone()).unwrap().0, + hash_tree_root(body.execution_payload.clone()).unwrap().0, + hash_tree_root(body.bls_to_execution_changes.clone()) + .unwrap() + .0, + hash_tree_root(body.blob_kzg_commitments.clone()).unwrap().0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ] as [_; 16]) + .as_ref(), + ); Ok(( H256(tree.root().unwrap()), tree.proof(&[9]) @@ -384,41 +387,43 @@ pub fn gen_execution_payload_fields_proof< payload: &ExecutionPayloadHeader, leaf_indices: &[usize], ) -> Result<(Root, Vec), Error> { - let tree = rs_merkle::MerkleTree::::from_leaves(&[ - payload.parent_hash.0, - hash_tree_root(payload.fee_recipient.clone()).unwrap().0, - payload.state_root.0, - payload.receipts_root.0, - hash_tree_root(payload.logs_bloom.clone()).unwrap().0, - payload.prev_randao.0, - hash_tree_root(payload.block_number).unwrap().0, - hash_tree_root(payload.gas_limit).unwrap().0, - hash_tree_root(payload.gas_used).unwrap().0, - hash_tree_root(payload.timestamp).unwrap().0, - hash_tree_root(payload.extra_data.clone()).unwrap().0, - hash_tree_root(payload.base_fee_per_gas.clone()).unwrap().0, - payload.block_hash.0, - payload.transactions_root.0, - payload.withdrawals_root.0, - hash_tree_root(payload.blob_gas_used).unwrap().0, - hash_tree_root(payload.excess_blob_gas).unwrap().0, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - Default::default(), - ]); - assert_eq!(tree.leaves_len(), 32); + let tree = MerkleTree::from_leaves( + ([ + payload.parent_hash.0, + hash_tree_root(payload.fee_recipient.clone()).unwrap().0, + payload.state_root.0, + payload.receipts_root.0, + hash_tree_root(payload.logs_bloom.clone()).unwrap().0, + payload.prev_randao.0, + hash_tree_root(payload.block_number).unwrap().0, + hash_tree_root(payload.gas_limit).unwrap().0, + hash_tree_root(payload.gas_used).unwrap().0, + hash_tree_root(payload.timestamp).unwrap().0, + hash_tree_root(payload.extra_data.clone()).unwrap().0, + hash_tree_root(payload.base_fee_per_gas.clone()).unwrap().0, + payload.block_hash.0, + payload.transactions_root.0, + payload.withdrawals_root.0, + hash_tree_root(payload.blob_gas_used).unwrap().0, + hash_tree_root(payload.excess_blob_gas).unwrap().0, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ] as [_; 32]) + .as_ref(), + ); Ok(( H256(tree.root().unwrap()), tree.proof(leaf_indices) diff --git a/crates/consensus/src/merkle.rs b/crates/consensus/src/merkle.rs index e88d309..189f110 100644 --- a/crates/consensus/src/merkle.rs +++ b/crates/consensus/src/merkle.rs @@ -1,6 +1,9 @@ use crate::{beacon::Root, errors::MerkleError, internal_prelude::*, types::H256}; use sha2::{Digest, Sha256}; +/// MerkleTree is a merkle tree implementation using sha256 as a hashing algorithm. +pub type MerkleTree = rs_merkle::MerkleTree; + /// Check if ``leaf`` at ``index`` verifies against the Merkle ``root`` and ``branch``. /// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#is_valid_merkle_branch pub fn is_valid_merkle_branch( From da939e8c7d6b4974987b53c637899de9d9d7fe44 Mon Sep 17 00:00:00 2001 From: Jun Kimura Date: Sun, 14 Jan 2024 22:48:03 +0900 Subject: [PATCH 7/7] add constant `EXECUTION_PAYLOAD_TREE_DEPTH` for deneb Signed-off-by: Jun Kimura --- crates/consensus/src/deneb.rs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/crates/consensus/src/deneb.rs b/crates/consensus/src/deneb.rs index 776536f..17c0d4e 100644 --- a/crates/consensus/src/deneb.rs +++ b/crates/consensus/src/deneb.rs @@ -18,6 +18,9 @@ use crate::{ use ssz_rs::{Deserialize, List, Merkleized, Sized}; use ssz_rs_derive::SimpleSerialize; +/// Execution payload tree depth +pub const EXECUTION_PAYLOAD_TREE_DEPTH: usize = 5; + /// Beacon Block /// https://github.com/ethereum/consensus-specs/blob/dev/specs/phase0/beacon-chain.md#beaconblock #[derive(