Skip to content

Commit

Permalink
Merge branch 'unstable' into jimmy/lh-2271-activate-peerdas-at-fulu-f…
Browse files Browse the repository at this point in the history
…ork-and-remove-eip7594_fork_epoch
  • Loading branch information
jimmygchen authored Jan 30, 2025
2 parents 38c7f05 + 66c6552 commit 8cb49c7
Show file tree
Hide file tree
Showing 30 changed files with 591 additions and 256 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ lint-fix:

# Also run the lints on the optimized-only tests
lint-full:
RUSTFLAGS="-C debug-assertions=no $(RUSTFLAGS)" $(MAKE) lint
TEST_FEATURES="beacon-node-leveldb,beacon-node-redb,${TEST_FEATURES}" RUSTFLAGS="-C debug-assertions=no $(RUSTFLAGS)" $(MAKE) lint

# Runs the makefile in the `ef_tests` repo.
#
Expand Down
58 changes: 44 additions & 14 deletions beacon_node/beacon_chain/src/block_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -208,24 +208,18 @@ pub enum BlockError {
///
/// The block is invalid and the peer is faulty.
IncorrectBlockProposer { block: u64, local_shuffling: u64 },
/// The proposal signature in invalid.
///
/// ## Peer scoring
///
/// The block is invalid and the peer is faulty.
ProposalSignatureInvalid,
/// The `block.proposal_index` is not known.
///
/// ## Peer scoring
///
/// The block is invalid and the peer is faulty.
UnknownValidator(u64),
/// A signature in the block is invalid (exactly which is unknown).
/// A signature in the block is invalid
///
/// ## Peer scoring
///
/// The block is invalid and the peer is faulty.
InvalidSignature,
InvalidSignature(InvalidSignature),
/// The provided block is not from a later slot than its parent.
///
/// ## Peer scoring
Expand Down Expand Up @@ -329,6 +323,17 @@ pub enum BlockError {
InternalError(String),
}

/// Which specific signature(s) are invalid in a SignedBeaconBlock
#[derive(Debug)]
pub enum InvalidSignature {
// The outer signature in a SignedBeaconBlock
ProposerSignature,
// One or more signatures in BeaconBlockBody
BlockBodySignatures,
// One or more signatures in SignedBeaconBlock
Unknown,
}

impl From<AvailabilityCheckError> for BlockError {
fn from(e: AvailabilityCheckError) -> Self {
Self::AvailabilityCheck(e)
Expand Down Expand Up @@ -523,7 +528,9 @@ pub enum BlockSlashInfo<TErr> {
impl BlockSlashInfo<BlockError> {
pub fn from_early_error_block(header: SignedBeaconBlockHeader, e: BlockError) -> Self {
match e {
BlockError::ProposalSignatureInvalid => BlockSlashInfo::SignatureInvalid(e),
BlockError::InvalidSignature(InvalidSignature::ProposerSignature) => {
BlockSlashInfo::SignatureInvalid(e)
}
// `InvalidSignature` could indicate any signature in the block, so we want
// to recheck the proposer signature alone.
_ => BlockSlashInfo::SignatureNotChecked(header, e),
Expand Down Expand Up @@ -652,7 +659,7 @@ pub fn signature_verify_chain_segment<T: BeaconChainTypes>(
}

if signature_verifier.verify().is_err() {
return Err(BlockError::InvalidSignature);
return Err(BlockError::InvalidSignature(InvalidSignature::Unknown));
}

drop(pubkey_cache);
Expand Down Expand Up @@ -964,7 +971,9 @@ impl<T: BeaconChainTypes> GossipVerifiedBlock<T> {
};

if !signature_is_valid {
return Err(BlockError::ProposalSignatureInvalid);
return Err(BlockError::InvalidSignature(
InvalidSignature::ProposerSignature,
));
}

chain
Expand Down Expand Up @@ -1098,7 +1107,26 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
parent: Some(parent),
})
} else {
Err(BlockError::InvalidSignature)
// Re-verify the proposer signature in isolation to attribute fault
let pubkey = pubkey_cache
.get(block.message().proposer_index() as usize)
.ok_or_else(|| BlockError::UnknownValidator(block.message().proposer_index()))?;
if block.as_block().verify_signature(
Some(block_root),
pubkey,
&state.fork(),
chain.genesis_validators_root,
&chain.spec,
) {
// Proposer signature is valid, the invalid signature must be in the body
Err(BlockError::InvalidSignature(
InvalidSignature::BlockBodySignatures,
))
} else {
Err(BlockError::InvalidSignature(
InvalidSignature::ProposerSignature,
))
}
}
}

Expand Down Expand Up @@ -1153,7 +1181,9 @@ impl<T: BeaconChainTypes> SignatureVerifiedBlock<T> {
consensus_context,
})
} else {
Err(BlockError::InvalidSignature)
Err(BlockError::InvalidSignature(
InvalidSignature::BlockBodySignatures,
))
}
}

