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

Sidecar inclusion proof #4900

Merged
merged 67 commits into from Dec 5, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
ec0dffb
Refactor BlobSidecar to new type
pawanjay176 Nov 2, 2023
aa1bd7b
Fix some compile errors
pawanjay176 Nov 2, 2023
53a877a
Gossip verification compiles
pawanjay176 Nov 2, 2023
dd7ccee
Fix http api types take 1
pawanjay176 Nov 3, 2023
7f67113
Fix another round of compile errors
pawanjay176 Nov 6, 2023
281f280
Beacon node crate compiles
pawanjay176 Nov 6, 2023
a24f508
EF tests compile
pawanjay176 Nov 6, 2023
fa4e868
Remove all blob signing from VC
pawanjay176 Nov 6, 2023
a0e4025
fmt
pawanjay176 Nov 6, 2023
c0b27ad
Tests compile
pawanjay176 Nov 7, 2023
ad7a6d8
Fix some tests
pawanjay176 Nov 7, 2023
60c1acb
Fix more http tests
pawanjay176 Nov 7, 2023
fb5facb
get compiling
realbigsean Nov 7, 2023
e647f21
Fix gossip conditions and tests
pawanjay176 Nov 8, 2023
c751fbd
Add basic proof generation and verification
pawanjay176 Nov 9, 2023
20c45f2
remove unnecessary ssz decode
realbigsean Nov 12, 2023
4782486
Merge branch 'sidecar-inclusion-proof' of https://github.com/sigp/lig…
realbigsean Nov 15, 2023
555dc30
add back build_sidecar
realbigsean Nov 15, 2023
825ae62
remove default at fork for blobs
realbigsean Nov 16, 2023
8ee1ff9
fix beacon chain tests
realbigsean Nov 16, 2023
9fe8b35
get relase tests compiling
realbigsean Nov 17, 2023
c12db38
fix lints
realbigsean Nov 17, 2023
d683ef0
fix existing spec tests
realbigsean Nov 18, 2023
76b56e2
add new ef tests
realbigsean Nov 19, 2023
14adec9
Merge pull request #4927 from realbigsean/sidecar-inclusion-api-updates
realbigsean Nov 19, 2023
357c42f
fix gossip duplicate rule
realbigsean Nov 21, 2023
338bdbb
lints
realbigsean Nov 21, 2023
2e31b11
add back sidecar signature check in gossip
realbigsean Nov 21, 2023
d9e650a
add finalized descendant check to blob sidecar gossip
realbigsean Nov 21, 2023
8697583
Merge pull request #4941 from realbigsean/sidecar-inclusion-cleanup
realbigsean Nov 21, 2023
3b4acfc
Merge branch 'unstable' of https://github.com/sigp/lighthouse into si…
realbigsean Nov 21, 2023
199cdf6
Merge branch 'sidecar-inclusion-proof' of https://github.com/sigp/lig…
realbigsean Nov 21, 2023
533ce06
fix error conversion
realbigsean Nov 21, 2023
4252fd1
Merge pull request #4942 from realbigsean/sidecar-inclusion-proof
realbigsean Nov 21, 2023
a72c880
Merge branch 'unstable' of https://github.com/sigp/lighthouse into si…
realbigsean Nov 21, 2023
8b7478c
fix release tests
realbigsean Nov 21, 2023
ba41d63
Merge pull request #4944 from realbigsean/sidecar-inclusion-proof
realbigsean Nov 21, 2023
8792c96
sidecar inclusion self review cleanup
realbigsean Nov 24, 2023
c6be31c
Merge pull request #4949 from realbigsean/sidecar-inclusion-selfreview
realbigsean Nov 24, 2023
9901e00
Merge branch 'unstable' into sidecar-inclusion-proof
pawanjay176 Nov 27, 2023
0d9cb7c
Add proof verification and computation metrics
pawanjay176 Nov 27, 2023
f6f0900
Remove accidentally committed file
pawanjay176 Nov 27, 2023
3ea42d9
Unify some block and blob errors; add slashing conditions for sidecars
pawanjay176 Nov 28, 2023
03063be
Merge branch 'unstable' into sidecar-inclusion-proof
pawanjay176 Nov 29, 2023
74a0fc8
Address review comment
pawanjay176 Nov 29, 2023
a130a5c
Clean up re-org tests (#4957)
michaelsproul Nov 29, 2023
e5a0e2c
Address more review comments
pawanjay176 Nov 30, 2023
10fe2ec
Add Comments & Eliminate Unnecessary Clones
ethDreamer Nov 30, 2023
1996005
Merge pull request #4964 from ethDreamer/sidecar-inclusion-proof
realbigsean Nov 30, 2023
9d7ac74
update names
realbigsean Nov 30, 2023
5c6d5b3
Update beacon_node/beacon_chain/src/metrics.rs
realbigsean Nov 30, 2023
808b6dd
Update beacon_node/network/src/network_beacon_processor/tests.rs
realbigsean Nov 30, 2023
1da8b69
pr feedback
realbigsean Nov 30, 2023
c8065a1
Merge branch 'sidecar-inclusion-proof' of https://github.com/sigp/lig…
realbigsean Nov 30, 2023
6f02de3
fix test compile
realbigsean Nov 30, 2023
620b974
Sidecar Inclusion proof small refactor and updates (#4967)
jimmygchen Dec 1, 2023
812af38
Update testing/ef_tests/src/cases/merkle_proof_validity.rs
realbigsean Dec 1, 2023
7836bd6
Merge pull request #4965 from realbigsean/sidecar-inclusion-review-up…
realbigsean Dec 1, 2023
5359698
Rename the block and blob wrapper types used in the beacon API interf…
jimmygchen Dec 4, 2023
ee3767c
make sure gossip invalid blobs are passed to the slasher (#4970)
realbigsean Dec 4, 2023
a870e07
Add blob headers to slasher before adding to DA checker
pawanjay176 Dec 4, 2023
3d44827
Replace Vec with HashSet in BlockQueue
pawanjay176 Dec 4, 2023
b226d29
fmt
pawanjay176 Dec 4, 2023
5d43472
Rename gindex -> index
pawanjay176 Dec 4, 2023
1fa71ec
Merge pull request #4976 from pawanjay176/fix-slasher-conditions
realbigsean Dec 4, 2023
3536fa3
Merge pull request #4974 from jimmygchen/deneb-types-rename
realbigsean Dec 4, 2023
6065c66
Simplify gossip condition
pawanjay176 Dec 5, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

149 changes: 93 additions & 56 deletions beacon_node/beacon_chain/src/beacon_chain.rs
Expand Up @@ -7,7 +7,7 @@ use crate::attester_cache::{AttesterCache, AttesterCacheKey};
use crate::beacon_block_streamer::{BeaconBlockStreamer, CheckEarlyAttesterCache};
use crate::beacon_proposer_cache::compute_proposer_duties_from_head;
use crate::beacon_proposer_cache::BeaconProposerCache;
use crate::blob_verification::{self, GossipBlobError, GossipVerifiedBlob};
use crate::blob_verification::{GossipBlobError, GossipVerifiedBlob};
use crate::block_times_cache::BlockTimesCache;
use crate::block_verification::POS_PANDA_BANNER;
use crate::block_verification::{
Expand Down Expand Up @@ -121,7 +121,6 @@ use tree_hash::TreeHash;
use types::beacon_state::CloneConfig;
use types::blob_sidecar::{BlobSidecarList, FixedBlobSidecarList};
use types::payload::BlockProductionVersion;
use types::sidecar::BlobItems;
use types::*;

pub type ForkChoiceError = fork_choice::Error<crate::ForkChoiceStoreError>;
Expand Down Expand Up @@ -484,16 +483,49 @@ pub struct BeaconChain<T: BeaconChainTypes> {
pub kzg: Option<Arc<Kzg>>,
}

pub enum BeaconBlockResponseType<T: EthSpec> {
pub enum BeaconBlockResponseWrapper<T: EthSpec> {
Full(BeaconBlockResponse<T, FullPayload<T>>),
Blinded(BeaconBlockResponse<T, BlindedPayload<T>>),
}

impl<E: EthSpec> BeaconBlockResponseWrapper<E> {
pub fn fork_name(&self, spec: &ChainSpec) -> Result<ForkName, InconsistentFork> {
Ok(match self {
BeaconBlockResponseWrapper::Full(resp) => resp.block.to_ref().fork_name(spec)?,
BeaconBlockResponseWrapper::Blinded(resp) => resp.block.to_ref().fork_name(spec)?,
})
}

pub fn execution_payload_value(&self) -> Option<Uint256> {
match self {
BeaconBlockResponseWrapper::Full(resp) => resp.execution_payload_value,
BeaconBlockResponseWrapper::Blinded(resp) => resp.execution_payload_value,
}
}

pub fn consensus_block_value(&self) -> Option<u64> {
match self {
BeaconBlockResponseWrapper::Full(resp) => resp.consensus_block_value,
BeaconBlockResponseWrapper::Blinded(resp) => resp.consensus_block_value,
}
}

pub fn is_blinded(&self) -> bool {
matches!(self, BeaconBlockResponseWrapper::Blinded(_))
}
}

/// The components produced when the local beacon node creates a new block to extend the chain
pub struct BeaconBlockResponse<T: EthSpec, Payload: AbstractExecPayload<T>> {
/// The newly produced beacon block
pub block: BeaconBlock<T, Payload>,
/// The post-state after applying the new block
pub state: BeaconState<T>,
pub maybe_side_car: Option<SidecarList<T, <Payload as AbstractExecPayload<T>>::Sidecar>>,
/// The Blobs / Proofs associated with the new block
pub blob_items: Option<(KzgProofs<T>, BlobsList<T>)>,
/// The execution layer reward for the block
pub execution_payload_value: Option<Uint256>,
/// The consensus layer reward to the proposer
pub consensus_block_value: Option<u64>,
}

Expand Down Expand Up @@ -2017,17 +2049,15 @@ impl<T: BeaconChainTypes> BeaconChain<T> {

pub fn verify_blob_sidecar_for_gossip(
self: &Arc<Self>,
blob_sidecar: SignedBlobSidecar<T::EthSpec>,
blob_sidecar: Arc<BlobSidecar<T::EthSpec>>,
subnet_id: u64,
) -> Result<GossipVerifiedBlob<T>, GossipBlobError<T::EthSpec>> {
metrics::inc_counter(&metrics::BLOBS_SIDECAR_PROCESSING_REQUESTS);
let _timer = metrics::start_timer(&metrics::BLOBS_SIDECAR_GOSSIP_VERIFICATION_TIMES);
blob_verification::validate_blob_sidecar_for_gossip(blob_sidecar, subnet_id, self).map(
|v| {
metrics::inc_counter(&metrics::BLOBS_SIDECAR_PROCESSING_SUCCESSES);
v
},
)
GossipVerifiedBlob::new(blob_sidecar, subnet_id, self).map(|v| {
metrics::inc_counter(&metrics::BLOBS_SIDECAR_PROCESSING_SUCCESSES);
v
})
}

/// Accepts some 'LightClientOptimisticUpdate' from the network and attempts to verify it
Expand Down Expand Up @@ -2827,7 +2857,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
}

self.data_availability_checker
.notify_gossip_blob(blob.as_blob().slot, block_root, &blob);
.notify_gossip_blob(blob.slot(), block_root, &blob);
let r = self.check_gossip_blob_availability_and_import(blob).await;
self.remove_notified(&block_root, r)
}
Expand Down Expand Up @@ -2937,6 +2967,20 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
// Increment the Prometheus counter for block processing requests.
metrics::inc_counter(&metrics::BLOCK_PROCESSING_REQUESTS);

// Set observed time if not already set. Usually this should be set by gossip or RPC,
// but just in case we set it again here (useful for tests).
if let (Some(seen_timestamp), Some(current_slot)) =
(self.slot_clock.now_duration(), self.slot_clock.now())
{
self.block_times_cache.write().set_time_observed(
block_root,
current_slot,
seen_timestamp,
None,
None,
);
}

let block_slot = unverified_block.block().slot();

// A small closure to group the verification and import errors.
Expand Down Expand Up @@ -3092,6 +3136,9 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
blob: GossipVerifiedBlob<T>,
) -> Result<AvailabilityProcessingStatus, BlockError<T::EthSpec>> {
let slot = blob.slot();
if let Some(slasher) = self.slasher.as_ref() {
slasher.accept_block_header(blob.signed_block_header());
}
let availability = self.data_availability_checker.put_gossip_blob(blob)?;

self.process_availability(slot, availability).await
Expand All @@ -3105,6 +3152,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
block_root: Hash256,
blobs: FixedBlobSidecarList<T::EthSpec>,
) -> Result<AvailabilityProcessingStatus, BlockError<T::EthSpec>> {
if let Some(slasher) = self.slasher.as_ref() {
for blob_sidecar in blobs.iter().filter_map(|blob| blob.clone()) {
slasher.accept_block_header(blob_sidecar.signed_block_header.clone());
}
}
let availability = self
.data_availability_checker
.put_rpc_blobs(block_root, blobs)?;
Expand Down Expand Up @@ -3963,7 +4015,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
validator_graffiti: Option<Graffiti>,
verification: ProduceBlockVerification,
block_production_version: BlockProductionVersion,
) -> Result<BeaconBlockResponseType<T::EthSpec>, BlockProductionError> {
) -> Result<BeaconBlockResponseWrapper<T::EthSpec>, BlockProductionError> {
metrics::inc_counter(&metrics::BLOCK_PRODUCTION_REQUESTS);
let _complete_timer = metrics::start_timer(&metrics::BLOCK_PRODUCTION_TIMES);
// Part 1/2 (blocking)
Expand Down Expand Up @@ -4379,7 +4431,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
/// This function uses heuristics that align quite closely but not exactly with the re-org
/// conditions set out in `get_state_for_re_org` and `get_proposer_head`. The differences are
/// documented below.
fn overridden_forkchoice_update_params(
pub fn overridden_forkchoice_update_params(
&self,
canonical_forkchoice_params: ForkchoiceUpdateParameters,
) -> Result<ForkchoiceUpdateParameters, Error> {
Expand All @@ -4397,7 +4449,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
})
}

fn overridden_forkchoice_update_params_or_failure_reason(
pub fn overridden_forkchoice_update_params_or_failure_reason(
&self,
canonical_forkchoice_params: &ForkchoiceUpdateParameters,
) -> Result<ForkchoiceUpdateParameters, ProposerHeadError<Error>> {
Expand Down Expand Up @@ -4538,7 +4590,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.unwrap_or_else(|| Duration::from_secs(0)),
);
block_delays.observed.map_or(false, |delay| {
delay > self.slot_clock.unagg_attestation_production_delay()
delay >= self.slot_clock.unagg_attestation_production_delay()
})
}

Expand All @@ -4564,7 +4616,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
validator_graffiti: Option<Graffiti>,
verification: ProduceBlockVerification,
block_production_version: BlockProductionVersion,
) -> Result<BeaconBlockResponseType<T::EthSpec>, BlockProductionError> {
) -> Result<BeaconBlockResponseWrapper<T::EthSpec>, BlockProductionError> {
// Part 1/3 (blocking)
//
// Perform the state advance and block-packing functions.
Expand Down Expand Up @@ -4623,7 +4675,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.await
.map_err(BlockProductionError::TokioJoin)??;

Ok(BeaconBlockResponseType::Full(beacon_block_response))
Ok(BeaconBlockResponseWrapper::Full(beacon_block_response))
}
BlockProposalContentsType::Blinded(block_contents) => {
let chain = self.clone();
Expand All @@ -4643,7 +4695,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.await
.map_err(BlockProductionError::TokioJoin)??;

Ok(BeaconBlockResponseType::Blinded(beacon_block_response))
Ok(BeaconBlockResponseWrapper::Blinded(beacon_block_response))
}
}
} else {
Expand All @@ -4664,7 +4716,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.await
.map_err(BlockProductionError::TokioJoin)??;

Ok(BeaconBlockResponseType::Full(beacon_block_response))
Ok(BeaconBlockResponseWrapper::Full(beacon_block_response))
}
}

