Skip to content

Commit 2a3eea8

Browse files
paulhaunerWoodpile37
authored andcommitted
Configure the validator/register_validator batch size via the CLI (sigp#4399)
## Issue Addressed NA ## Proposed Changes Adds the `--validator-registration-batch-size` flag to the VC to allow runtime configuration of the number of validators POSTed to the [`validator/register_validator`](https://ethereum.github.io/beacon-APIs/?urls.primaryName=dev#/Validator/registerValidator) endpoint. There are builders (Agnostic and Eden) that are timing out with `regsiterValidator` requests with ~400 validators, even with a 9 second timeout. Exposing the batch size will help tune batch sizes to (hopefully) avoid this. This PR should not change the behavior of Lighthouse when the new flag is not provided (i.e., the same default value is used). ## Additional Info NA
1 parent e10b811 commit 2a3eea8

File tree

5 files changed

+57
-5
lines changed

5 files changed

+57
-5
lines changed

lighthouse/tests/validator_client.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,3 +499,24 @@ fn latency_measurement_service() {
499499
assert!(!config.enable_latency_measurement_service);
500500
});
501501
}
502+
503+
#[test]
504+
fn validator_registration_batch_size() {
505+
CommandLineTest::new().run().with_config(|config| {
506+
assert_eq!(config.validator_registration_batch_size, 500);
507+
});
508+
CommandLineTest::new()
509+
.flag("validator-registration-batch-size", Some("100"))
510+
.run()
511+
.with_config(|config| {
512+
assert_eq!(config.validator_registration_batch_size, 100);
513+
});
514+
}
515+
516+
#[test]
517+
#[should_panic]
518+
fn validator_registration_batch_size_zero_value() {
519+
CommandLineTest::new()
520+
.flag("validator-registration-batch-size", Some("0"))
521+
.run();
522+
}

validator_client/src/cli.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,16 @@ pub fn cli_app<'a, 'b>() -> App<'a, 'b> {
333333
.default_value("true")
334334
.takes_value(true),
335335
)
336+
.arg(
337+
Arg::with_name("validator-registration-batch-size")
338+
.long("validator-registration-batch-size")
339+
.value_name("INTEGER")
340+
.help("Defines the number of validators per \
341+
validator/register_validator request sent to the BN. This value \
342+
can be reduced to avoid timeouts from builders.")
343+
.default_value("500")
344+
.takes_value(true),
345+
)
336346
/*
337347
* Experimental/development options.
338348
*/

validator_client/src/config.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,8 @@ pub struct Config {
7777
pub disable_run_on_all: bool,
7878
/// Enables a service which attempts to measure latency between the VC and BNs.
7979
pub enable_latency_measurement_service: bool,
80+
/// Defines the number of validators per `validator/register_validator` request sent to the BN.
81+
pub validator_registration_batch_size: usize,
8082
}
8183

8284
impl Default for Config {
@@ -117,6 +119,7 @@ impl Default for Config {
117119
gas_limit: None,
118120
disable_run_on_all: false,
119121
enable_latency_measurement_service: true,
122+
validator_registration_batch_size: 500,
120123
}
121124
}
122125
}
@@ -380,6 +383,12 @@ impl Config {
380383
config.enable_latency_measurement_service =
381384
parse_optional(cli_args, "latency-measurement-service")?.unwrap_or(true);
382385

386+
config.validator_registration_batch_size =
387+
parse_required(cli_args, "validator-registration-batch-size")?;
388+
if config.validator_registration_batch_size == 0 {
389+
return Err("validator-registration-batch-size cannot be 0".to_string());
390+
}
391+
383392
/*
384393
* Experimental
385394
*/

validator_client/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ impl<T: EthSpec> ProductionValidatorClient<T> {
487487
.beacon_nodes(beacon_nodes.clone())
488488
.runtime_context(context.service_context("preparation".into()))
489489
.builder_registration_timestamp_override(config.builder_registration_timestamp_override)
490+
.validator_registration_batch_size(config.validator_registration_batch_size)
490491
.build()?;
491492

492493
let sync_committee_service = SyncCommitteeService::new(

validator_client/src/preparation_service.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,16 +23,14 @@ const PROPOSER_PREPARATION_LOOKAHEAD_EPOCHS: u64 = 2;
2323
/// Number of epochs to wait before re-submitting validator registration.
2424
const EPOCHS_PER_VALIDATOR_REGISTRATION_SUBMISSION: u64 = 1;
2525

26-
/// The number of validator registrations to include per request to the beacon node.
27-
const VALIDATOR_REGISTRATION_BATCH_SIZE: usize = 500;
28-
2926
/// Builds an `PreparationService`.
3027
pub struct PreparationServiceBuilder<T: SlotClock + 'static, E: EthSpec> {
3128
validator_store: Option<Arc<ValidatorStore<T, E>>>,
3229
slot_clock: Option<T>,
3330
beacon_nodes: Option<Arc<BeaconNodeFallback<T, E>>>,
3431
context: Option<RuntimeContext<E>>,
3532
builder_registration_timestamp_override: Option<u64>,
33+
validator_registration_batch_size: Option<usize>,
3634
}
3735

3836
impl<T: SlotClock + 'static, E: EthSpec> PreparationServiceBuilder<T, E> {
@@ -43,6 +41,7 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationServiceBuilder<T, E> {
4341
beacon_nodes: None,
4442
context: None,
4543
builder_registration_timestamp_override: None,
44+
validator_registration_batch_size: None,
4645
}
4746
}
4847

@@ -74,6 +73,14 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationServiceBuilder<T, E> {
7473
self
7574
}
7675

76+
pub fn validator_registration_batch_size(
77+
mut self,
78+
validator_registration_batch_size: usize,
79+
) -> Self {
80+
self.validator_registration_batch_size = Some(validator_registration_batch_size);
81+
self
82+
}
83+
7784
pub fn build(self) -> Result<PreparationService<T, E>, String> {
7885
Ok(PreparationService {
7986
inner: Arc::new(Inner {
@@ -91,6 +98,9 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationServiceBuilder<T, E> {
9198
.ok_or("Cannot build PreparationService without runtime_context")?,
9299
builder_registration_timestamp_override: self
93100
.builder_registration_timestamp_override,
101+
validator_registration_batch_size: self.validator_registration_batch_size.ok_or(
102+
"Cannot build PreparationService without validator_registration_batch_size",
103+
)?,
94104
validator_registration_cache: RwLock::new(HashMap::new()),
95105
}),
96106
})
@@ -107,6 +117,7 @@ pub struct Inner<T, E: EthSpec> {
107117
// Used to track unpublished validator registration changes.
108118
validator_registration_cache:
109119
RwLock<HashMap<ValidatorRegistrationKey, SignedValidatorRegistrationData>>,
120+
validator_registration_batch_size: usize,
110121
}
111122

112123
#[derive(Hash, Eq, PartialEq, Debug, Clone)]
@@ -447,7 +458,7 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
447458
}
448459

449460
if !signed.is_empty() {
450-
for batch in signed.chunks(VALIDATOR_REGISTRATION_BATCH_SIZE) {
461+
for batch in signed.chunks(self.validator_registration_batch_size) {
451462
match self
452463
.beacon_nodes
453464
.first_success(
@@ -462,7 +473,7 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
462473
Ok(()) => info!(
463474
log,
464475
"Published validator registrations to the builder network";
465-
"count" => registration_data_len,
476+
"count" => batch.len(),
466477
),
467478
Err(e) => warn!(
468479
log,

0 commit comments

Comments
 (0)