diff --git a/crates/consensus/src/lib.rs b/crates/consensus/src/lib.rs index de51fe8..0d166f5 100644 --- a/crates/consensus/src/lib.rs +++ b/crates/consensus/src/lib.rs @@ -20,3 +20,7 @@ pub mod merkle; pub mod preset; pub mod sync_protocol; pub mod types; + +/// re-export +pub use milagro_bls; +pub use ssz_rs; diff --git a/crates/light-client-verifier/Cargo.toml b/crates/light-client-verifier/Cargo.toml index 93965a6..0424c3c 100644 --- a/crates/light-client-verifier/Cargo.toml +++ b/crates/light-client-verifier/Cargo.toml @@ -13,12 +13,12 @@ patricia-merkle-trie = { git = "https://github.com/bluele/patricia-merkle-trie", primitive-types = { version = "0.12.1", default-features = false } rlp = { version = "0.5.2", default-features = false } +rand = { version = "0.8.5", features = ["std", "std_rng"], optional = true} + [dev-dependencies] serde_json = "1.0.91" hex-literal = "0.3.4" rand = { version = "0.8.5", features = ["std", "std_rng"] } -ssz-rs = { git = "https://github.com/bluele/ssz_rs", branch = "serde-no-std", default-features = false, features = ["serde"] } -milagro_bls = { git = "https://github.com/datachainlab/milagro_bls", rev = "bc2b5b5e8d48b7e2e1bfaa56dc2d93e13cb32095", default-features = false } [features] default = ["std"] @@ -27,3 +27,4 @@ std = [ "patricia-merkle-trie/std" ] mock = [] +test-utils = ["std", "mock", "rand"] diff --git a/crates/light-client-verifier/src/consensus.rs b/crates/light-client-verifier/src/consensus.rs index 8fc58dc..4ecbd07 100644 --- a/crates/light-client-verifier/src/consensus.rs +++ b/crates/light-client-verifier/src/consensus.rs @@ -344,6 +344,431 @@ pub fn verify_bls_signatures( } } +#[cfg(any(feature = "test-utils", test))] +pub mod test_utils { + use super::*; + use crate::updates::{ConsensusUpdateInfo, LightClientUpdate}; + use ethereum_consensus::milagro_bls::{ + AggregateSignature, PublicKey as BLSPublicKey, SecretKey as BLSSecretKey, + }; + use ethereum_consensus::ssz_rs::Vector; + use ethereum_consensus::{ + beacon::{BlockNumber, Checkpoint, Epoch, Slot}, + bls::{aggreate_public_key, PublicKey, Signature}, + fork::deneb, + merkle::MerkleTree, + preset::mainnet::DenebBeaconBlock, + sync_protocol::SyncAggregate, + types::U64, + }; + + #[derive(Clone)] + struct Validator { + sk: BLSSecretKey, + } + + impl Validator { + pub fn new() -> Self { + Self { + sk: BLSSecretKey::random(&mut rand::thread_rng()), + } + } + + pub fn sign(&self, msg: H256) -> BLSSignature { + BLSSignature::new(msg.as_bytes(), &self.sk) + } + + pub fn public_key(&self) -> BLSPublicKey { + BLSPublicKey::from_secret_key(&self.sk) + } + } + + #[derive(Clone)] + pub struct MockSyncCommittee { + committee: Vec, + } + + impl Default for MockSyncCommittee { + fn default() -> Self { + Self::new() + } + } + + impl MockSyncCommittee { + pub fn new() -> Self { + let mut committee = Vec::new(); + for _ in 0..SYNC_COMMITTEE_SIZE { + committee.push(Validator::new()); + } + Self { committee } + } + + pub fn to_committee(&self) -> SyncCommittee { + let mut pubkeys = Vec::new(); + for v in self.committee.iter() { + pubkeys.push(v.public_key()); + } + let aggregate_pubkey = aggreate_public_key(&pubkeys.to_vec()).unwrap(); + SyncCommittee { + pubkeys: Vector::from_iter(pubkeys.into_iter().map(PublicKey::from)), + aggregate_pubkey: PublicKey::from(aggregate_pubkey), + } + } + + pub fn sign_header( + &self, + ctx: &C, + signature_slot: U64, + attested_header: BeaconBlockHeader, + sign_num: usize, + ) -> SyncAggregate { + let fork_version_slot = signature_slot.max(1.into()) - 1; + let fork_version = + compute_fork_version(ctx, compute_epoch_at_slot(ctx, fork_version_slot)); + let domain = compute_domain( + ctx, + DOMAIN_SYNC_COMMITTEE, + Some(fork_version), + Some(ctx.genesis_validators_root()), + ) + .unwrap(); + let signing_root = compute_signing_root(attested_header, domain).unwrap(); + self.sign(signing_root, sign_num) + } + + pub fn sign( + &self, + signing_root: H256, + sign_num: usize, + ) -> SyncAggregate { + // let mut sigs = Vec::new(); + let mut agg_sig = AggregateSignature::new(); + let mut sg = SyncAggregate::::default(); + for (i, v) in self.committee.iter().enumerate() { + if i < sign_num { + agg_sig.add(&v.sign(signing_root)); + sg.sync_committee_bits.set(i, true); + } else { + sg.sync_committee_bits.set(i, false); + } + } + sg.sync_committee_signature = Signature::try_from(agg_sig.as_bytes().to_vec()).unwrap(); + sg + } + } + + pub struct MockSyncCommitteeManager { + pub base_period: u64, + pub committees: Vec>, + } + + impl MockSyncCommitteeManager { + pub fn new(base_period: u64, n_period: u64) -> Self { + let mut committees = Vec::new(); + for _ in 0..n_period { + committees.push(MockSyncCommittee::::new()); + } + Self { + base_period, + committees, + } + } + + pub fn get_committee(&self, period: u64) -> &MockSyncCommittee { + let idx = period - self.base_period; + &self.committees[idx as usize] + } + } + + pub fn gen_light_client_update< + const SYNC_COMMITTEE_SIZE: usize, + C: ChainConsensusVerificationContext, + >( + ctx: &C, + signature_slot: Slot, + attested_slot: Slot, + finalized_epoch: Epoch, + execution_state_root: H256, + execution_block_number: BlockNumber, + scm: &MockSyncCommitteeManager, + ) -> ConsensusUpdateInfo { + let signature_period = compute_sync_committee_period_at_slot(ctx, signature_slot); + let attested_period = compute_sync_committee_period_at_slot(ctx, attested_slot); + gen_light_client_update_with_params( + ctx, + signature_slot, + attested_slot, + finalized_epoch, + execution_state_root, + execution_block_number, + scm.get_committee(signature_period.into()), + scm.get_committee((attested_period + 1).into()), + SYNC_COMMITTEE_SIZE, + ) + } + + #[allow(clippy::too_many_arguments)] + pub fn gen_light_client_update_with_params< + const SYNC_COMMITTEE_SIZE: usize, + C: ChainConsensusVerificationContext, + >( + ctx: &C, + signature_slot: Slot, + attested_slot: Slot, + finalized_epoch: Epoch, + execution_state_root: H256, + execution_block_number: BlockNumber, + sync_committee: &MockSyncCommittee, + next_sync_committee: &MockSyncCommittee, + sign_num: usize, + ) -> ConsensusUpdateInfo { + assert!( + sign_num <= SYNC_COMMITTEE_SIZE, + "sign_num must be less than SYNC_COMMITTEE_SIZE({})", + SYNC_COMMITTEE_SIZE + ); + let finalized_block = gen_finalized_beacon_block::( + ctx, + finalized_epoch, + execution_state_root, + execution_block_number, + ); + let finalized_root = hash_tree_root(finalized_block.clone()).unwrap(); + let (attested_block, finalized_checkpoint_branch, _, next_sync_committee_branch) = + gen_attested_beacon_block( + ctx, + attested_slot, + finalized_root, + sync_committee.to_committee(), + next_sync_committee.to_committee(), + ); + + let (_, finalized_execution_branch) = + ethereum_consensus::fork::deneb::test_utils::gen_execution_payload_proof( + &finalized_block.body, + ) + .unwrap(); + let finalized_execution_root = + hash_tree_root(finalized_block.body.execution_payload.clone()) + .unwrap() + .0 + .into(); + + let attested_header = attested_block.to_header(); + let update = LightClientUpdate:: { + attested_header: attested_header.clone(), + finalized_header: (finalized_block.to_header(), finalized_checkpoint_branch), + signature_slot, + sync_aggregate: sync_committee.sign_header( + ctx, + signature_slot, + attested_header, + sign_num, + ), + next_sync_committee: Some(( + next_sync_committee.to_committee(), + next_sync_committee_branch, + )), + }; + + ConsensusUpdateInfo { + light_client_update: update, + finalized_execution_root, + finalized_execution_branch, + } + } + + fn compute_epoch_boundary_slot(ctx: &C, epoch: Epoch) -> Slot { + ctx.slots_per_epoch() * epoch + } + + pub fn gen_attested_beacon_block( + _: &C, + attested_slot: Slot, + finalized_header_root: H256, + current_sync_committee: SyncCommittee, + next_sync_committee: SyncCommittee, + ) -> (DenebBeaconBlock, Vec, Vec, Vec) { + let mut block = DenebBeaconBlock { + slot: attested_slot, + ..Default::default() + }; + + let finalized_checkpoint = Checkpoint { + root: finalized_header_root, + ..Default::default() + }; + let state = DummyDenebBeaconState::::new( + attested_slot.into(), + finalized_checkpoint, + current_sync_committee, + next_sync_committee, + ); + block.state_root = state.tree().root().unwrap().into(); + + let finalized_checkpoint_proof = state.generate_finalized_checkpoint(); + let current_sync_committee_proof = state.generate_current_sync_committee_proof(); + let next_sync_committee_proof = state.generate_next_sync_committee_proof(); + ( + block, + finalized_checkpoint_proof, + current_sync_committee_proof, + next_sync_committee_proof, + ) + } + + pub fn gen_finalized_beacon_block( + ctx: &C, + finalized_epoch: Epoch, + execution_state_root: H256, + execution_block_number: BlockNumber, + ) -> DenebBeaconBlock { + let mut block = DenebBeaconBlock { + slot: compute_epoch_boundary_slot(ctx, finalized_epoch), + ..Default::default() + }; + let mut body = deneb::BeaconBlockBody::default(); + body.execution_payload.state_root = execution_state_root; + body.execution_payload.block_number = execution_block_number; + block.body = body; + block + } + + pub type DummySSZType = [u8; 32]; + + /// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#beaconstate + #[derive(Debug, Clone, Default)] + struct DummyDenebBeaconState { + genesis_time: DummySSZType, + genesis_validators_root: DummySSZType, + pub slot: U64, + fork: DummySSZType, + latest_block_header: DummySSZType, + block_roots: DummySSZType, + state_roots: DummySSZType, + historical_roots: DummySSZType, + eth1_data: DummySSZType, + eth1_data_votes: DummySSZType, + eth1_deposit_index: DummySSZType, + validators: DummySSZType, + balances: DummySSZType, + randao_mixes: DummySSZType, + slashings: DummySSZType, + previous_epoch_participation: DummySSZType, + current_epoch_participation: DummySSZType, + justification_bits: DummySSZType, + previous_justified_checkpoint: DummySSZType, + current_justified_checkpoint: DummySSZType, + pub finalized_checkpoint: Checkpoint, + inactivity_scores: DummySSZType, + pub current_sync_committee: SyncCommittee, + pub next_sync_committee: SyncCommittee, + latest_execution_payload_header: DummySSZType, + next_withdrawal_index: DummySSZType, + next_withdrawal_validator_index: DummySSZType, + historical_summaries: DummySSZType, + } + + impl DummyDenebBeaconState { + pub fn new( + slot: u64, + finalized_checkpoint: Checkpoint, + current_sync_committee: SyncCommittee, + next_sync_committee: SyncCommittee, + ) -> Self { + Self { + slot: slot.into(), + finalized_checkpoint, + current_sync_committee, + next_sync_committee, + ..Default::default() + } + } + + pub fn tree(&self) -> MerkleTree { + use ethereum_consensus::compute::hash_tree_root; + let tree = MerkleTree::from_leaves( + ([ + self.genesis_time, + self.genesis_validators_root, + hash_tree_root(self.slot).unwrap().0, + self.fork, + self.latest_block_header, + self.block_roots, + self.state_roots, + self.historical_roots, + self.eth1_data, + self.eth1_data_votes, + self.eth1_deposit_index, + self.validators, + self.balances, + self.randao_mixes, + self.slashings, + self.previous_epoch_participation, + self.current_epoch_participation, + self.justification_bits, + self.previous_justified_checkpoint, + self.current_justified_checkpoint, + hash_tree_root(self.finalized_checkpoint.clone()).unwrap().0, + self.inactivity_scores, + hash_tree_root(self.current_sync_committee.clone()) + .unwrap() + .0, + hash_tree_root(self.next_sync_committee.clone()).unwrap().0, + self.latest_execution_payload_header, + self.next_withdrawal_index, + self.next_withdrawal_validator_index, + self.historical_summaries, + Default::default(), + Default::default(), + Default::default(), + Default::default(), + ] as [_; 32]) + .as_ref(), + ); + tree + } + + pub fn generate_finalized_checkpoint(&self) -> Vec { + let br: Vec = self + .tree() + .proof(&[20]) + .proof_hashes() + .iter() + .map(|h| H256::from_slice(h)) + .collect(); + let node = hash_tree_root(self.finalized_checkpoint.epoch) + .unwrap() + .0 + .into(); + let mut branch: Vec = Vec::new(); + branch.push(node); + for b in br.iter() { + branch.push(*b); + } + branch + } + + pub fn generate_current_sync_committee_proof(&self) -> Vec { + self.tree() + .proof(&[22]) + .proof_hashes() + .iter() + .map(|h| H256::from_slice(h)) + .collect() + } + + pub fn generate_next_sync_committee_proof(&self) -> Vec { + self.tree() + .proof(&[23]) + .proof_hashes() + .iter() + .map(|h| H256::from_slice(h)) + .collect() + } + } +} + #[cfg(test)] mod tests { use super::*; @@ -507,20 +932,18 @@ mod tests { } mod deneb { - use std::time::SystemTime; - + use super::*; use crate::{ context::{Fraction, LightClientContext}, misbehaviour::{FinalizedHeaderMisbehaviour, NextSyncCommitteeMisbehaviour}, mock::MockStore, }; use ethereum_consensus::{config, types::U64}; - use utils::{ + use std::time::SystemTime; + use test_utils::{ gen_light_client_update, gen_light_client_update_with_params, MockSyncCommitteeManager, }; - use super::*; - #[test] fn test_lc() { let scm = MockSyncCommitteeManager::<32>::new(1, 4); @@ -895,426 +1318,4 @@ mod tests { } } } - - mod utils { - use crate::updates::{ConsensusUpdateInfo, LightClientUpdate}; - - use super::*; - use ethereum_consensus::{ - beacon::{BlockNumber, Checkpoint, Epoch, Slot}, - bls::{aggreate_public_key, PublicKey, Signature}, - fork::deneb, - merkle::MerkleTree, - preset::mainnet::DenebBeaconBlock, - sync_protocol::SyncAggregate, - types::U64, - }; - use milagro_bls::{ - AggregateSignature, PublicKey as BLSPublicKey, SecretKey as BLSSecretKey, - }; - use ssz_rs::Vector; - - #[derive(Clone)] - struct Validator { - sk: BLSSecretKey, - } - - impl Default for Validator { - fn default() -> Self { - Self { - sk: BLSSecretKey::random(&mut rand::thread_rng()), - } - } - } - - impl Validator { - pub fn sign(&self, msg: H256) -> BLSSignature { - BLSSignature::new(msg.as_bytes(), &self.sk) - } - - pub fn public_key(&self) -> BLSPublicKey { - BLSPublicKey::from_secret_key(&self.sk) - } - } - - #[derive(Clone)] - pub struct MockSyncCommittee { - committee: Vec, - } - - impl MockSyncCommittee { - pub fn new() -> Self { - let mut committee = Vec::new(); - for _ in 0..SYNC_COMMITTEE_SIZE { - committee.push(Validator::default()); - } - Self { committee } - } - - pub fn to_committee(&self) -> SyncCommittee { - let mut pubkeys = Vec::new(); - for v in self.committee.iter() { - pubkeys.push(v.public_key()); - } - let aggregate_pubkey = aggreate_public_key(&pubkeys.to_vec()).unwrap(); - SyncCommittee { - pubkeys: Vector::from_iter(pubkeys.into_iter().map(PublicKey::from)), - aggregate_pubkey: PublicKey::from(aggregate_pubkey), - } - } - - pub fn sign_header( - &self, - ctx: &C, - signature_slot: U64, - attested_header: BeaconBlockHeader, - sign_num: usize, - ) -> SyncAggregate { - let fork_version_slot = signature_slot.max(1.into()) - 1; - let fork_version = - compute_fork_version(ctx, compute_epoch_at_slot(ctx, fork_version_slot)); - let domain = compute_domain( - ctx, - DOMAIN_SYNC_COMMITTEE, - Some(fork_version), - Some(ctx.genesis_validators_root()), - ) - .unwrap(); - let signing_root = compute_signing_root(attested_header, domain).unwrap(); - self.sign(signing_root, sign_num) - } - - pub fn sign( - &self, - signing_root: H256, - sign_num: usize, - ) -> SyncAggregate { - // let mut sigs = Vec::new(); - let mut agg_sig = AggregateSignature::new(); - let mut sg = SyncAggregate::::default(); - for (i, v) in self.committee.iter().enumerate() { - if i < sign_num { - agg_sig.add(&v.sign(signing_root)); - sg.sync_committee_bits.set(i, true); - } else { - sg.sync_committee_bits.set(i, false); - } - } - sg.sync_committee_signature = - Signature::try_from(agg_sig.as_bytes().to_vec()).unwrap(); - sg - } - } - - pub struct MockSyncCommitteeManager { - pub base_period: u64, - pub committees: Vec>, - } - - impl MockSyncCommitteeManager { - pub fn new(base_period: u64, n_period: u64) -> Self { - let mut committees = Vec::new(); - for _ in 0..n_period { - committees.push(MockSyncCommittee::::new()); - } - Self { - base_period, - committees, - } - } - - pub fn get_committee(&self, period: u64) -> &MockSyncCommittee { - let idx = period - self.base_period; - &self.committees[idx as usize] - } - } - - pub fn gen_light_client_update< - const SYNC_COMMITTEE_SIZE: usize, - C: ChainConsensusVerificationContext, - >( - ctx: &C, - signature_slot: Slot, - attested_slot: Slot, - finalized_epoch: Epoch, - execution_state_root: H256, - execution_block_number: BlockNumber, - scm: &MockSyncCommitteeManager, - ) -> ConsensusUpdateInfo { - let signature_period = compute_sync_committee_period_at_slot(ctx, signature_slot); - let attested_period = compute_sync_committee_period_at_slot(ctx, attested_slot); - gen_light_client_update_with_params( - ctx, - signature_slot, - attested_slot, - finalized_epoch, - execution_state_root, - execution_block_number, - scm.get_committee(signature_period.into()), - scm.get_committee((attested_period + 1).into()), - SYNC_COMMITTEE_SIZE, - ) - } - - #[allow(clippy::too_many_arguments)] - pub fn gen_light_client_update_with_params< - const SYNC_COMMITTEE_SIZE: usize, - C: ChainConsensusVerificationContext, - >( - ctx: &C, - signature_slot: Slot, - attested_slot: Slot, - finalized_epoch: Epoch, - execution_state_root: H256, - execution_block_number: BlockNumber, - sync_committee: &MockSyncCommittee, - next_sync_committee: &MockSyncCommittee, - sign_num: usize, - ) -> ConsensusUpdateInfo { - assert!( - sign_num <= SYNC_COMMITTEE_SIZE, - "sign_num must be less than SYNC_COMMITTEE_SIZE({})", - SYNC_COMMITTEE_SIZE - ); - let finalized_block = gen_finalized_beacon_block::( - ctx, - finalized_epoch, - execution_state_root, - execution_block_number, - ); - let finalized_root = hash_tree_root(finalized_block.clone()).unwrap(); - let (attested_block, finalized_checkpoint_branch, _, next_sync_committee_branch) = - gen_attested_beacon_block( - ctx, - attested_slot, - finalized_root, - sync_committee.to_committee(), - next_sync_committee.to_committee(), - ); - - let (_, finalized_execution_branch) = - ethereum_consensus::fork::deneb::test_utils::gen_execution_payload_proof( - &finalized_block.body, - ) - .unwrap(); - let finalized_execution_root = - hash_tree_root(finalized_block.body.execution_payload.clone()) - .unwrap() - .0 - .into(); - - let attested_header = attested_block.to_header(); - let update = LightClientUpdate:: { - attested_header: attested_header.clone(), - finalized_header: (finalized_block.to_header(), finalized_checkpoint_branch), - signature_slot, - sync_aggregate: sync_committee.sign_header( - ctx, - signature_slot, - attested_header, - sign_num, - ), - next_sync_committee: Some(( - next_sync_committee.to_committee(), - next_sync_committee_branch, - )), - }; - - ConsensusUpdateInfo { - light_client_update: update, - finalized_execution_root, - finalized_execution_branch, - } - } - - fn compute_epoch_boundary_slot(ctx: &C, epoch: Epoch) -> Slot { - ctx.slots_per_epoch() * epoch - } - - pub fn gen_attested_beacon_block( - _: &C, - attested_slot: Slot, - finalized_header_root: H256, - current_sync_committee: SyncCommittee, - next_sync_committee: SyncCommittee, - ) -> (DenebBeaconBlock, Vec, Vec, Vec) { - let mut block = DenebBeaconBlock { - slot: attested_slot, - ..Default::default() - }; - - let finalized_checkpoint = Checkpoint { - root: finalized_header_root, - ..Default::default() - }; - let state = DummyDenebBeaconState::::new( - attested_slot.into(), - finalized_checkpoint, - current_sync_committee, - next_sync_committee, - ); - block.state_root = state.tree().root().unwrap().into(); - - let finalized_checkpoint_proof = state.generate_finalized_checkpoint(); - let current_sync_committee_proof = state.generate_current_sync_committee_proof(); - let next_sync_committee_proof = state.generate_next_sync_committee_proof(); - ( - block, - finalized_checkpoint_proof, - current_sync_committee_proof, - next_sync_committee_proof, - ) - } - - pub fn gen_finalized_beacon_block( - ctx: &C, - finalized_epoch: Epoch, - execution_state_root: H256, - execution_block_number: BlockNumber, - ) -> DenebBeaconBlock { - let mut block = DenebBeaconBlock { - slot: compute_epoch_boundary_slot(ctx, finalized_epoch), - ..Default::default() - }; - let mut body = deneb::BeaconBlockBody::default(); - body.execution_payload.state_root = execution_state_root; - body.execution_payload.block_number = execution_block_number; - block.body = body; - block - } - - pub type DummySSZType = [u8; 32]; - - /// https://github.com/ethereum/consensus-specs/blob/dev/specs/capella/beacon-chain.md#beaconstate - #[derive(Debug, Clone, Default)] - struct DummyDenebBeaconState { - genesis_time: DummySSZType, - genesis_validators_root: DummySSZType, - pub slot: U64, - fork: DummySSZType, - latest_block_header: DummySSZType, - block_roots: DummySSZType, - state_roots: DummySSZType, - historical_roots: DummySSZType, - eth1_data: DummySSZType, - eth1_data_votes: DummySSZType, - eth1_deposit_index: DummySSZType, - validators: DummySSZType, - balances: DummySSZType, - randao_mixes: DummySSZType, - slashings: DummySSZType, - previous_epoch_participation: DummySSZType, - current_epoch_participation: DummySSZType, - justification_bits: DummySSZType, - previous_justified_checkpoint: DummySSZType, - current_justified_checkpoint: DummySSZType, - pub finalized_checkpoint: Checkpoint, - inactivity_scores: DummySSZType, - pub current_sync_committee: SyncCommittee, - pub next_sync_committee: SyncCommittee, - latest_execution_payload_header: DummySSZType, - next_withdrawal_index: DummySSZType, - next_withdrawal_validator_index: DummySSZType, - historical_summaries: DummySSZType, - } - - impl DummyDenebBeaconState { - pub fn new( - slot: u64, - finalized_checkpoint: Checkpoint, - current_sync_committee: SyncCommittee, - next_sync_committee: SyncCommittee, - ) -> Self { - Self { - slot: slot.into(), - finalized_checkpoint, - current_sync_committee, - next_sync_committee, - ..Default::default() - } - } - - pub fn tree(&self) -> MerkleTree { - use ethereum_consensus::compute::hash_tree_root; - let tree = MerkleTree::from_leaves( - ([ - self.genesis_time, - self.genesis_validators_root, - hash_tree_root(self.slot).unwrap().0, - self.fork, - self.latest_block_header, - self.block_roots, - self.state_roots, - self.historical_roots, - self.eth1_data, - self.eth1_data_votes, - self.eth1_deposit_index, - self.validators, - self.balances, - self.randao_mixes, - self.slashings, - self.previous_epoch_participation, - self.current_epoch_participation, - self.justification_bits, - self.previous_justified_checkpoint, - self.current_justified_checkpoint, - hash_tree_root(self.finalized_checkpoint.clone()).unwrap().0, - self.inactivity_scores, - hash_tree_root(self.current_sync_committee.clone()) - .unwrap() - .0, - hash_tree_root(self.next_sync_committee.clone()).unwrap().0, - self.latest_execution_payload_header, - self.next_withdrawal_index, - self.next_withdrawal_validator_index, - self.historical_summaries, - Default::default(), - Default::default(), - Default::default(), - Default::default(), - ] as [_; 32]) - .as_ref(), - ); - tree - } - - pub fn generate_finalized_checkpoint(&self) -> Vec { - let br: Vec = self - .tree() - .proof(&[20]) - .proof_hashes() - .iter() - .map(|h| H256::from_slice(h)) - .collect(); - let node = hash_tree_root(self.finalized_checkpoint.epoch) - .unwrap() - .0 - .into(); - let mut branch: Vec = Vec::new(); - branch.push(node); - for b in br.iter() { - branch.push(*b); - } - branch - } - - pub fn generate_current_sync_committee_proof(&self) -> Vec { - self.tree() - .proof(&[22]) - .proof_hashes() - .iter() - .map(|h| H256::from_slice(h)) - .collect() - } - - pub fn generate_next_sync_committee_proof(&self) -> Vec { - self.tree() - .proof(&[23]) - .proof_hashes() - .iter() - .map(|h| H256::from_slice(h)) - .collect() - } - } - } }