Skip to content

Commit aaab142

Browse files
committed
v2: add most of the remaining changes
1 parent 2c29c6b commit aaab142

File tree

8 files changed

+130
-64
lines changed

8 files changed

+130
-64
lines changed

common/eth2/src/lighthouse_vc/types.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ pub struct CreatedValidator {
6565
#[serde(default)]
6666
#[serde(skip_serializing_if = "Option::is_none")]
6767
pub builder_proposals: Option<bool>,
68+
#[serde(skip_serializing_if = "Option::is_none")]
69+
pub builder_pubkey_override: Option<PublicKeyBytes>,
70+
#[serde(skip_serializing_if = "Option::is_none")]
71+
pub builder_timestamp_override: Option<u64>,
6872
pub eth1_deposit_tx_data: String,
6973
#[serde(with = "eth2_serde_utils::quoted_u64")]
7074
pub deposit_gwei: u64,
@@ -132,6 +136,8 @@ pub struct Web3SignerValidatorRequest {
132136
pub builder_proposals: Option<bool>,
133137
#[serde(skip_serializing_if = "Option::is_none")]
134138
pub builder_pubkey_override: Option<PublicKeyBytes>,
139+
#[serde(skip_serializing_if = "Option::is_none")]
140+
pub builder_timestamp_override: Option<u64>,
135141
pub voting_public_key: PublicKey,
136142
pub url: String,
137143
#[serde(default)]

validator_client/src/http_api/create_validator.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ pub async fn create_validators_mnemonic<P: AsRef<Path>, T: 'static + SlotClock,
142142
request.suggested_fee_recipient,
143143
request.gas_limit,
144144
request.builder_proposals,
145-
request.builder_pubkey_override
145+
request.builder_pubkey_override,
146+
request.builder_timestamp_override
146147
)
147148
.await
148149
.map_err(|e| {
@@ -159,6 +160,8 @@ pub async fn create_validators_mnemonic<P: AsRef<Path>, T: 'static + SlotClock,
159160
suggested_fee_recipient: request.suggested_fee_recipient,
160161
gas_limit: request.gas_limit,
161162
builder_proposals: request.builder_proposals,
163+
builder_pubkey_override: request.builder_pubkey_override,
164+
builder_timestamp_override: request.builder_timestamp_override,
162165
voting_pubkey,
163166
eth1_deposit_tx_data: eth2_serde_utils::hex::encode(&eth1_deposit_data.rlp),
164167
deposit_gwei: request.deposit_gwei,

validator_client/src/http_api/keystores.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,7 @@ fn import_single_keystore<T: SlotClock + 'static, E: EthSpec>(
208208
None,
209209
None,
210210
None,
211+
None
211212
))
212213
.map_err(|e| format!("failed to initialize validator: {:?}", e))?;
213214

validator_client/src/http_api/tests.rs

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -286,6 +286,7 @@ impl ApiTester {
286286
gas_limit: None,
287287
builder_proposals: None,
288288
builder_pubkey_override: None,
289+
builder_timestamp_override: None,
289290
deposit_gwei: E::default_spec().max_effective_balance,
290291
})
291292
.collect::<Vec<_>>();
@@ -480,6 +481,7 @@ impl ApiTester {
480481
gas_limit: None,
481482
builder_proposals: None,
482483
builder_pubkey_override: None,
484+
builder_timestamp_override: None,
483485
voting_public_key: kp.pk,
484486
url: format!("http://signer_{}.com/", i),
485487
root_certificate_path: None,
@@ -536,7 +538,7 @@ impl ApiTester {
536538
let validator = &self.client.get_lighthouse_validators().await.unwrap().data[index];
537539

538540
self.client
539-
.patch_lighthouse_validators(&validator.voting_pubkey, Some(enabled), None, None)
541+
.patch_lighthouse_validators(&validator.voting_pubkey, Some(enabled), None, None, None, None)
540542
.await
541543
.unwrap();
542544

@@ -578,7 +580,7 @@ impl ApiTester {
578580
let validator = &self.client.get_lighthouse_validators().await.unwrap().data[index];
579581

580582
self.client
581-
.patch_lighthouse_validators(&validator.voting_pubkey, None, Some(gas_limit), None)
583+
.patch_lighthouse_validators(&validator.voting_pubkey, None, Some(gas_limit), None, None, None)
582584
.await
583585
.unwrap();
584586

@@ -605,6 +607,7 @@ impl ApiTester {
605607
None,
606608
None,
607609
Some(builder_proposals),
610+
None,
608611
None
609612
)
610613
.await
@@ -634,7 +637,8 @@ impl ApiTester {
634637
None,
635638
None,
636639
None,
637-
builder_pubkey_override
640+
Some(builder_pubkey_override),
641+
None
638642
)
639643
.await
640644
.unwrap();
@@ -647,9 +651,38 @@ impl ApiTester {
647651

648652
assert_eq!(
649653
self.validator_store
650-
.get
651-
// .get_builder_proposals(&validator.voting_pubkey),
652-
// builder_proposals
654+
.get_builder_pubkey_override(&validator.voting_pubkey),
655+
builder_pubkey_override
656+
);
657+
658+
self
659+
}
660+
661+
pub async fn set_builder_timestamp_override(self, index: usize, builder_timestamp_override: u64) -> Self {
662+
let validator = &self.client.get_lighthouse_validators().await.unwrap().data[index];
663+
664+
self.client
665+
.patch_lighthouse_validators(
666+
&validator.voting_pubkey,
667+
None,
668+
None,
669+
None,
670+
None,
671+
Some(builder_timestamp_override)
672+
)
673+
.await
674+
.unwrap();
675+
676+
self
677+
}
678+
679+
pub async fn assert_builder_timestamp_override(self, index: usize, builder_timestamp_override: u64) -> Self {
680+
let validator = &self.client.get_lighthouse_validators().await.unwrap().data[index];
681+
682+
assert_eq!(
683+
self.validator_store
684+
.get_builder_timestamp_override(&validator.voting_pubkey),
685+
builder_timestamp_override
653686
);
654687

655688
self
@@ -720,6 +753,8 @@ fn routes_with_invalid_auth() {
720753
suggested_fee_recipient: <_>::default(),
721754
gas_limit: <_>::default(),
722755
builder_proposals: <_>::default(),
756+
builder_pubkey_override: <_>::default(),
757+
builder_timestamp_override: <_>::default(),
723758
deposit_gwei: <_>::default(),
724759
}])
725760
.await

validator_client/src/http_api/tests/keystores.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ fn web3signer_validator_with_pubkey(pubkey: PublicKey) -> Web3SignerValidatorReq
4343
gas_limit: None,
4444
builder_proposals: None,
4545
builder_pubkey_override: None,
46+
builder_timestamp_override: None,
4647
voting_public_key: pubkey,
4748
url: web3_signer_url(),
4849
root_certificate_path: None,

validator_client/src/initialized_validators.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,6 +113,7 @@ pub struct InitializedValidator {
113113
gas_limit: Option<u64>,
114114
builder_proposals: Option<bool>,
115115
builder_pubkey_override: Option<PublicKeyBytes>,
116+
builder_timestamp_override: Option<u64>,
116117
/// The validators index in `state.validators`, to be updated by an external service.
117118
index: Option<u64>,
118119
}
@@ -147,6 +148,8 @@ impl InitializedValidator {
147148

148149
pub fn get_builder_pubkey_override(&self) -> Option<PublicKeyBytes> { self.builder_pubkey_override }
149150

151+
pub fn get_builder_timestamp_override(&self) -> Option<u64> { self.builder_timestamp_override }
152+
150153
pub fn get_index(&self) -> Option<u64> {
151154
self.index
152155
}
@@ -316,6 +319,7 @@ impl InitializedValidator {
316319
gas_limit: def.gas_limit,
317320
builder_proposals: def.builder_proposals,
318321
builder_pubkey_override: def.builder_pubkey_override,
322+
builder_timestamp_override: def.builder_timestamp_override,
319323
index: None,
320324
})
321325
}
@@ -677,6 +681,14 @@ impl InitializedValidators {
677681
.and_then(|v| v.builder_pubkey_override)
678682
}
679683

684+
/// Returns the `builder_timestamp_override` for a given public key specified in the
685+
/// `ValidatorDefinitions`.
686+
pub fn builder_timestamp_override(&self, public_key: &PublicKeyBytes) -> Option<u64> {
687+
self.validators
688+
.get(public_key)
689+
.and_then(|v| v.builder_timestamp_override)
690+
}
691+
680692
/// Returns an `Option` of a reference to an `InitializedValidator` for a given public key specified in the
681693
/// `ValidatorDefinitions`.
682694
pub fn validator(&self, public_key: &PublicKeyBytes) -> Option<&InitializedValidator> {

validator_client/src/preparation_service.rs

Lines changed: 50 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -113,23 +113,7 @@ pub struct Inner<T, E: EthSpec> {
113113
pub struct ValidatorRegistrationKey {
114114
pub fee_recipient: Address,
115115
pub gas_limit: u64,
116-
pub pubkey: PublicKeyBytes,
117-
}
118-
119-
impl From<ValidatorRegistrationData> for ValidatorRegistrationKey {
120-
fn from(data: ValidatorRegistrationData) -> Self {
121-
let ValidatorRegistrationData {
122-
fee_recipient,
123-
gas_limit,
124-
timestamp: _,
125-
pubkey,
126-
} = data;
127-
Self {
128-
fee_recipient,
129-
gas_limit,
130-
pubkey,
131-
}
132-
}
116+
pub signing_pubkey: PublicKeyBytes,
133117
}
134118

135119
/// Attempts to produce proposer preparations for all known validators at the beginning of each epoch.
@@ -284,21 +268,31 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
284268
})
285269
}
286270

