Skip to content

Commit 9ae796d

Browse files
authored
Cache and resend, rather than recreate, builder API registrations (#4040)
1 parent 59092e5 commit 9ae796d

File tree

8 files changed

+54
-26
lines changed

8 files changed

+54
-26
lines changed

beacon_chain/consensus_object_pools/block_dag.nim

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ else:
1111
{.push raises: [].}
1212

1313
import
14-
std/options,
1514
chronicles,
1615
../spec/datatypes/[phase0, altair, bellatrix],
1716
../spec/forks

beacon_chain/consensus_object_pools/blockchain_dag.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1952,7 +1952,7 @@ proc preInit*(
19521952
tailStateSlot = getStateField(tailState, slot)
19531953

19541954
let genesisBlockRoot = withState(genesisState):
1955-
if state.root != getStateRoot(tailState):
1955+
if forkyState.root != getStateRoot(tailState):
19561956
# Different tail and genesis
19571957
if state.data.slot >= getStateField(tailState, slot):
19581958
fatal "Tail state must be newer or the same as genesis state"

beacon_chain/spec/beaconstate.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ else:
1111
{.push raises: [].}
1212

1313
import
14-
std/[algorithm, collections/heapqueue, math, options, sequtils, tables],
14+
std/[algorithm, collections/heapqueue, math, sequtils, tables],
1515
stew/assign2,
1616
json_serialization/std/sets,
1717
chronicles,

beacon_chain/spec/state_transition_block.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ else:
2323
{.push raises: [].}
2424

2525
import
26-
std/[algorithm, options, sequtils, sets, tables],
26+
std/[algorithm, sequtils, sets, tables],
2727
chronicles, metrics,
2828
../extras,
2929
./datatypes/[phase0, altair, bellatrix],
@@ -172,7 +172,7 @@ proc check_proposer_slashing*(
172172
state: var ForkedHashedBeaconState; proposer_slashing: SomeProposerSlashing;
173173
flags: UpdateFlags): Result[ValidatorIndex, cstring] =
174174
withState(state):
175-
check_proposer_slashing(state.data, proposer_slashing, flags)
175+
check_proposer_slashing(forkyState.data, proposer_slashing, flags)
176176

177177
# https://github.com/ethereum/consensus-specs/blob/v1.2.0-rc.3/specs/phase0/beacon-chain.md#proposer-slashings
178178
proc process_proposer_slashing*(

beacon_chain/validators/validator_duties.nim

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1280,6 +1280,8 @@ proc getValidatorRegistration(
12801280

12811281
return ok validatorRegistration
12821282

1283+
from std/sequtils import toSeq
1284+
12831285
proc registerValidators(node: BeaconNode, epoch: Epoch) {.async.} =
12841286
try:
12851287
if (not node.config.payloadBuilderEnable) or
@@ -1303,10 +1305,20 @@ proc registerValidators(node: BeaconNode, epoch: Epoch) {.async.} =
13031305
builderStatus = restBuilderStatus
13041306
return
13051307

1306-
# TODO cache the generated registrations and keep resending the previous ones
1308+
# The async aspect of signing the registrations can cause the attached
1309+
# validators to change during the loop.
1310+
let attachedValidatorPubkeys =
1311+
toSeq(node.attachedValidators[].validators.keys)
1312+
13071313
# https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/validator.md#validator-registration
13081314
var validatorRegistrations: seq[SignedValidatorRegistrationV1]
1309-
for validator in node.attachedValidators[].validators.values:
1315+
for key in attachedValidatorPubkeys:
1316+
# Time passed during awaits; REST keymanager API might have removed it
1317+
if key notin node.attachedValidators[].validators:
1318+
continue
1319+
1320+
let validator = node.attachedValidators[].validators[key]
1321+
13101322
if validator.index.isNone:
13111323
continue
13121324

@@ -1321,14 +1333,23 @@ proc registerValidators(node: BeaconNode, epoch: Epoch) {.async.} =
13211333
state.data.validators.item(validator.index.get).exit_epoch:
13221334
continue
13231335

1324-
let validatorRegistration =
1325-
await node.getValidatorRegistration(validator, epoch)
1326-
if validatorRegistration.isErr:
1327-
error "registerValidators: validatorRegistration failed",
1328-
validatorRegistration
1329-
continue
1336+
if validator.externalBuilderRegistration.isSome:
1337+
validatorRegistrations.add validator.externalBuilderRegistration.get
1338+
else:
1339+
let validatorRegistration =
1340+
await node.getValidatorRegistration(validator, epoch)
1341+
if validatorRegistration.isErr:
1342+
error "registerValidators: validatorRegistration failed",
1343+
validatorRegistration
1344+
continue
1345+
1346+
# Time passed during await; REST keymanager API might have removed it
1347+
if key notin node.attachedValidators[].validators:
1348+
continue
13301349

1331-
validatorRegistrations.add validatorRegistration.get
1350+
node.attachedValidators[].validators[key].externalBuilderRegistration =
1351+
Opt.some validatorRegistration.get
1352+
validatorRegistrations.add validatorRegistration.get
13321353

13331354
let registerValidatorResult =
13341355
awaitWithTimeout(node.payloadBuilderRestClient.registerValidator(validatorRegistrations),

beacon_chain/validators/validator_pool.nim

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,11 @@ type
5858

5959
# Cache the latest slot signature - the slot signature is used to determine
6060
# if the validator will be aggregating (in the near future)
61-
slotSignature*: Option[tuple[slot: Slot, signature: ValidatorSig]]
61+
slotSignature*: Opt[tuple[slot: Slot, signature: ValidatorSig]]
62+
63+
# For the external payload builder; each epoch, the external payload
64+
# builder should be informed of current validators
65+
externalBuilderRegistration*: Opt[SignedValidatorRegistrationV1]
6266

6367
startSlot*: Slot
6468

@@ -93,8 +97,10 @@ proc addLocalValidator*(pool: var ValidatorPool, item: KeystoreData,
9397
index: Opt[ValidatorIndex], slot: Slot) =
9498
doAssert item.kind == KeystoreKind.Local
9599
let pubkey = item.pubkey
96-
let v = AttachedValidator(kind: ValidatorKind.Local, pubkey: pubkey,
97-
index: index, data: item, startSlot: slot)
100+
let v = AttachedValidator(
101+
kind: ValidatorKind.Local, pubkey: pubkey, index: index, data: item,
102+
externalBuilderRegistration: Opt.none SignedValidatorRegistrationV1,
103+
startSlot: slot)
98104
pool.validators[pubkey] = v
99105
notice "Local validator attached", pubkey, validator = shortLog(v),
100106
start_slot = slot
@@ -109,9 +115,11 @@ proc addRemoteValidator*(pool: var ValidatorPool, item: KeystoreData,
109115
index: Opt[ValidatorIndex], slot: Slot) =
110116
doAssert item.kind == KeystoreKind.Remote
111117
let pubkey = item.pubkey
112-
let v = AttachedValidator(kind: ValidatorKind.Remote, pubkey: pubkey,
113-
index: index, data: item, clients: clients,
114-
startSlot: slot)
118+
let v = AttachedValidator(
119+
kind: ValidatorKind.Remote, pubkey: pubkey, index: index, data: item,
120+
clients: clients,
121+
externalBuilderRegistration: Opt.none SignedValidatorRegistrationV1,
122+
startSlot: slot)
115123
pool.validators[pubkey] = v
116124
notice "Remote validator attached", pubkey, validator = shortLog(v),
117125
remote_signer = $item.remotes,
@@ -403,7 +411,7 @@ proc getSlotSignature*(v: AttachedValidator, fork: Fork,
403411
if signature.isErr:
404412
return signature
405413

406-
v.slotSignature = some((slot, signature.get))
414+
v.slotSignature = Opt.some((slot, signature.get))
407415
return signature
408416

409417
# https://github.com/ethereum/builder-specs/blob/v0.2.0/specs/builder.md#signing

research/simutils.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ proc loadGenesis*(validators: Natural, validate: bool):
8787
quit 1
8888

8989
if forkyState.data.validators.len != validators:
90-
echo &"Supplied genesis file has {state.data.validators.len} validators, while {validators} where requested, running anyway"
90+
echo &"Supplied genesis file has {forkyState.data.validators.len} validators, while {validators} where requested, running anyway"
9191

9292
echo &"Loaded {genesisFn}..."
9393

research/state_sim.nim

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,11 @@ cli do(slots = SLOTS_PER_EPOCH * 5,
6363
write(stdout, ".")
6464

6565
if last:
66-
withState(state[]): writeJson("state.json", state.data)
66+
withState(state[]): writeJson("state.json", forkyState.data)
6767
else:
6868
withState(state[]):
69-
if state.data.slot mod json_interval.uint64 == 0:
70-
writeJson(jsonName(prefix, state.data.slot), state.data)
69+
if forkyState.data.slot mod json_interval.uint64 == 0:
70+
writeJson(jsonName(prefix, forkyState.data.slot), forkyState.data)
7171
write(stdout, ":")
7272
else:
7373
write(stdout, ".")
@@ -107,7 +107,7 @@ cli do(slots = SLOTS_PER_EPOCH * 5,
107107

108108
withState(state[]):
109109
let
110-
slot = state.data.slot
110+
slot = forkyState.data.slot
111111
epoch = slot.epoch
112112
committees_per_slot =
113113
get_committee_count_per_slot(state.data, epoch, cache)

0 commit comments

Comments
 (0)