Skip to content

Commit f579112

Browse files
etan-statuszah
authored andcommitted
widen allowed specs for validator client
The validator client was only able to connect to beacon nodes exposing the exact same set of spec constants that are locally known via their config/spec REST API. However, that set of spec constants is dynamic. As the validator client only requires a subset of relevant constants, this may lead to compatible specs being rejected. This patch widens the allowed specs by only verifying that the required set of constants are present in the spec response, ignoring any spec constants that are not locally known, and ignoring missing spec constants that are locally known but not included by the remote beacon node when not relevant for operation of the validator client.
1 parent 9b334c3 commit f579112

File tree

5 files changed

+49
-3
lines changed

5 files changed

+49
-3
lines changed

beacon_chain/spec/eth2_apis/eth2_rest_serialization.nim

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,12 @@ type
7171
GetBlockV2Response |
7272
GetStateV2Response
7373

74+
# These types may be extended with additional fields in the future.
75+
# Locally unknown fields are silently ignored when decoding them.
76+
ExtensibleDecodeTypes* =
77+
GetSpecResponse |
78+
GetSpecVCResponse
79+
7480
SszDecodeTypes* =
7581
GetPhase0StateSszResponse |
7682
GetAltairStateSszResponse |
@@ -957,10 +963,11 @@ proc encodeBytes*[T: EncodeArrays](value: T,
957963

958964
proc decodeBytes*[T: DecodeTypes](t: typedesc[T], value: openarray[byte],
959965
contentType: string): RestResult[T] =
966+
const isExtensibleType = t is ExtensibleDecodeTypes
960967
case contentType
961968
of "application/json":
962969
try:
963-
ok RestJson.decode(value, T)
970+
ok RestJson.decode(value, T, allowUnknownFields = isExtensibleType)
964971
except SerializationError as exc:
965972
err("Serialization error")
966973
else:

beacon_chain/spec/eth2_apis/rest_config_calls.nim

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,10 @@ proc getSpec*(): RestResponse[GetSpecResponse] {.
2020
rest, endpoint: "/eth/v1/config/spec", meth: MethodGet.}
2121
## https://ethereum.github.io/beacon-APIs/#/Config/getSpec
2222

23+
proc getSpecVC*(): RestResponse[GetSpecVCResponse] {.
24+
rest, endpoint: "/eth/v1/config/spec", meth: MethodGet.}
25+
## https://ethereum.github.io/beacon-APIs/#/Config/getSpec
26+
2327
proc getDepositContract*(): RestResponse[GetDepositContractResponse] {.
2428
rest, endpoint: "/eth/v1/config/deposit_contract", meth: MethodGet.}
2529
## https://ethereum.github.io/beacon-APIs/#/Config/getDepositContract

beacon_chain/spec/eth2_apis/rest_types.nim

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,39 @@ type
306306
DOMAIN_SYNC_COMMITTEE*: DomainType
307307
DOMAIN_SYNC_COMMITTEE_SELECTION_PROOF*: DomainType
308308

309+
# The `RestSpec` is a dynamic dictionary that includes version-specific spec
310+
# constants. New versions may introduce new constants, and remove old ones.
311+
# The Nimbus validator client fetches the remote spec to determine whether it
312+
# is connected to a compatible beacon node. For this purpose, it only needs to
313+
# verify a small set of relevant spec constants. To avoid rejecting a remote
314+
# spec that includes all of those relevant spec constants, but that does not
315+
# include all of the locally known spec constants, a separate type is defined
316+
# that includes just the spec constants relevant for the validator client.
317+
# Extra spec constants are silently ignored.
318+
RestSpecVC* = object
319+
# /!\ Keep in sync with `validator_client/api.nim` > `checkCompatible`.
320+
MAX_VALIDATORS_PER_COMMITTEE*: uint64
321+
SLOTS_PER_EPOCH*: uint64
322+
SECONDS_PER_SLOT*: uint64
323+
EPOCHS_PER_ETH1_VOTING_PERIOD*: uint64
324+
SLOTS_PER_HISTORICAL_ROOT*: uint64
325+
EPOCHS_PER_HISTORICAL_VECTOR*: uint64
326+
EPOCHS_PER_SLASHINGS_VECTOR*: uint64
327+
HISTORICAL_ROOTS_LIMIT*: uint64
328+
VALIDATOR_REGISTRY_LIMIT*: uint64
329+
MAX_PROPOSER_SLASHINGS*: uint64
330+
MAX_ATTESTER_SLASHINGS*: uint64
331+
MAX_ATTESTATIONS*: uint64
332+
MAX_DEPOSITS*: uint64
333+
MAX_VOLUNTARY_EXITS*: uint64
334+
DOMAIN_BEACON_PROPOSER*: DomainType
335+
DOMAIN_BEACON_ATTESTER*: DomainType
336+
DOMAIN_RANDAO*: DomainType
337+
DOMAIN_DEPOSIT*: DomainType
338+
DOMAIN_VOLUNTARY_EXIT*: DomainType
339+
DOMAIN_SELECTION_PROOF*: DomainType
340+
DOMAIN_AGGREGATE_AND_PROOF*: DomainType
341+
309342
RestDepositContract* = object
310343
chain_id*: string
311344
address*: string
@@ -371,6 +404,7 @@ type
371404
GetProposerDutiesResponse* = DataRootEnclosedObject[seq[RestProposerDuty]]
372405
GetSyncCommitteeDutiesResponse* = DataEnclosedObject[seq[RestSyncCommitteeDuty]]
373406
GetSpecResponse* = DataEnclosedObject[RestSpec]
407+
GetSpecVCResponse* = DataEnclosedObject[RestSpecVC]
374408
GetStateFinalityCheckpointsResponse* = DataEnclosedObject[RestBeaconStatesFinalityCheckpoints]
375409
GetStateForkResponse* = DataEnclosedObject[Fork]
376410
GetStateRootResponse* = DataEnclosedObject[Eth2Digest]

beacon_chain/validator_client/api.nim

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ proc checkCompatible*(vc: ValidatorClientRef,
1616
let info =
1717
try:
1818
debug "Requesting beacon node network configuration"
19-
let res = await node.client.getSpec()
19+
let res = await node.client.getSpecVC()
2020
res.data.data
2121
except CancelledError as exc:
2222
error "Configuration request was interrupted"
@@ -55,6 +55,7 @@ proc checkCompatible*(vc: ValidatorClientRef,
5555

5656
let genesisFlag = (genesis != vc.beaconGenesis)
5757
let configFlag =
58+
# /!\ Keep in sync with `spec/eth2_apis/rest_types.nim` > `RestSpecVC`.
5859
info.MAX_VALIDATORS_PER_COMMITTEE != MAX_VALIDATORS_PER_COMMITTEE or
5960
info.SLOTS_PER_EPOCH != SLOTS_PER_EPOCH or
6061
info.SECONDS_PER_SLOT != SECONDS_PER_SLOT or

beacon_chain/validator_client/common.nim

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ type
6969
BeaconNodeServer* = object
7070
client*: RestClientRef
7171
endpoint*: string
72-
config*: Option[RestSpec]
72+
config*: Option[RestSpecVC]
7373
ident*: Option[string]
7474
genesis*: Option[RestGenesis]
7575
syncInfo*: Option[RestSyncInfo]

0 commit comments

Comments
 (0)