Expand Down Expand Up @@ -4942,7 +4994,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
bls_to_execution_changes,
} = partial_beacon_block;

let (inner_block, blobs_opt, proofs_opt, execution_payload_value) = match &state {
let (inner_block, maybe_blobs_and_proofs, execution_payload_value) = match &state {
BeaconState::Base(_) => (
BeaconBlock::Base(BeaconBlockBase {
slot,
Expand All @@ -4962,7 +5014,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
},
}),
None,
None,
Uint256::zero(),
),
BeaconState::Altair(_) => (
Expand All @@ -4986,7 +5037,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
},
}),
None,
None,
Uint256::zero(),
),
BeaconState::Merge(_) => {
Expand Down Expand Up @@ -5017,7 +5067,6 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
},
}),
None,
None,
execution_payload_value,
)
}
Expand Down Expand Up @@ -5051,12 +5100,11 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
},
}),
None,
None,
execution_payload_value,
)
}
BeaconState::Deneb(_) => {
let (payload, kzg_commitments, blobs, proofs, execution_payload_value) =
let (payload, kzg_commitments, maybe_blobs_and_proofs, execution_payload_value) =
block_contents
.ok_or(BlockProductionError::MissingExecutionPayload)?
.deconstruct();
Expand Down Expand Up @@ -5086,8 +5134,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
.ok_or(BlockProductionError::InvalidPayloadFork)?,
},
}),
blobs,
proofs,
maybe_blobs_and_proofs,
execution_payload_value,
)
}
Expand Down Expand Up @@ -5146,51 +5193,41 @@ impl<T: BeaconChainTypes> BeaconChain<T> {

let blobs_verification_timer =
metrics::start_timer(&metrics::BLOCK_PRODUCTION_BLOBS_VERIFICATION_TIMES);
let maybe_sidecar_list = match (blobs_opt, proofs_opt) {
(Some(blobs_or_blobs_roots), Some(proofs)) => {
let blob_items = match maybe_blobs_and_proofs {
Some((blobs, proofs)) => {
let expected_kzg_commitments =
block.body().blob_kzg_commitments().map_err(|_| {
BlockProductionError::InvalidBlockVariant(
"deneb block does not contain kzg commitments".to_string(),
)
})?;

if expected_kzg_commitments.len() != blobs_or_blobs_roots.len() {
if expected_kzg_commitments.len() != blobs.len() {
return Err(BlockProductionError::MissingKzgCommitment(format!(
"Missing KZG commitment for slot {}. Expected {}, got: {}",
block.slot(),
blobs_or_blobs_roots.len(),
blobs.len(),
expected_kzg_commitments.len()
)));
}

let kzg_proofs = Vec::from(proofs);

if let Some(blobs) = blobs_or_blobs_roots.blobs() {
let kzg = self
.kzg
.as_ref()
.ok_or(BlockProductionError::TrustedSetupNotInitialized)?;
kzg_utils::validate_blobs::<T::EthSpec>(
kzg,
expected_kzg_commitments,
blobs.iter().collect(),
&kzg_proofs,
)
.map_err(BlockProductionError::KzgError)?;
}

Some(
Sidecar::build_sidecar(
blobs_or_blobs_roots,
&block,
expected_kzg_commitments,
kzg_proofs,
)
.map_err(BlockProductionError::FailedToBuildBlobSidecars)?,
let kzg = self
.kzg
.as_ref()
.ok_or(BlockProductionError::TrustedSetupNotInitialized)?;
kzg_utils::validate_blobs::<T::EthSpec>(
kzg,
expected_kzg_commitments,
blobs.iter().collect(),
&kzg_proofs,
)
.map_err(BlockProductionError::KzgError)?;

Some((kzg_proofs.into(), blobs))
}
_ => None,
None => None,
};

drop(blobs_verification_timer);
Expand All @@ -5208,7 +5245,7 @@ impl<T: BeaconChainTypes> BeaconChain<T> {
Ok(BeaconBlockResponse {
block,
state,
maybe_side_car: maybe_sidecar_list,
blob_items,
execution_payload_value: Some(execution_payload_value),
consensus_block_value: Some(consensus_block_value),
})
Expand Down