Skip to content

Commit 6e11bdd

Browse files
authored
feat: adds CLI flags to delay publishing for edge case testing on PeerDAS devnets (#6947)
Closes #6919
1 parent 3fab6a2 commit 6e11bdd

File tree

5 files changed

+92
-0
lines changed

5 files changed

+92
-0
lines changed

beacon_node/beacon_chain/src/chain_config.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,10 @@ pub struct ChainConfig {
9494
/// The delay in milliseconds applied by the node between sending each blob or data column batch.
9595
/// This doesn't apply if the node is the block proposer.
9696
pub blob_publication_batch_interval: Duration,
97+
/// Artificial delay for block publishing. For PeerDAS testing only.
98+
pub block_publishing_delay: Option<Duration>,
99+
/// Artificial delay for data column publishing. For PeerDAS testing only.
100+
pub data_column_publishing_delay: Option<Duration>,
97101
}
98102

99103
impl Default for ChainConfig {
@@ -129,6 +133,8 @@ impl Default for ChainConfig {
129133
enable_sampling: false,
130134
blob_publication_batches: 4,
131135
blob_publication_batch_interval: Duration::from_millis(300),
136+
block_publishing_delay: None,
137+
data_column_publishing_delay: None,
132138
}
133139
}
134140
}

beacon_node/http_api/src/publish_blocks.rs

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlock<T>>(
8686
network_globals: Arc<NetworkGlobals<T::EthSpec>>,
8787
) -> Result<Response, Rejection> {
8888
let seen_timestamp = timestamp_now();
89+
let block_publishing_delay_for_testing = chain.config.block_publishing_delay;
90+
let data_column_publishing_delay_for_testing = chain.config.data_column_publishing_delay;
8991

9092
let (unverified_block, unverified_blobs, is_locally_built_block) = match provenanced_block {
9193
ProvenancedBlock::Local(block, blobs, _) => (block, blobs, true),
@@ -147,6 +149,14 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlock<T>>(
147149

148150
let should_publish_block = gossip_verified_block_result.is_ok();
149151
if BroadcastValidation::Gossip == validation_level && should_publish_block {
152+
if let Some(block_publishing_delay) = block_publishing_delay_for_testing {
153+
debug!(
154+
log,
155+
"Publishing block with artificial delay";
156+
"block_publishing_delay" => ?block_publishing_delay
157+
);
158+
tokio::time::sleep(block_publishing_delay).await;
159+
}
150160
publish_block_p2p(
151161
block.clone(),
152162
sender_clone.clone(),
@@ -207,6 +217,23 @@ pub async fn publish_block<T: BeaconChainTypes, B: IntoGossipVerifiedBlock<T>>(
207217
}
208218

209219
if gossip_verified_columns.iter().map(Option::is_some).count() > 0 {
220+
if let Some(data_column_publishing_delay) = data_column_publishing_delay_for_testing {
221+
// Subtract block publishing delay if it is also used.
222+
// Note: if `data_column_publishing_delay` is less than `block_publishing_delay`, it
223+
// will still be delayed by `block_publishing_delay`. This could be solved with spawning
224+
// async tasks but the limitation is minor and I believe it's probably not worth
225+
// affecting the mainnet code path.
226+
let block_publishing_delay = block_publishing_delay_for_testing.unwrap_or_default();
227+
let delay = data_column_publishing_delay.saturating_sub(block_publishing_delay);
228+
if !delay.is_zero() {
229+
debug!(
230+
log,
231+
"Publishing data columns with artificial delay";
232+
"data_column_publishing_delay" => ?data_column_publishing_delay
233+
);
234+
tokio::time::sleep(delay).await;
235+
}
236+
}
210237
publish_column_sidecars(network_tx, &gossip_verified_columns, &chain).map_err(|_| {
211238
warp_utils::reject::custom_server_error("unable to publish data column sidecars".into())
212239
})?;

beacon_node/src/cli.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1599,5 +1599,30 @@ pub fn cli_app() -> Command {
15991599
.action(ArgAction::Set)
16001600
.display_order(0)
16011601
)
1602+
.arg(
1603+
Arg::new("delay-block-publishing")
1604+
.long("delay-block-publishing")
1605+
.value_name("SECONDS")
1606+
.action(ArgAction::Set)
1607+
.help_heading(FLAG_HEADER)
1608+
.help("TESTING ONLY: Artificially delay block publishing by the specified number of seconds. \
1609+
This only works for if `BroadcastValidation::Gossip` is used (default). \
1610+
DO NOT USE IN PRODUCTION.")
1611+
.hide(true)
1612+
.display_order(0)
1613+
)
1614+
.arg(
1615+
Arg::new("delay-data-column-publishing")
1616+
.long("delay-data-column-publishing")
1617+
.value_name("SECONDS")
1618+
.action(ArgAction::Set)
1619+
.help_heading(FLAG_HEADER)
1620+
.help("TESTING ONLY: Artificially delay data column publishing by the specified number of seconds. \
1621+
Limitation: If `delay-block-publishing` is also used, data columns will be delayed for a \
1622+
minimum of `delay-block-publishing` seconds.
1623+
DO NOT USE IN PRODUCTION.")
1624+
.hide(true)
1625+
.display_order(0)
1626+
)
16021627
.group(ArgGroup::new("enable_http").args(["http", "gui", "staking"]).multiple(true))
16031628
}

beacon_node/src/config.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -895,6 +895,14 @@ pub fn get_config<E: EthSpec>(
895895
.max_gossip_aggregate_batch_size =
896896
clap_utils::parse_required(cli_args, "beacon-processor-aggregate-batch-size")?;
897897

898+
if let Some(delay) = clap_utils::parse_optional(cli_args, "delay-block-publishing")? {
899+
client_config.chain.block_publishing_delay = Some(Duration::from_secs_f64(delay));
900+
}
901+
902+
if let Some(delay) = clap_utils::parse_optional(cli_args, "delay-data-column-publishing")? {
903+
client_config.chain.data_column_publishing_delay = Some(Duration::from_secs_f64(delay));
904+
}
905+
898906
Ok(client_config)
899907
}
900908

lighthouse/tests/beacon_node.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2715,3 +2715,29 @@ fn beacon_node_backend_override() {
27152715
assert_eq!(config.store.backend, BeaconNodeBackend::LevelDb);
27162716
});
27172717
}
2718+
2719+
#[test]
2720+
fn block_publishing_delay_for_testing() {
2721+
CommandLineTest::new()
2722+
.flag("delay-block-publishing", Some("2.5"))
2723+
.run_with_zero_port()
2724+
.with_config(|config| {
2725+
assert_eq!(
2726+
config.chain.block_publishing_delay,
2727+
Some(Duration::from_secs_f64(2.5f64))
2728+
);
2729+
});
2730+
}
2731+
2732+
#[test]
2733+
fn data_column_publishing_delay_for_testing() {
2734+
CommandLineTest::new()
2735+
.flag("delay-data-column-publishing", Some("3.5"))
2736+
.run_with_zero_port()
2737+
.with_config(|config| {
2738+
assert_eq!(
2739+
config.chain.data_column_publishing_delay,
2740+
Some(Duration::from_secs_f64(3.5f64))
2741+
);
2742+
});
2743+
}

0 commit comments

Comments
 (0)