Skip to content
Closed
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
85 changes: 51 additions & 34 deletions beacon_node/beacon_chain/tests/block_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,20 +35,30 @@ type E = MainnetEthSpec;

// Gloas requires >= 1 validator per slot for PTC committee computation, so >= 32 for MainnetEthSpec.
const VALIDATOR_COUNT: usize = 32;
const CHAIN_SEGMENT_LENGTH: usize = 64 * 5;
const BLOCK_INDICES: &[usize] = &[0, 1, 32, 64, 68 + 1, 129, CHAIN_SEGMENT_LENGTH - 1];
const CHAIN_SEGMENT_LENGTH: usize = 32 * 6;
const BLOCK_INDICES: &[usize] = &[1, 32, 64];

/// A cached set of keys.
static KEYPAIRS: LazyLock<Vec<Keypair>> =
LazyLock::new(|| types::test_utils::generate_deterministic_keypairs(VALIDATOR_COUNT));

// TODO(#8633): Delete this unnecessary enum and refactor this file to use `AvailableBlockData` instead.
#[derive(Clone)]
enum DataSidecars<E: EthSpec> {
Blobs(BlobSidecarList<E>),
DataColumns(Vec<CustodyDataColumn<E>>),
}

async fn get_chain_segment() -> (Vec<BeaconSnapshot<E>>, Vec<Option<DataSidecars<E>>>) {
type ChainSegmentData = (Vec<BeaconSnapshot<E>>, Vec<Option<DataSidecars<E>>>);

static CHAIN_SEGMENT: LazyLock<tokio::sync::OnceCell<ChainSegmentData>> =
LazyLock::new(tokio::sync::OnceCell::new);

async fn get_chain_segment() -> &'static ChainSegmentData {
CHAIN_SEGMENT.get_or_init(build_chain_segment).await
}

