Skip to content

Commit

Permalink
Remove gossip verification changes (sigp#5783).
Browse files Browse the repository at this point in the history
  • Loading branch information
jimmygchen committed Jul 22, 2024
1 parent 0ef9a1a commit 8e0fa1b
Show file tree
Hide file tree
Showing 7 changed files with 14 additions and 806 deletions.
6 changes: 2 additions & 4 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ use crate::observed_aggregates::{
use crate::observed_attesters::{
ObservedAggregators, ObservedAttesters, ObservedSyncAggregators, ObservedSyncContributors,
};
use crate::observed_blob_sidecars::ObservedBlobSidecars;
use crate::observed_block_producers::ObservedBlockProducers;
use crate::observed_data_sidecars::ObservedDataSidecars;
use crate::observed_operations::{ObservationOutcome, ObservedOperations};
use crate::observed_slashable::ObservedSlashable;
use crate::persisted_beacon_chain::{PersistedBeaconChain, DUMMY_CANONICAL_HEAD_BLOCK_ROOT};
Expand Down Expand Up @@ -427,9 +427,7 @@ pub struct BeaconChain<T: BeaconChainTypes> {
/// Maintains a record of which validators have proposed blocks for each slot.
pub observed_block_producers: RwLock<ObservedBlockProducers<T::EthSpec>>,
/// Maintains a record of blob sidecars seen over the gossip network.
pub observed_blob_sidecars: RwLock<ObservedDataSidecars<BlobSidecar<T::EthSpec>>>,
/// Maintains a record of column sidecars seen over the gossip network.
pub observed_column_sidecars: RwLock<ObservedDataSidecars<DataColumnSidecar<T::EthSpec>>>,
pub observed_blob_sidecars: RwLock<ObservedBlobSidecars<T::EthSpec>>,
/// Maintains a record of slashable message seen over the gossip network or RPC.
pub observed_slashable: RwLock<ObservedSlashable<T::EthSpec>>,
/// Maintains a record of which validators have submitted voluntary exits.
Expand Down
4 changes: 1 addition & 3 deletions beacon_node/beacon_chain/src/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ use crate::graffiti_calculator::{GraffitiCalculator, GraffitiOrigin};
use crate::head_tracker::HeadTracker;
use crate::light_client_server_cache::LightClientServerCache;
use crate::migrate::{BackgroundMigrator, MigratorConfig};
use crate::observed_data_sidecars::ObservedDataSidecars;
use crate::persisted_beacon_chain::PersistedBeaconChain;
use crate::shuffling_cache::{BlockShufflingIds, ShufflingCache};
use crate::timeout_rw_lock::TimeoutRwLock;
Expand Down Expand Up @@ -919,8 +918,7 @@ where
observed_sync_aggregators: <_>::default(),
// TODO: allow for persisting and loading the pool from disk.
observed_block_producers: <_>::default(),
observed_column_sidecars: RwLock::new(ObservedDataSidecars::new(self.spec.clone())),
observed_blob_sidecars: RwLock::new(ObservedDataSidecars::new(self.spec.clone())),
observed_blob_sidecars: <_>::default(),
observed_slashable: <_>::default(),
observed_voluntary_exits: <_>::default(),
observed_proposer_slashings: <_>::default(),
Expand Down
253 changes: 6 additions & 247 deletions beacon_node/beacon_chain/src/data_column_verification.rs
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
use crate::block_verification::{
cheap_state_advance_to_obtain_committees, get_validator_pubkey_cache, process_block_slash_info,
BlockSlashInfo,
};
use crate::block_verification::{process_block_slash_info, BlockSlashInfo};
use crate::{BeaconChain, BeaconChainError, BeaconChainTypes};
use derivative::Derivative;
use fork_choice::ProtoBlock;
use kzg::{Error as KzgError, Kzg};
use proto_array::Block;
use slasher::test_utils::E;
use slog::debug;
use slot_clock::SlotClock;
use ssz_derive::{Decode, Encode};
use std::sync::Arc;
use types::data_column_sidecar::{ColumnIndex, DataColumnIdentifier};
use types::{
BeaconStateError, ChainSpec, DataColumnSidecar, DataColumnSubnetId, EthSpec, Hash256,
RuntimeVariableList, SignedBeaconBlockHeader, Slot,
BeaconStateError, DataColumnSidecar, EthSpec, Hash256, RuntimeVariableList,
SignedBeaconBlockHeader, Slot,
};

/// An error occurred while validating a gossip data column.
Expand Down Expand Up @@ -240,257 +232,24 @@ pub fn verify_kzg_for_data_column_list<'a, E: EthSpec, I>(
where
I: Iterator<Item = &'a Arc<DataColumnSidecar<E>>> + Clone,
{
// TODO(das): KZG verification to be implemented
// TODO(das): implement KZG verification
Ok(())
}

pub fn validate_data_column_sidecar_for_gossip<T: BeaconChainTypes>(
data_column: Arc<DataColumnSidecar<T::EthSpec>>,
subnet: u64,
_subnet: u64,
chain: &BeaconChain<T>,
) -> Result<GossipVerifiedDataColumn<T>, GossipDataColumnError<T::EthSpec>> {
let column_slot = data_column.slot();

verify_index_matches_subnet(&data_column, subnet, &chain.spec)?;
verify_sidecar_not_from_future_slot(chain, column_slot)?;
verify_slot_greater_than_latest_finalized_slot(chain, column_slot)?;
verify_is_first_sidecar(chain, &data_column)?;
verify_column_inclusion_proof(&data_column)?;
let parent_block = verify_parent_block_and_finalized_descendant(data_column.clone(), chain)?;
verify_slot_higher_than_parent(&parent_block, column_slot)?;
verify_proposer_and_signature(&data_column, &parent_block, chain)?;

// TODO(das): implement gossip verification
let kzg = chain
.kzg
.clone()
.ok_or(GossipDataColumnError::KzgNotInitialized)?;
let kzg_verified_data_column = verify_kzg_for_data_column(data_column.clone(), &kzg)
.map_err(GossipDataColumnError::InvalidKzgProof)?;

chain
.observed_slashable
.write()
.observe_slashable(
column_slot,
data_column.block_proposer_index(),
data_column.block_root(),
)
.map_err(|e| GossipDataColumnError::BeaconChainError(e.into()))?;

Ok(GossipVerifiedDataColumn {
block_root: data_column.block_root(),
data_column: kzg_verified_data_column,
})
}

// Verify that this is the first column sidecar received for the tuple:
// (block_header.slot, block_header.proposer_index, column_sidecar.index)
fn verify_is_first_sidecar<T: BeaconChainTypes>(
chain: &BeaconChain<T>,
data_column: &DataColumnSidecar<T::EthSpec>,
) -> Result<(), GossipDataColumnError<T::EthSpec>> {
if chain
.observed_column_sidecars
.read()
.proposer_is_known(data_column)
.map_err(|e| GossipDataColumnError::BeaconChainError(e.into()))?
{
return Err(GossipDataColumnError::PriorKnown {
proposer: data_column.block_proposer_index(),
slot: data_column.slot(),
index: data_column.index,
});
}
Ok(())
}

fn verify_column_inclusion_proof<E: EthSpec>(
_data_column: &DataColumnSidecar<E>,
) -> Result<(), GossipDataColumnError<E>> {
// TODO(das): to be implemented
Ok(())
}

fn verify_slot_higher_than_parent<E: EthSpec>(
parent_block: &Block,
data_column_slot: Slot,
) -> Result<(), GossipDataColumnError<E>> {
if parent_block.slot >= data_column_slot {
return Err(GossipDataColumnError::IsNotLaterThanParent {
data_column_slot,
parent_slot: parent_block.slot,
});
}
Ok(())
}

fn verify_parent_block_and_finalized_descendant<T: BeaconChainTypes>(
data_column: Arc<DataColumnSidecar<T::EthSpec>>,
chain: &BeaconChain<T>,
) -> Result<ProtoBlock, GossipDataColumnError<T::EthSpec>> {
let fork_choice = chain.canonical_head.fork_choice_read_lock();

// We have already verified that the column is past finalization, so we can
// just check fork choice for the block's parent.
let block_parent_root = data_column.block_parent_root();
let Some(parent_block) = fork_choice.get_block(&block_parent_root) else {
return Err(GossipDataColumnError::ParentUnknown(data_column.clone()));
};

// Do not process a column that does not descend from the finalized root.
// We just loaded the parent_block, so we can be sure that it exists in fork choice.
if !fork_choice.is_finalized_checkpoint_or_descendant(block_parent_root) {
return Err(GossipDataColumnError::NotFinalizedDescendant { block_parent_root });
}

Ok(parent_block)
}

fn verify_proposer_and_signature<T: BeaconChainTypes>(
data_column: &DataColumnSidecar<T::EthSpec>,
parent_block: &ProtoBlock,
chain: &BeaconChain<T>,
) -> Result<(), GossipDataColumnError<T::EthSpec>> {
let column_slot = data_column.slot();
let column_epoch = column_slot.epoch(E::slots_per_epoch());
let column_index = data_column.index;
let block_root = data_column.block_root();
let block_parent_root = data_column.block_parent_root();

let proposer_shuffling_root =
if parent_block.slot.epoch(T::EthSpec::slots_per_epoch()) == column_epoch {
parent_block
.next_epoch_shuffling_id
.shuffling_decision_block
} else {
parent_block.root
};

let proposer_opt = chain
.beacon_proposer_cache
.lock()
.get_slot::<T::EthSpec>(proposer_shuffling_root, column_slot);

let (proposer_index, fork) = if let Some(proposer) = proposer_opt {
(proposer.index, proposer.fork)
} else {
debug!(
chain.log,
"Proposer shuffling cache miss for column verification";
"block_root" => %block_root,
"index" => %column_index,
);
let (parent_state_root, mut parent_state) = chain
.store
.get_advanced_hot_state(block_parent_root, column_slot, parent_block.state_root)
.map_err(|e| GossipDataColumnError::BeaconChainError(e.into()))?
.ok_or_else(|| {
BeaconChainError::DBInconsistent(format!(
"Missing state for parent block {block_parent_root:?}",
))
})?;

let state = cheap_state_advance_to_obtain_committees::<_, GossipDataColumnError<T::EthSpec>>(
&mut parent_state,
Some(parent_state_root),
column_slot,
&chain.spec,
)?;

let proposers = state.get_beacon_proposer_indices(&chain.spec)?;
let proposer_index = *proposers
.get(column_slot.as_usize() % T::EthSpec::slots_per_epoch() as usize)
.ok_or_else(|| BeaconChainError::NoProposerForSlot(column_slot))?;

// Prime the proposer shuffling cache with the newly-learned value.
chain.beacon_proposer_cache.lock().insert(
column_epoch,
proposer_shuffling_root,
proposers,
state.fork(),
)?;
(proposer_index, state.fork())
};

// Signature verify the signed block header.
let signature_is_valid = {
let pubkey_cache = get_validator_pubkey_cache(chain)
.map_err(|_| GossipDataColumnError::PubkeyCacheTimeout)?;

let pubkey = pubkey_cache
.get(proposer_index)
.ok_or_else(|| GossipDataColumnError::UnknownValidator(proposer_index as u64))?;
let signed_block_header = &data_column.signed_block_header;
signed_block_header.verify_signature::<T::EthSpec>(
pubkey,
&fork,
chain.genesis_validators_root,
&chain.spec,
)
};

if !signature_is_valid {
return Err(GossipDataColumnError::ProposalSignatureInvalid);
}

let column_proposer_index = data_column.block_proposer_index();
if proposer_index != column_proposer_index as usize {
return Err(GossipDataColumnError::ProposerIndexMismatch {
sidecar: column_proposer_index as usize,
local: proposer_index,
});
}

Ok(())
}

fn verify_index_matches_subnet<E: EthSpec>(
data_column: &DataColumnSidecar<E>,
subnet: u64,
spec: &ChainSpec,
) -> Result<(), GossipDataColumnError<E>> {
let expected_subnet: u64 =
DataColumnSubnetId::from_column_index::<E>(data_column.index as usize, spec).into();
if expected_subnet != subnet {
return Err(GossipDataColumnError::InvalidSubnetId {
received: subnet,
expected: expected_subnet,
});
}
Ok(())
}

fn verify_slot_greater_than_latest_finalized_slot<T: BeaconChainTypes>(
chain: &BeaconChain<T>,
column_slot: Slot,
) -> Result<(), GossipDataColumnError<T::EthSpec>> {
let latest_finalized_slot = chain
.head()
.finalized_checkpoint()
.epoch
.start_slot(T::EthSpec::slots_per_epoch());
if column_slot <= latest_finalized_slot {
return Err(GossipDataColumnError::PastFinalizedSlot {
column_slot,
finalized_slot: latest_finalized_slot,
});
}
Ok(())
}

fn verify_sidecar_not_from_future_slot<T: BeaconChainTypes>(
chain: &BeaconChain<T>,
column_slot: Slot,
) -> Result<(), GossipDataColumnError<T::EthSpec>> {
let latest_permissible_slot = chain
.slot_clock
.now_with_future_tolerance(chain.spec.maximum_gossip_clock_disparity())
.ok_or(BeaconChainError::UnableToReadSlot)?;
if column_slot > latest_permissible_slot {
return Err(GossipDataColumnError::FutureSlot {
message_slot: column_slot,
latest_permissible_slot,
});
}
Ok(())
}
2 changes: 1 addition & 1 deletion beacon_node/beacon_chain/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use crate::migrate::PruningError;
use crate::naive_aggregation_pool::Error as NaiveAggregationError;
use crate::observed_aggregates::Error as ObservedAttestationsError;
use crate::observed_attesters::Error as ObservedAttestersError;
use crate::observed_blob_sidecars::Error as ObservedBlobSidecarsError;
use crate::observed_block_producers::Error as ObservedBlockProducersError;
use crate::observed_data_sidecars::Error as ObservedBlobSidecarsError;
use execution_layer::PayloadStatus;
use fork_choice::ExecutionStatus;
use futures::channel::mpsc::TrySendError;
Expand Down
2 changes: 1 addition & 1 deletion beacon_node/beacon_chain/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ pub mod migrate;
mod naive_aggregation_pool;
pub mod observed_aggregates;
mod observed_attesters;
mod observed_blob_sidecars;
pub mod observed_block_producers;
mod observed_data_sidecars;
pub mod observed_operations;
mod observed_slashable;
pub mod otb_verification_service;
Expand Down
Loading

0 comments on commit 8e0fa1b

Please sign in to comment.