Skip to content
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
261c782
Add Electra and Fulu forks to basic sim tests.
jimmygchen Mar 25, 2025
f2c5981
Add error message on panic and update CI job name.
jimmygchen Mar 25, 2025
dcab218
Merge remote-tracking branch 'origin/unstable' into add-electra-fulu-…
jimmygchen Apr 9, 2025
23f0ac9
Fix lint
jimmygchen Apr 9, 2025
2c52e47
Filter deps logs.
jimmygchen Apr 9, 2025
fc08254
Compute proposer shuffling only once in gossip verification (#7304)
jimmygchen Apr 10, 2025
0d292b0
Log missed slots.
jimmygchen Apr 11, 2025
7a0a25a
Merge remote-tracking branch 'origin/unstable' into add-electra-fulu-…
jimmygchen Apr 11, 2025
5b63d6b
Merge branch 'unstable' into add-electra-fulu-sim-test-support
michaelsproul Apr 30, 2025
b80a1a5
Reduce number of supernodes in sim tests. 6 supernodes on a single ma…
jimmygchen Apr 30, 2025
3374085
Fix incorrect epoch calculation resulting in shuffling cache miss. Fi…
jimmygchen Apr 30, 2025
23c8fdc
Revert "Compute proposer shuffling only once in gossip verification (…
jimmygchen Apr 30, 2025
bdb6ab3
Fix build.
jimmygchen Apr 30, 2025
31344ce
Merge remote-tracking branch 'origin/unstable' into add-electra-fulu-…
jimmygchen May 1, 2025
87a2c3a
Clean up and reduce max blobs per block for testing PeerDAS.
jimmygchen May 1, 2025
f976de8
Lower number of nodes from 6 to 4.
jimmygchen May 1, 2025
dc7b310
Fix incorrect logging.
jimmygchen May 1, 2025
b0d8fbe
Try longer slot time.
jimmygchen May 1, 2025
75b4b52
Remove Fulu fork from basic sim
jimmygchen May 5, 2025
bf8fa3c
Merge branch 'unstable' into add-electra-fulu-sim-test-support
jimmygchen May 5, 2025
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
4 changes: 2 additions & 2 deletions .github/workflows/test-suite.yml
Original file line number Diff line number Diff line change
Expand Up @@ -295,8 +295,8 @@ jobs:
with:
channel: stable
cache-target: release
- name: Run a basic beacon chain sim that starts from Bellatrix
run: cargo run --release --bin simulator basic-sim
- name: Run a basic beacon chain sim that starts from Deneb
run: cargo run --release --bin simulator basic-sim --speed-up-factor 2
fallback-simulator-ubuntu:
name: fallback-simulator-ubuntu
needs: [check-labels]
Expand Down
21 changes: 10 additions & 11 deletions beacon_node/beacon_chain/src/data_column_verification.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ use derivative::Derivative;
use fork_choice::ProtoBlock;
use kzg::{Error as KzgError, Kzg};
use proto_array::Block;
use slasher::test_utils::E;
use slot_clock::SlotClock;
use ssz_derive::{Decode, Encode};
use std::iter;
Expand Down Expand Up @@ -589,19 +588,19 @@ fn verify_proposer_and_signature<T: BeaconChainTypes>(
chain: &BeaconChain<T>,
) -> Result<(), GossipDataColumnError> {
let column_slot = data_column.slot();
let column_epoch = column_slot.epoch(E::slots_per_epoch());
let slots_per_epoch = T::EthSpec::slots_per_epoch();
let column_epoch = column_slot.epoch(slots_per_epoch);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bug in minimal preset - causing proposer shuffling miss for every gossip column.

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_shuffling_root = if parent_block.slot.epoch(slots_per_epoch) == column_epoch {
parent_block
.next_epoch_shuffling_id
.shuffling_decision_block
} else {
parent_block.root
};

// We lock the cache briefly to get or insert a OnceCell, then drop the lock
// before doing proposer shuffling calculation via `OnceCell::get_or_try_init`. This avoids
Expand Down Expand Up @@ -649,7 +648,7 @@ fn verify_proposer_and_signature<T: BeaconChainTypes>(

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

let fork = epoch_proposers.fork;
Expand Down
3 changes: 1 addition & 2 deletions testing/node_test_rig/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ use environment::RuntimeContext;
use eth2::{reqwest::ClientBuilder, BeaconNodeHttpClient, Timeouts};
use sensitive_url::SensitiveUrl;
use std::path::PathBuf;
use std::sync::Arc;
use std::time::Duration;
use std::time::{SystemTime, UNIX_EPOCH};
use tempfile::{Builder as TempBuilder, TempDir};
Expand Down Expand Up @@ -249,7 +248,7 @@ impl<E: EthSpec> LocalExecutionNode<E> {
if let Err(e) = std::fs::write(jwt_file_path, config.jwt_key.hex_string()) {
panic!("Failed to write jwt file {}", e);
}
let spec = Arc::new(E::default_spec());
let spec = context.eth2_config.spec.clone();
Self {
server: MockServer::new_with_config(
&context.executor.handle().unwrap(),
Expand Down
44 changes: 32 additions & 12 deletions testing/simulator/src/basic_sim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,22 @@ use environment::tracing_common;
use tracing_subscriber::prelude::*;
use tracing_subscriber::{layer::SubscriberExt, util::SubscriberInitExt};

use logging::build_workspace_filter;
use tokio::time::sleep;
use types::{Epoch, EthSpec, MinimalEthSpec};

const END_EPOCH: u64 = 16;
const GENESIS_DELAY: u64 = 32;
const ALTAIR_FORK_EPOCH: u64 = 0;
const BELLATRIX_FORK_EPOCH: u64 = 0;
const CAPELLA_FORK_EPOCH: u64 = 1;
const DENEB_FORK_EPOCH: u64 = 2;
// const ELECTRA_FORK_EPOCH: u64 = 3;
// const FULU_FORK_EPOCH: u64 = 4;
const CAPELLA_FORK_EPOCH: u64 = 0;
const DENEB_FORK_EPOCH: u64 = 0;
const ELECTRA_FORK_EPOCH: u64 = 1;
// Set Fulu fork epoch half way through the test, so that:
// 1. We run the simulator for a few electra epochs to cover electra testing;
// 2. The Fulu fork epoch is not too close to Electra fork epoch, so we're not subscribed to topics
// across 3 forks simultaneously.
const FULU_FORK_EPOCH: u64 = 8;

const SUGGESTED_FEE_RECIPIENT: [u8; 20] =
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1];
Expand Down Expand Up @@ -116,7 +121,11 @@ pub fn run_basic_sim(matches: &ArgMatches) -> Result<(), String> {
);

if let Err(e) = tracing_subscriber::registry()
.with(stdout_logging_layer.with_filter(logger_config.debug_level))
.with(
stdout_logging_layer
.with_filter(logger_config.debug_level)
.with_filter(build_workspace_filter()?),
)
.try_init()
{
eprintln!("Failed to initialize dependency logging: {e}");
Expand All @@ -130,8 +139,8 @@ pub fn run_basic_sim(matches: &ArgMatches) -> Result<(), String> {
let genesis_delay = GENESIS_DELAY;

// Convenience variables. Update these values when adding a newer fork.
let latest_fork_version = spec.deneb_fork_version;
let latest_fork_start_epoch = DENEB_FORK_EPOCH;
let latest_fork_version = spec.fulu_fork_version;
let latest_fork_start_epoch = FULU_FORK_EPOCH;

spec.seconds_per_slot /= speed_up_factor;
spec.seconds_per_slot = max(1, spec.seconds_per_slot);
Expand All @@ -142,8 +151,8 @@ pub fn run_basic_sim(matches: &ArgMatches) -> Result<(), String> {
spec.bellatrix_fork_epoch = Some(Epoch::new(BELLATRIX_FORK_EPOCH));
spec.capella_fork_epoch = Some(Epoch::new(CAPELLA_FORK_EPOCH));
spec.deneb_fork_epoch = Some(Epoch::new(DENEB_FORK_EPOCH));
//spec.electra_fork_epoch = Some(Epoch::new(ELECTRA_FORK_EPOCH));
//spec.fulu_fork_epoch = Some(Epoch::new(FULU_FORK_EPOCH));
spec.electra_fork_epoch = Some(Epoch::new(ELECTRA_FORK_EPOCH));
spec.fulu_fork_epoch = Some(Epoch::new(FULU_FORK_EPOCH));
let spec = Arc::new(spec);
env.eth2_config.spec = spec.clone();

Expand Down Expand Up @@ -175,16 +184,27 @@ pub fn run_basic_sim(matches: &ArgMatches) -> Result<(), String> {
.await?;

// Add nodes to the network.
for _ in 0..node_count {
for i in 0..node_count {
let mut beacon_config = beacon_config.clone();
// Run one PeerDAS supernode.
if i == 0 {
beacon_config.network.subscribe_all_data_column_subnets = true;
}
network
.add_beacon_node(beacon_config.clone(), mock_execution_config.clone(), false)
.add_beacon_node(beacon_config, mock_execution_config.clone(), false)
.await?;
}

/*
* One by one, add proposer nodes to the network.
*/
for _ in 0..proposer_nodes {
for i in 0..proposer_nodes {
let mut beacon_config = beacon_config.clone();
// Run one PeerDAS proposer supernode.
if i == 0 {
beacon_config.network.subscribe_all_data_column_subnets = true;
}

println!("Adding a proposer node");
network
.add_beacon_node(beacon_config.clone(), mock_execution_config.clone(), true)
Expand Down
31 changes: 21 additions & 10 deletions testing/simulator/src/checks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,17 +128,23 @@ pub async fn verify_full_block_production_up_to<E: EthSpec>(
slot_delay(slot, slot_duration).await;
let beacon_nodes = network.beacon_nodes.read();
let beacon_chain = beacon_nodes[0].client.beacon_chain().unwrap();
let num_blocks = beacon_chain
let block_slots = beacon_chain
.chain_dump()
.unwrap()
.iter()
.take_while(|s| s.beacon_block.slot() <= slot)
.count();
.map(|s| s.beacon_block.slot().as_usize())
.collect::<Vec<_>>();
let num_blocks = block_slots.len();
if num_blocks != slot.as_usize() + 1 {
let missed_slots = (0..slot.as_usize())
.filter(|slot| !block_slots.contains(slot))
.collect::<Vec<_>>();
return Err(format!(
"There wasn't a block produced at every slot, got: {}, expected: {}",
"There wasn't a block produced at every slot, got: {}, expected: {}, missed: {:?}",
num_blocks,
slot.as_usize() + 1
slot.as_usize() + 1,
missed_slots
));
}
Ok(())
Expand Down Expand Up @@ -185,12 +191,17 @@ pub async fn verify_full_sync_aggregates_up_to<E: EthSpec>(
.get_beacon_blocks::<E>(BlockId::Slot(Slot::new(slot)))
.await
.map(|resp| {
resp.unwrap()
.data
.message()
.body()
.sync_aggregate()
.map(|agg| agg.num_set_bits())
resp.unwrap_or_else(|| {
panic!(
"Beacon block for slot {} not returned from Beacon API",
slot
)
})
.data
.message()
.body()
.sync_aggregate()
.map(|agg| agg.num_set_bits())
})
.map_err(|e| format!("Error while getting beacon block: {:?}", e))?
.map_err(|_| format!("Altair block {} should have sync aggregate", slot))?;
Expand Down
1 change: 1 addition & 0 deletions testing/simulator/src/local_network.rs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ fn default_client_config(network_params: LocalNetworkParams, genesis_time: u64)
beacon_config.network.enr_address = (Some(Ipv4Addr::LOCALHOST), None);
beacon_config.network.enable_light_client_server = true;
beacon_config.network.discv5_config.enable_packet_filter = false;
beacon_config.network.subscribe_all_data_column_subnets = false;
beacon_config.chain.enable_light_client_server = true;
beacon_config.chain.optimistic_finalized_sync = false;
beacon_config.trusted_setup = serde_json::from_reader(get_trusted_setup().as_slice())
Expand Down
Loading