async fn build_chain_segment() -> ChainSegmentData {
// The assumption that you can re-import a block based on what you have in your DB
// is no longer true, as fullnodes stores less than what they sample.
// We use a supernode here to build a chain segment.
Expand Down Expand Up @@ -365,9 +375,9 @@ async fn chain_segment_full_segment() {
}
let harness = get_harness(VALIDATOR_COUNT, NodeCustodyType::Fullnode);
let (chain_segment, chain_segment_blobs) = get_chain_segment().await;
store_envelopes_for_chain_segment(&chain_segment, &harness);
store_envelopes_for_chain_segment(chain_segment, &harness);
let blocks: Vec<RangeSyncBlock<E>> =
chain_segment_blocks(&chain_segment, &chain_segment_blobs, harness.chain.clone())
chain_segment_blocks(chain_segment, chain_segment_blobs, harness.chain.clone())
.into_iter()
.collect();

Expand All @@ -391,7 +401,7 @@ async fn chain_segment_full_segment() {
.into_block_error()
.expect("should import chain segment");

update_fork_choice_with_envelopes(&chain_segment, &harness);
update_fork_choice_with_envelopes(chain_segment, &harness);
harness.chain.recompute_head_at_current_slot().await;

assert_eq!(
Expand All @@ -410,13 +420,13 @@ async fn chain_segment_varying_chunk_size() {
let (chain_segment, chain_segment_blobs) = get_chain_segment().await;
let harness = get_harness(VALIDATOR_COUNT, NodeCustodyType::Fullnode);
let blocks: Vec<RangeSyncBlock<E>> =
chain_segment_blocks(&chain_segment, &chain_segment_blobs, harness.chain.clone())
chain_segment_blocks(chain_segment, chain_segment_blobs, harness.chain.clone())
.into_iter()
.collect();

for chunk_size in &[1, 2, 31, 32, 33] {
for chunk_size in &[1, 32, 33] {
let harness = get_harness(VALIDATOR_COUNT, NodeCustodyType::Fullnode);
store_envelopes_for_chain_segment(&chain_segment, &harness);
store_envelopes_for_chain_segment(chain_segment, &harness);

harness
.chain
Expand All @@ -432,7 +442,7 @@ async fn chain_segment_varying_chunk_size() {
.unwrap_or_else(|_| panic!("should import chain segment of len {}", chunk_size));
}

update_fork_choice_with_envelopes(&chain_segment, &harness);
update_fork_choice_with_envelopes(chain_segment, &harness);
harness.chain.recompute_head_at_current_slot().await;

assert_eq!(
Expand All @@ -457,7 +467,7 @@ async fn chain_segment_non_linear_parent_roots() {
* Test with a block removed.
*/
let mut blocks: Vec<RangeSyncBlock<E>> =
chain_segment_blocks(&chain_segment, &chain_segment_blobs, harness.chain.clone())
chain_segment_blocks(chain_segment, chain_segment_blobs, harness.chain.clone())
.into_iter()
.collect();
blocks.remove(2);
Expand All @@ -478,7 +488,7 @@ async fn chain_segment_non_linear_parent_roots() {
* Test with a modified parent root.
*/
let mut blocks: Vec<RangeSyncBlock<E>> =
chain_segment_blocks(&chain_segment, &chain_segment_blobs, harness.chain.clone())
chain_segment_blocks(chain_segment, chain_segment_blobs, harness.chain.clone())
.into_iter()
.collect();

Expand Down Expand Up @@ -520,7 +530,7 @@ async fn chain_segment_non_linear_slots() {
*/

let mut blocks: Vec<RangeSyncBlock<E>> =
chain_segment_blocks(&chain_segment, &chain_segment_blobs, harness.chain.clone())
chain_segment_blocks(chain_segment, chain_segment_blobs, harness.chain.clone())
.into_iter()
.collect();
let (mut block, signature) = blocks[3].as_block().clone().deconstruct();
Expand Down Expand Up @@ -550,7 +560,7 @@ async fn chain_segment_non_linear_slots() {
*/

let mut blocks: Vec<RangeSyncBlock<E>> =
chain_segment_blocks(&chain_segment, &chain_segment_blobs, harness.chain.clone())
chain_segment_blocks(chain_segment, chain_segment_blobs, harness.chain.clone())
.into_iter()
.collect();
let (mut block, signature) = blocks[3].as_block().clone().deconstruct();
Expand Down Expand Up @@ -694,7 +704,7 @@ async fn invalid_signature_gossip_block() {
let (chain_segment, chain_segment_blobs) = get_chain_segment().await;
for &block_index in BLOCK_INDICES {
// Ensure the block will be rejected if imported on its own (without gossip checking).
let harness = get_invalid_sigs_harness(&chain_segment).await;
let harness = get_invalid_sigs_harness(chain_segment).await;
let mut snapshots = chain_segment.clone();
let (block, _) = snapshots[block_index]
.beacon_block
Expand Down Expand Up @@ -753,7 +763,7 @@ async fn invalid_signature_block_proposal() {
}
let (chain_segment, chain_segment_blobs) = get_chain_segment().await;
for &block_index in BLOCK_INDICES {
let harness = get_invalid_sigs_harness(&chain_segment).await;
let harness = get_invalid_sigs_harness(chain_segment).await;
let mut snapshots = chain_segment.clone();
let (block, _) = snapshots[block_index]
.beacon_block
Expand Down Expand Up @@ -794,9 +804,10 @@ async fn invalid_signature_randao_reveal() {
if fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
return;
}
let (chain_segment, mut chain_segment_blobs) = get_chain_segment().await;
let (chain_segment, ref_blobs) = get_chain_segment().await;
let mut chain_segment_blobs = ref_blobs.clone();
for &block_index in BLOCK_INDICES {
let harness = get_invalid_sigs_harness(&chain_segment).await;
let harness = get_invalid_sigs_harness(chain_segment).await;
let mut snapshots = chain_segment.clone();
let (mut block, signature) = snapshots[block_index]
.beacon_block
Expand All @@ -809,7 +820,7 @@ async fn invalid_signature_randao_reveal() {
update_parent_roots(&mut snapshots, &mut chain_segment_blobs);
update_proposal_signatures(&mut snapshots, &harness);
assert_invalid_signature(
&chain_segment,
chain_segment,
&chain_segment_blobs,
&harness,
block_index,
Expand All @@ -826,9 +837,10 @@ async fn invalid_signature_proposer_slashing() {
if fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
return;
}
let (chain_segment, mut chain_segment_blobs) = get_chain_segment().await;
let (chain_segment, ref_blobs) = get_chain_segment().await;
let mut chain_segment_blobs = ref_blobs.clone();
for &block_index in BLOCK_INDICES {
let harness = get_invalid_sigs_harness(&chain_segment).await;
let harness = get_invalid_sigs_harness(chain_segment).await;
let mut snapshots = chain_segment.clone();
let (mut block, signature) = snapshots[block_index]
.beacon_block
Expand All @@ -855,7 +867,7 @@ async fn invalid_signature_proposer_slashing() {
update_parent_roots(&mut snapshots, &mut chain_segment_blobs);
update_proposal_signatures(&mut snapshots, &harness);
assert_invalid_signature(
&chain_segment,
chain_segment,
&chain_segment_blobs,
&harness,
block_index,
Expand All @@ -872,9 +884,10 @@ async fn invalid_signature_attester_slashing() {
if fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
return;
}
let (chain_segment, mut chain_segment_blobs) = get_chain_segment().await;
let (chain_segment, ref_blobs) = get_chain_segment().await;
let mut chain_segment_blobs = ref_blobs.clone();
for &block_index in BLOCK_INDICES {
let harness = get_invalid_sigs_harness(&chain_segment).await;
let harness = get_invalid_sigs_harness(chain_segment).await;
let mut snapshots = chain_segment.clone();
let fork_name = harness.chain.spec.fork_name_at_slot::<E>(Slot::new(0));

Expand Down Expand Up @@ -980,7 +993,7 @@ async fn invalid_signature_attester_slashing() {
update_parent_roots(&mut snapshots, &mut chain_segment_blobs);
update_proposal_signatures(&mut snapshots, &harness);
assert_invalid_signature(
&chain_segment,
chain_segment,
&chain_segment_blobs,
&harness,
block_index,
Expand All @@ -997,11 +1010,12 @@ async fn invalid_signature_attestation() {
if fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
return;
}
let (chain_segment, mut chain_segment_blobs) = get_chain_segment().await;
let (chain_segment, ref_blobs) = get_chain_segment().await;
let mut chain_segment_blobs = ref_blobs.clone();
let mut checked_attestation = false;

for &block_index in BLOCK_INDICES {
let harness = get_invalid_sigs_harness(&chain_segment).await;
let harness = get_invalid_sigs_harness(chain_segment).await;
let mut snapshots = chain_segment.clone();
let (mut block, signature) = snapshots[block_index]
.beacon_block
Expand Down Expand Up @@ -1049,7 +1063,7 @@ async fn invalid_signature_attestation() {
update_parent_roots(&mut snapshots, &mut chain_segment_blobs);
update_proposal_signatures(&mut snapshots, &harness);
assert_invalid_signature(
&chain_segment,
chain_segment,
&chain_segment_blobs,
&harness,
block_index,
Expand All @@ -1069,10 +1083,11 @@ async fn invalid_signature_attestation() {

#[tokio::test]
async fn invalid_signature_deposit() {
let (chain_segment, mut chain_segment_blobs) = get_chain_segment().await;
let (chain_segment, ref_blobs) = get_chain_segment().await;
let mut chain_segment_blobs = ref_blobs.clone();
for &block_index in BLOCK_INDICES {
// Note: an invalid deposit signature is permitted!
let harness = get_invalid_sigs_harness(&chain_segment).await;
let harness = get_invalid_sigs_harness(chain_segment).await;
let mut snapshots = chain_segment.clone();
let deposit = Deposit {
proof: vec![Hash256::zero(); DEPOSIT_TREE_DEPTH + 1]
Expand Down Expand Up @@ -1126,9 +1141,10 @@ async fn invalid_signature_exit() {
if fork_name_from_env().is_some_and(|f| f.gloas_enabled()) {
return;
}
let (chain_segment, mut chain_segment_blobs) = get_chain_segment().await;
let (chain_segment, ref_blobs) = get_chain_segment().await;
let mut chain_segment_blobs = ref_blobs.clone();
for &block_index in BLOCK_INDICES {
let harness = get_invalid_sigs_harness(&chain_segment).await;
let harness = get_invalid_sigs_harness(chain_segment).await;
let mut snapshots = chain_segment.clone();
let epoch = snapshots[block_index].beacon_state.current_epoch();
let (mut block, signature) = snapshots[block_index]
Expand All @@ -1152,7 +1168,7 @@ async fn invalid_signature_exit() {
update_parent_roots(&mut snapshots, &mut chain_segment_blobs);
update_proposal_signatures(&mut snapshots, &harness);
assert_invalid_signature(
&chain_segment,
chain_segment,
&chain_segment_blobs,
&harness,
block_index,
Expand All @@ -1173,7 +1189,8 @@ fn unwrap_err<T, U>(result: Result<T, U>) -> U {
#[tokio::test]
async fn block_gossip_verification() {
let harness = get_harness(VALIDATOR_COUNT, NodeCustodyType::Fullnode);
let (chain_segment, chain_segment_blobs) = get_chain_segment().await;
let (chain_segment, ref_blobs) = get_chain_segment().await;
let chain_segment_blobs = ref_blobs.clone();

let block_index = CHAIN_SEGMENT_LENGTH - 2;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,16 +14,16 @@ use tracing::{debug, warn};
use types::SignedExecutionPayloadBid;
use warp::{Filter, Rejection, Reply, hyper::Body, hyper::Response};

// POST /eth/v1/beacon/execution_payload_bid (SSZ)
pub(crate) fn post_beacon_execution_payload_bid_ssz<T: BeaconChainTypes>(
// POST /eth/v1/beacon/execution_payload_bids (SSZ)
pub(crate) fn post_beacon_execution_payload_bids_ssz<T: BeaconChainTypes>(
eth_v1: EthV1Filter,
task_spawner_filter: TaskSpawnerFilter<T>,
chain_filter: ChainFilter<T>,
network_tx_filter: NetworkTxFilter<T>,
) -> ResponseFilter {
eth_v1
.and(warp::path("beacon"))
.and(warp::path("execution_payload_bid"))
.and(warp::path("execution_payload_bids"))
.and(warp::path::end())
.and(warp::body::bytes())
.and(task_spawner_filter)
Expand All @@ -46,16 +46,16 @@ pub(crate) fn post_beacon_execution_payload_bid_ssz<T: BeaconChainTypes>(
.boxed()
}

// POST /eth/v1/beacon/execution_payload_bid
pub(crate) fn post_beacon_execution_payload_bid<T: BeaconChainTypes>(
// POST /eth/v1/beacon/execution_payload_bids
pub(crate) fn post_beacon_execution_payload_bids<T: BeaconChainTypes>(
eth_v1: EthV1Filter,
task_spawner_filter: TaskSpawnerFilter<T>,
chain_filter: ChainFilter<T>,
network_tx_filter: NetworkTxFilter<T>,
) -> ResponseFilter {
eth_v1
.and(warp::path("beacon"))
.and(warp::path("execution_payload_bid"))
.and(warp::path("execution_payload_bids"))
.and(warp::path::end())
.and(warp::body::json())
.and(task_spawner_filter)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,16 +24,16 @@ use warp::{
hyper::{Body, Response},
};

// POST beacon/execution_payload_envelope (SSZ)
pub(crate) fn post_beacon_execution_payload_envelope_ssz<T: BeaconChainTypes>(
// POST beacon/execution_payload_envelopes (SSZ)
pub(crate) fn post_beacon_execution_payload_envelopes_ssz<T: BeaconChainTypes>(
eth_v1: EthV1Filter,
task_spawner_filter: TaskSpawnerFilter<T>,
chain_filter: ChainFilter<T>,
network_tx_filter: NetworkTxFilter<T>,
) -> ResponseFilter {
eth_v1
.and(warp::path("beacon"))
.and(warp::path("execution_payload_envelope"))
.and(warp::path("execution_payload_envelopes"))
.and(warp::path::end())
.and(warp::body::bytes())
.and(task_spawner_filter)
Expand All @@ -57,16 +57,16 @@ pub(crate) fn post_beacon_execution_payload_envelope_ssz<T: BeaconChainTypes>(
.boxed()
}

// POST beacon/execution_payload_envelope
pub(crate) fn post_beacon_execution_payload_envelope<T: BeaconChainTypes>(
// POST beacon/execution_payload_envelopes
pub(crate) fn post_beacon_execution_payload_envelopes<T: BeaconChainTypes>(
eth_v1: EthV1Filter,
task_spawner_filter: TaskSpawnerFilter<T>,
chain_filter: ChainFilter<T>,
network_tx_filter: NetworkTxFilter<T>,
) -> ResponseFilter {
eth_v1
.and(warp::path("beacon"))
.and(warp::path("execution_payload_envelope"))
.and(warp::path("execution_payload_envelopes"))
.and(warp::path::end())
.and(warp::body::json())
.and(task_spawner_filter.clone())
Expand All @@ -85,7 +85,7 @@ pub(crate) fn post_beacon_execution_payload_envelope<T: BeaconChainTypes>(
.boxed()
}
/// Publishes a signed execution payload envelope to the network. Implements
/// `POST /eth/v1/beacon/execution_payload_envelope` per the in-flight beacon-APIs PR
/// `POST /eth/v1/beacon/execution_payload_envelopes` per the in-flight beacon-APIs PR
/// <https://github.com/ethereum/beacon-APIs/pull/580>.
pub async fn publish_execution_payload_envelope<T: BeaconChainTypes>(
envelope: SignedExecutionPayloadEnvelope<T::EthSpec>,
Expand Down Expand Up @@ -292,8 +292,8 @@ fn build_gloas_data_columns<T: BeaconChainTypes>(
}

// TODO(gloas): add tests for this endpoint once we support importing payloads into the db
// GET beacon/execution_payload_envelope/{block_id}
pub(crate) fn get_beacon_execution_payload_envelope<T: BeaconChainTypes>(
// GET beacon/execution_payload_envelopes/{block_id}
pub(crate) fn get_beacon_execution_payload_envelopes<T: BeaconChainTypes>(
eth_v1: EthV1Filter,
block_id_or_err: impl Filter<Extract = (BlockId,), Error = Rejection>
+ Clone
Expand All @@ -305,7 +305,7 @@ pub(crate) fn get_beacon_execution_payload_envelope<T: BeaconChainTypes>(
) -> ResponseFilter {
eth_v1
.and(warp::path("beacon"))
.and(warp::path("execution_payload_envelope"))
.and(warp::path("execution_payload_envelopes"))
.and(block_id_or_err)
.and(warp::path::end())
.and(task_spawner_filter)
Expand Down
4 changes: 2 additions & 2 deletions beacon_node/http_api/src/beacon/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
pub mod execution_payload_bid;
pub mod execution_payload_envelope;
pub mod execution_payload_bids;
pub mod execution_payload_envelopes;
pub mod pool;
pub mod states;
Loading
Loading