287-
fn collect_validator_registration_keys(&self) -> Vec<ValidatorRegistrationKey> {
288-
self.collect_proposal_data(|pubkey, proposal_data| {
271+
fn collect_validator_registration_keys(&self) -> Vec<(PublicKeyBytes, ValidatorRegistrationKey)> {
272+
self.collect_proposal_data(|signing_pubkey, proposal_data| {
289273
// Ignore fee recipients for keys without indices, they are inactive.
290274
proposal_data.validator_index?;
291275

292276
// We don't log for missing fee recipients here because this will be logged more
293277
// frequently in `collect_preparation_data`.
294278
proposal_data.fee_recipient.and_then(|fee_recipient| {
295-
proposal_data
296-
.builder_proposals
297-
.then_some(ValidatorRegistrationKey {
298-
fee_recipient,
299-
gas_limit: proposal_data.gas_limit,
300-
pubkey,
301-
})
279+
proposal_data.builder_proposals.then(|| {
280+
let registration_pubkey =
281+
if let Some(pubkey_override) = proposal_data.builder_pubkey_override {
282+
pubkey_override
283+
} else {
284+
signing_pubkey
285+
};
286+
287+
(
288+
registration_pubkey,
289+
ValidatorRegistrationKey {
290+
fee_recipient,
291+
gas_limit: proposal_data.gas_limit,
292+
signing_pubkey,
293+
},
294+
)
295+
})
302296
})
303297
})
304298
}
@@ -357,31 +351,35 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
357351
}
358352

359353
/// Register validators with builders, used in the blinded block proposal flow.
354+
/// This method re-publishes all messages if it's been `EPOCHS_PER_VALIDATOR_REGISTRATION_SUBMISSION`.
355+
/// Otherwise it publishes any messages that have been updated since they were last published.
360356
async fn register_validators(&self) -> Result<(), String> {
361357
let registration_keys = self.collect_validator_registration_keys();
362358

363-
let mut changed_keys = vec![];
364-
365-
// Need to scope this so the read lock is not held across an await point (I don't know why
366-
// but the explicit `drop` is not enough).
367-
{
368-
let guard = self.validator_registration_cache.read();
369-
for key in registration_keys.iter() {
370-
if !guard.contains_key(key) {
371-
changed_keys.push(key.clone());
372-
}
373-
}
374-
drop(guard);
375-
}
376-
377359
// Check if any have changed or it's been `EPOCHS_PER_VALIDATOR_REGISTRATION_SUBMISSION`.
378360
if let Some(slot) = self.slot_clock.now() {
379361
if slot % (E::slots_per_epoch() * EPOCHS_PER_VALIDATOR_REGISTRATION_SUBMISSION) == 0 {
380362
self.publish_validator_registration_data(registration_keys)
381363
.await?;
382-
} else if !changed_keys.is_empty() {
383-
self.publish_validator_registration_data(changed_keys)
384-
.await?;
364+
} else {
365+
let mut changed_keys = vec![];
366+
367+
// Need to scope this so the read lock is not held across an await point (I don't know why
368+
// but the explicit `drop` is not enough).
369+
{
370+
let guard = self.validator_registration_cache.read();
371+
for (registration_pubkey, key) in registration_keys.into_iter() {
372+
if !guard.contains_key(&key) {
373+
changed_keys.push((registration_pubkey, key));
374+
}
375+
}
376+
drop(guard);
377+
}
378+
379+
if !changed_keys.is_empty() {
380+
self.publish_validator_registration_data(changed_keys)
381+
.await?;
382+
}
385383
}
386384
}
387385

@@ -390,14 +388,14 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
390388

391389
async fn publish_validator_registration_data(
392390
&self,
393-
registration_keys: Vec<ValidatorRegistrationKey>,
391+
registration_keys: Vec<(PublicKeyBytes, ValidatorRegistrationKey)>,
394392
) -> Result<(), String> {
395393
let log = self.context.log();
396394

397395
let registration_data_len = registration_keys.len();
398396
let mut signed = Vec::with_capacity(registration_data_len);
399397

400-
for key in registration_keys {
398+
for (registration_pubkey, key) in registration_keys {
401399
let cached_registration_opt =
402400
self.validator_registration_cache.read().get(&key).cloned();
403401

@@ -417,22 +415,23 @@ impl<T: SlotClock + 'static, E: EthSpec> PreparationService<T, E> {
417415
let ValidatorRegistrationKey {
418416
fee_recipient,
419417
gas_limit,
420-
pubkey,
418+
signing_pubkey,
421419
} = key.clone();
422420

423421
let signed_data = match self
424422
.validator_store
425-
.sign_validator_registration_data(ValidatorRegistrationData {
423+
.sign_validator_registration_data(signing_pubkey,
424+
ValidatorRegistrationData {
426425
fee_recipient,
427426
gas_limit,
428427
timestamp,
429-
pubkey,
428+
pubkey: registration_pubkey,
430429
})
431430
.await
432431
{
433432
Ok(data) => data,
434433
Err(e) => {
435-
error!(log, "Unable to sign validator registration data"; "error" => ?e, "pubkey" => ?pubkey);
434+
error!(log, "Unable to sign validator registration data"; "error" => ?e, "pubkey" => ?signing_pubkey);
436435
continue;
437436
}
438437
};
@@ -482,4 +481,6 @@ pub struct ProposalData {
482481
pub(crate) fee_recipient: Option<Address>,
483482
pub(crate) gas_limit: u64,
484483
pub(crate) builder_proposals: bool,
484+
pub(crate) builder_pubkey_override: Option<PublicKeyBytes>,
485+
pub(crate) builder_timestamp_override: Option<u64>
485486
}

0 commit comments

Comments
 (0)