Expand Down Expand Up @@ -1981,7 +2011,7 @@ impl BlockBlobError for BlockError {
}

fn proposer_signature_invalid() -> Self {
BlockError::ProposalSignatureInvalid
BlockError::InvalidSignature(InvalidSignature::ProposerSignature)
}
}

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 @@ -78,7 +78,7 @@ pub use beacon_fork_choice_store::{BeaconForkChoiceStore, Error as ForkChoiceSto
pub use block_verification::{
build_blob_data_column_sidecars, get_block_root, BlockError, ExecutionPayloadError,
ExecutionPendingBlock, GossipVerifiedBlock, IntoExecutionPendingBlock, IntoGossipVerifiedBlock,
PayloadVerificationOutcome, PayloadVerificationStatus,
InvalidSignature, PayloadVerificationOutcome, PayloadVerificationStatus,
};
pub use block_verification_types::AvailabilityPendingExecutedBlock;
pub use block_verification_types::ExecutedBlock;
Expand Down
59 changes: 35 additions & 24 deletions beacon_node/beacon_chain/tests/block_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use beacon_chain::{
};
use beacon_chain::{
BeaconSnapshot, BlockError, ChainConfig, ChainSegmentResult, IntoExecutionPendingBlock,
NotifyExecutionLayer,
InvalidSignature, NotifyExecutionLayer,
};
use logging::test_logger;
use slasher::{Config as SlasherConfig, Slasher};
Expand Down Expand Up @@ -470,7 +470,7 @@ async fn assert_invalid_signature(
.process_chain_segment(blocks, NotifyExecutionLayer::Yes)
.await
.into_block_error(),
Err(BlockError::InvalidSignature)
Err(BlockError::InvalidSignature(InvalidSignature::Unknown))
),
"should not import chain segment with an invalid {} signature",
item
Expand Down Expand Up @@ -511,7 +511,12 @@ async fn assert_invalid_signature(
)
.await;
assert!(
matches!(process_res, Err(BlockError::InvalidSignature)),
matches!(
process_res,
Err(BlockError::InvalidSignature(
InvalidSignature::BlockBodySignatures
))
),
"should not import individual block with an invalid {} signature, got: {:?}",
item,
process_res
Expand Down Expand Up @@ -567,21 +572,25 @@ async fn invalid_signature_gossip_block() {
.into_block_error()
.expect("should import all blocks prior to the one being tested");
let signed_block = SignedBeaconBlock::from_block(block, junk_signature());
let process_res = harness
.chain
.process_block(
signed_block.canonical_root(),
Arc::new(signed_block),
NotifyExecutionLayer::Yes,
BlockImportSource::Lookup,
|| Ok(()),
)
.await;
assert!(
matches!(
harness
.chain
.process_block(
signed_block.canonical_root(),
Arc::new(signed_block),
NotifyExecutionLayer::Yes,
BlockImportSource::Lookup,
|| Ok(()),
)
.await,
Err(BlockError::InvalidSignature)
process_res,
Err(BlockError::InvalidSignature(
InvalidSignature::ProposerSignature
))
),
"should not import individual block with an invalid gossip signature",
"should not import individual block with an invalid gossip signature, got: {:?}",
process_res
);
}
}
Expand Down Expand Up @@ -609,16 +618,18 @@ async fn invalid_signature_block_proposal() {
})
.collect::<Vec<_>>();
// Ensure the block will be rejected if imported in a chain segment.
let process_res = harness
.chain
.process_chain_segment(blocks, NotifyExecutionLayer::Yes)
.await
.into_block_error();
assert!(
matches!(
harness
.chain
.process_chain_segment(blocks, NotifyExecutionLayer::Yes)
.await
.into_block_error(),
Err(BlockError::InvalidSignature)
process_res,
Err(BlockError::InvalidSignature(InvalidSignature::Unknown))
),
"should not import chain segment with an invalid block signature",
"should not import chain segment with an invalid block signature, got: {:?}",
process_res
);
}
}
Expand Down Expand Up @@ -921,7 +932,7 @@ async fn invalid_signature_deposit() {
.process_chain_segment(blocks, NotifyExecutionLayer::Yes)
.await
.into_block_error(),
Err(BlockError::InvalidSignature)
Err(BlockError::InvalidSignature(InvalidSignature::Unknown))
),
"should not throw an invalid signature error for a bad deposit signature"
);
Expand Down Expand Up @@ -1105,7 +1116,7 @@ async fn block_gossip_verification() {
)))
.await
),
BlockError::ProposalSignatureInvalid
BlockError::InvalidSignature(InvalidSignature::ProposerSignature)
),
"should not import a block with an invalid proposal signature"
);
Expand Down
Loading

0 comments on commit 8cb49c7

Please sign in to comment.