Skip to content

Commit 6532dfb

Browse files
authored
VC: Fix validator registration cache issue. (#6907)
* Fix cache invalidation issue in VC. * Update copyright source. * Address review comments. * Update cache invalidation for gas limit calls. * Update copyright year.
1 parent 135febc commit 6532dfb

File tree

2 files changed

+54
-52
lines changed

2 files changed

+54
-52
lines changed

beacon_chain/validator_client/common.nim

Lines changed: 46 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# beacon_chain
2-
# Copyright (c) 2021-2024 Status Research & Development GmbH
2+
# Copyright (c) 2021-2025 Status Research & Development GmbH
33
# Licensed and distributed under either of
44
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
55
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@@ -236,7 +236,6 @@ type
236236
beaconGenesis*: RestGenesis
237237
proposerTasks*: Table[Slot, seq[ProposerTask]]
238238
dynamicFeeRecipientsStore*: ref DynamicFeeRecipientsStore
239-
validatorsRegCache*: Table[ValidatorPubKey, SignedValidatorRegistrationV1]
240239
blocksSeen*: Table[Slot, BlockDataItem]
241240
rootsSeen*: Table[Eth2Digest, Slot]
242241
processingDelay*: Opt[Duration]
@@ -1059,68 +1058,64 @@ proc isExpired(vc: ValidatorClientRef,
10591058
EPOCHS_BETWEEN_VALIDATOR_REGISTRATION
10601059

10611060
proc getValidatorRegistration(
1062-
vc: ValidatorClientRef,
1063-
validator: AttachedValidator,
1064-
timestamp: Time,
1065-
fork: Fork
1066-
): Result[PendingValidatorRegistration, RegistrationKind] =
1061+
vc: ValidatorClientRef,
1062+
validator: AttachedValidator,
1063+
timestamp: Time,
1064+
fork: Fork
1065+
): Result[PendingValidatorRegistration, RegistrationKind] =
10671066
if validator.index.isNone():
10681067
debug "Validator registration missing validator index",
10691068
validator = validatorLog(validator)
10701069
return err(RegistrationKind.MissingIndex)
10711070

10721071
let
1073-
cached = vc.validatorsRegCache.getOrDefault(validator.pubkey)
10741072
currentSlot =
10751073
block:
10761074
let res = vc.beaconClock.toSlot(timestamp)
10771075
if not(res.afterGenesis):
10781076
return err(RegistrationKind.IncorrectTime)
10791077
res.slot
10801078

1081-
if cached.isDefault() or vc.isExpired(cached, currentSlot):
1082-
if not cached.isDefault():
1083-
# Want to send it to relay, but not recompute perfectly fine cache
1084-
return ok(PendingValidatorRegistration(registration: cached, future: nil))
1079+
if validator.externalBuilderRegistration.isSome():
1080+
let cached = validator.externalBuilderRegistration.get()
1081+
return
1082+
if not(vc.isExpired(cached, currentSlot)):
1083+
err(RegistrationKind.Cached)
1084+
else:
1085+
ok(PendingValidatorRegistration(registration: cached, future: nil))
10851086

1086-
let
1087-
feeRecipient = vc.getFeeRecipient(validator, currentSlot.epoch())
1088-
gasLimit = vc.getGasLimit(validator)
1089-
var registration =
1090-
SignedValidatorRegistrationV1(
1091-
message: ValidatorRegistrationV1(
1092-
fee_recipient: ExecutionAddress(data: distinctBase(feeRecipient)),
1093-
gas_limit: gasLimit,
1094-
timestamp: uint64(timestamp.toUnix()),
1095-
pubkey: validator.pubkey
1096-
)
1087+
let
1088+
feeRecipient = vc.getFeeRecipient(validator, currentSlot.epoch())
1089+
gasLimit = vc.getGasLimit(validator)
1090+
1091+
var registration =
1092+
SignedValidatorRegistrationV1(
1093+
message: ValidatorRegistrationV1(
1094+
fee_recipient: ExecutionAddress(data: distinctBase(feeRecipient)),
1095+
gas_limit: gasLimit,
1096+
timestamp: uint64(timestamp.toUnix()),
1097+
pubkey: validator.pubkey
10971098
)
1098-
1099-
let sigfut = validator.getBuilderSignature(fork, registration.message)
1100-
if sigfut.finished():
1101-
# This is short-path if we able to create signature locally.
1102-
if not(sigfut.completed()):
1103-
let exc = sigfut.error()
1104-
debug "Got unexpected exception while signing validator registration",
1105-
validator = validatorLog(validator), error = exc.name,
1106-
reason = exc.msg
1107-
return err(RegistrationKind.ErrorSignature)
1108-
let sigres = sigfut.value()
1109-
if sigres.isErr():
1110-
debug "Failed to get signature for validator registration",
1111-
validator = validatorLog(validator), reason = sigres.error()
1112-
return err(RegistrationKind.NoSignature)
1113-
registration.signature = sigres.get()
1114-
# Updating cache table with new signed registration data
1115-
vc.validatorsRegCache[registration.message.pubkey] = registration
1116-
ok(PendingValidatorRegistration(registration: registration, future: nil))
1117-
else:
1118-
# Remote signature service involved, cache will be updated later.
1119-
ok(PendingValidatorRegistration(registration: registration,
1120-
future: sigfut))
1099+
)
1100+
1101+
let sigfut = validator.getBuilderSignature(fork, registration.message)
1102+
if sigfut.finished():
1103+
# This is short-path if we able to create signature locally.
1104+
if not(sigfut.completed()):
1105+
let exc = sigfut.error()
1106+
debug "Got unexpected exception while signing validator registration",
1107+
validator = validatorLog(validator), error = exc.name,
1108+
reason = exc.msg
1109+
return err(RegistrationKind.ErrorSignature)
1110+
1111+
registration.signature = sigfut.value().valueOr:
1112+
debug "Failed to get signature for validator registration",
1113+
validator = validatorLog(validator), reason = error
1114+
return err(RegistrationKind.NoSignature)
1115+
1116+
ok(PendingValidatorRegistration(registration: registration, future: nil))
11211117
else:
1122-
# Returning cached result.
1123-
err(RegistrationKind.Cached)
1118+
ok(PendingValidatorRegistration(registration: registration, future: sigfut))
11241119

11251120
proc prepareRegistrationList*(
11261121
vc: ValidatorClientRef,
@@ -1131,6 +1126,7 @@ proc prepareRegistrationList*(
11311126

11321127
var
11331128
messages: seq[SignedValidatorRegistrationV1]
1129+
validators: seq[AttachedValidator]
11341130
futures: seq[Future[SignatureResult]]
11351131
registrations: seq[SignedValidatorRegistrationV1]
11361132
total = vc.attachedValidators[].count()
@@ -1151,6 +1147,7 @@ proc prepareRegistrationList*(
11511147
registrations.add(preg.registration)
11521148
else:
11531149
messages.add(preg.registration)
1150+
validators.add(validator)
11541151
futures.add(preg.future)
11551152
else:
11561153
case res.error()
@@ -1174,8 +1171,7 @@ proc prepareRegistrationList*(
11741171
var reg = messages[index]
11751172
reg.signature = sres.get()
11761173
registrations.add(reg)
1177-
# Updating cache table
1178-
vc.validatorsRegCache[reg.message.pubkey] = reg
1174+
validators[index].externalBuilderRegistration = Opt.some(reg)
11791175
inc(succeed)
11801176
else:
11811177
inc(bad)

beacon_chain/validators/keystore_management.nim

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# beacon_chain
2-
# Copyright (c) 2018-2024 Status Research & Development GmbH
2+
# Copyright (c) 2018-2025 Status Research & Development GmbH
33
# Licensed and distributed under either of
44
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
55
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
@@ -1491,6 +1491,7 @@ proc removeGasLimitFile*(host: KeymanagerHost,
14911491
if fileExists(path):
14921492
io2.removeFile(path).isOkOr:
14931493
return err($uint(error) & " " & ioErrorMsg(error))
1494+
host.validatorPool[].invalidateValidatorRegistration(pubkey)
14941495
ok()
14951496
14961497
proc removeGraffitiFile*(host: KeymanagerHost,
@@ -1525,9 +1526,14 @@ proc setGasLimit*(host: KeymanagerHost,
15251526
? secureCreatePath(validatorKeystoreDir).mapErr(proc(e: auto): string =
15261527
"Could not create wallet directory [" & validatorKeystoreDir & "]: " & $e)
15271528

1528-
io2.writeFile(validatorKeystoreDir / GasLimitFilename, $gasLimit)
1529+
let res = io2.writeFile(validatorKeystoreDir / GasLimitFilename, $gasLimit)
15291530
.mapErr(proc(e: auto): string = "Failed to write gas limit file: " & $e)
15301531

1532+
if res.isOk:
1533+
host.validatorPool[].invalidateValidatorRegistration(pubkey)
1534+
1535+
res
1536+
15311537
proc setGraffiti*(host: KeymanagerHost,
15321538
pubkey: ValidatorPubKey,
15331539
graffiti: GraffitiBytes): Result[void, string] =

0 commit comments

Comments
 (0)