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

Add validation for supported fork #18

Merged
merged 1 commit into from
Nov 10, 2024
Merged
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
33 changes: 29 additions & 4 deletions crates/consensus/src/fork.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,11 @@ pub const GENESIS_SPEC: ForkSpec = ForkSpec {
execution_payload_block_number_gindex: 0,
};

pub const ALTAIR_INDEX: usize = 0;
pub const BELLATRIX_INDEX: usize = 1;
pub const CAPELLA_INDEX: usize = 2;
pub const DENEB_INDEX: usize = 3;

/// Fork parameters for the beacon chain
#[derive(Debug, Default, Clone, PartialEq, Eq, serde::Serialize, serde::Deserialize)]
pub struct ForkParameters {
Expand Down Expand Up @@ -63,19 +68,32 @@ impl ForkParameters {
/// Compute the fork version for the given epoch
pub fn compute_fork_version(&self, epoch: Epoch) -> Version {
self.compute_fork(epoch)
.map(|f| f.version)
.map(|(_, f)| f.version.clone())
.unwrap_or(self.genesis_version.clone())
}

/// Compute the fork spec for the given epoch
pub fn compute_fork_spec(&self, epoch: Epoch) -> ForkSpec {
self.compute_fork(epoch)
.map(|f| f.spec)
.map(|(_, f)| f.spec.clone())
.unwrap_or(GENESIS_SPEC)
}

fn compute_fork(&self, epoch: Epoch) -> Option<ForkParameter> {
self.forks.iter().rev().find(|f| epoch >= f.epoch).cloned()
/// Returns a boolean indicating whether the given epoch is after the fork
pub fn is_fork(&self, epoch: Epoch, fork_index: usize) -> bool {
if let Some((current, _)) = self.compute_fork(epoch) {
current >= fork_index
} else {
false
}
}

fn compute_fork(&self, epoch: Epoch) -> Option<(usize, &ForkParameter)> {
self.forks
.iter()
.enumerate()
.rev()
.find(|(_, f)| epoch >= f.epoch)
}
}

Expand Down Expand Up @@ -169,6 +187,13 @@ mod tests {
assert_eq!(params.compute_fork_version(2.into()), Version([3, 0, 0, 1]));
assert_eq!(params.compute_fork_version(3.into()), Version([4, 0, 0, 1]));
assert_eq!(params.compute_fork_version(4.into()), Version([4, 0, 0, 1]));
assert!(params.is_fork(0.into(), ALTAIR_INDEX));
assert!(!params.is_fork(0.into(), BELLATRIX_INDEX));
assert!(params.is_fork(1.into(), ALTAIR_INDEX));
assert!(params.is_fork(1.into(), BELLATRIX_INDEX));
assert!(!params.is_fork(1.into(), CAPELLA_INDEX));
assert!(params.is_fork(3.into(), DENEB_INDEX));
assert!(params.is_fork(4.into(), DENEB_INDEX));

let res = ForkParameters::new(
Version([0, 0, 0, 1]),
Expand Down
10 changes: 9 additions & 1 deletion crates/light-client-verifier/src/consensus.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use ethereum_consensus::compute::{
compute_sync_committee_period_at_slot, hash_tree_root,
};
use ethereum_consensus::context::ChainContext;
use ethereum_consensus::fork::ForkSpec;
use ethereum_consensus::fork::{ForkSpec, BELLATRIX_INDEX};
use ethereum_consensus::merkle::is_valid_normalized_merkle_branch;
use ethereum_consensus::sync_protocol::SyncCommittee;
use ethereum_consensus::types::H256;
Expand Down Expand Up @@ -249,6 +249,14 @@ pub fn validate_light_client_update<
consensus_update: &CU,
) -> Result<(), Error> {
consensus_update.validate_basic(ctx)?;
let finalized_epoch =
compute_epoch_at_slot(ctx, consensus_update.finalized_beacon_header().slot);
if !ctx
.fork_parameters()
.is_fork(finalized_epoch, BELLATRIX_INDEX)
{
return Err(Error::ForkNotSupported(finalized_epoch));
}

let current_period = store.current_period(ctx);
let signature_period =
Expand Down
4 changes: 3 additions & 1 deletion crates/light-client-verifier/src/errors.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use crate::internal_prelude::*;
use displaydoc::Display;
use ethereum_consensus::{
beacon::{BeaconBlockHeader, Root, Slot},
beacon::{BeaconBlockHeader, Epoch, Root, Slot},
bls::PublicKey,
errors::MerkleError,
sync_protocol::SyncCommitteePeriod,
Expand All @@ -13,6 +13,8 @@ type BoxedTrieError = Box<TrieError<primitive_types::H256, rlp::DecoderError>>;

#[derive(Debug, Display)]
pub enum Error {
/// the light client does not support the fork corresponding to the finalized epoch: `epoch={0}`
ForkNotSupported(Epoch),
/// unexpected signature period: `store={0} signature={1} reason={2}`
UnexpectedSingaturePeriod(SyncCommitteePeriod, SyncCommitteePeriod, String),
/// unexpected attested period: `store={0} attested={1} reason={2}`
Expand Down