From 38827d776c7bee9fb2ec886f7b8befe758e783b7 Mon Sep 17 00:00:00 2001 From: tersec Date: Sun, 4 Dec 2022 07:42:03 +0000 Subject: [PATCH] capella gossip support (#4386) --- beacon_chain/light_client.nim | 9 +- beacon_chain/networking/eth2_network.nim | 7 +- beacon_chain/nimbus_beacon_node.nim | 22 ++- beacon_chain/nimbus_light_client.nim | 3 +- beacon_chain/spec/datatypes/base.nim | 2 +- beacon_chain/spec/network.nim | 73 +++++---- beacon_chain/validators/validator_duties.nim | 42 +++-- tests/test_gossip_transition.nim | 162 +++++++++++++------ tests/test_gossip_validation.nim | 3 +- tests/test_light_client.nim | 3 +- tests/test_light_client_processor.nim | 3 +- 11 files changed, 209 insertions(+), 120 deletions(-) diff --git a/beacon_chain/light_client.nim b/beacon_chain/light_client.nim index 65c348fe2..2ca6da4a6 100644 --- a/beacon_chain/light_client.nim +++ b/beacon_chain/light_client.nim @@ -291,7 +291,8 @@ proc installMessageValidators*( ValidationResult.Ignore let forkDigests = lightClient.forkDigests - for digest in [forkDigests.altair, forkDigests.bellatrix]: + for digest in [ + forkDigests.altair, forkDigests.bellatrix, forkDigests.capella]: lightClient.network.addValidator( getLightClientFinalityUpdateTopic(digest), proc(msg: altair.LightClientFinalityUpdate): ValidationResult = @@ -321,7 +322,8 @@ proc updateGossipStatus*( isBehind = lcBehind and dagBehind currentEpochTargetGossipState = getTargetGossipState( - epoch, cfg.ALTAIR_FORK_EPOCH, cfg.BELLATRIX_FORK_EPOCH, isBehind) + epoch, cfg.ALTAIR_FORK_EPOCH, cfg.BELLATRIX_FORK_EPOCH, + cfg.CAPELLA_FORK_EPOCH, isBehind) targetGossipState = if lcBehind or epoch < 1: currentEpochTargetGossipState @@ -330,7 +332,8 @@ proc updateGossipStatus*( # which is in the past relative to the signature slot (current slot). # Therefore, LC topic subscriptions are kept for 1 extra epoch. let previousEpochTargetGossipState = getTargetGossipState( - epoch - 1, cfg.ALTAIR_FORK_EPOCH, cfg.BELLATRIX_FORK_EPOCH, isBehind) + epoch - 1, cfg.ALTAIR_FORK_EPOCH, cfg.BELLATRIX_FORK_EPOCH, + cfg.CAPELLA_FORK_EPOCH, isBehind) currentEpochTargetGossipState + previousEpochTargetGossipState template currentGossipState(): auto = lightClient.gossipState diff --git a/beacon_chain/networking/eth2_network.nim b/beacon_chain/networking/eth2_network.nim index e67c6fcf1..7be298115 100644 --- a/beacon_chain/networking/eth2_network.nim +++ b/beacon_chain/networking/eth2_network.nim @@ -816,11 +816,13 @@ func chunkMaxSize[T](): uint32 = func maxGossipMaxSize(): auto {.compileTime.} = max(GOSSIP_MAX_SIZE, GOSSIP_MAX_SIZE_BELLATRIX) +from ../spec/datatypes/capella import SignedBeaconBlock + template gossipMaxSize(T: untyped): uint32 = const maxSize = static: when isFixedSize(T): fixedPortionSize(T) - elif T is bellatrix.SignedBeaconBlock: + elif T is bellatrix.SignedBeaconBlock or T is capella.SignedBeaconBlock: GOSSIP_MAX_SIZE_BELLATRIX # TODO https://github.com/status-im/nim-ssz-serialization/issues/20 for # Attestation, AttesterSlashing, and SignedAggregateAndProof, which all @@ -2625,9 +2627,6 @@ proc broadcastBeaconBlock*( let topic = getBeaconBlocksTopic(node.forkDigests.bellatrix) node.broadcast(topic, blck) -# TODO when forks re-exports this, use that instead and rm this -from ../spec/datatypes/capella import SignedBeaconBlock - proc broadcastBeaconBlock*( node: Eth2Node, blck: capella.SignedBeaconBlock): Future[SendResult] = let topic = getBeaconBlocksTopic(node.forkDigests.capella) diff --git a/beacon_chain/nimbus_beacon_node.nim b/beacon_chain/nimbus_beacon_node.nim index fcf3e6ab1..3025b83f9 100644 --- a/beacon_chain/nimbus_beacon_node.nim +++ b/beacon_chain/nimbus_beacon_node.nim @@ -813,7 +813,8 @@ proc updateBlocksGossipStatus*( dagIsBehind targetGossipState = getTargetGossipState( - slot.epoch, cfg.ALTAIR_FORK_EPOCH, cfg.BELLATRIX_FORK_EPOCH, isBehind) + slot.epoch, cfg.ALTAIR_FORK_EPOCH, cfg.BELLATRIX_FORK_EPOCH, + cfg.CAPELLA_FORK_EPOCH, isBehind) template currentGossipState(): auto = node.blocksGossipState if currentGossipState == targetGossipState: @@ -1024,6 +1025,7 @@ proc updateGossipStatus(node: BeaconNode, slot: Slot) {.async.} = slot.epoch, node.dag.cfg.ALTAIR_FORK_EPOCH, node.dag.cfg.BELLATRIX_FORK_EPOCH, + node.dag.cfg.CAPELLA_FORK_EPOCH, isBehind) doAssert targetGossipState.card <= 2 @@ -1374,6 +1376,8 @@ proc installRestHandlers(restServer: RestServerRef, node: BeaconNode) = if node.dag.lcDataStore.serve: restServer.router.installLightClientApiHandlers(node) +from ./spec/datatypes/capella import SignedBeaconBlock + proc installMessageValidators(node: BeaconNode) = # https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.1/specs/phase0/p2p-interface.md#attestations-and-aggregation # These validators stay around the whole time, regardless of which specific @@ -1433,10 +1437,11 @@ proc installMessageValidators(node: BeaconNode) = installPhase0Validators(forkDigests.phase0) - # Validators introduced in phase0 are also used in altair and merge, but with - # different fork digest + # Validators introduced in phase0 are also used in Altair and Bellatrix, but + # with different fork digests installPhase0Validators(forkDigests.altair) installPhase0Validators(forkDigests.bellatrix) + installPhase0Validators(forkDigests.capella) node.network.addValidator( getBeaconBlocksTopic(forkDigests.altair), @@ -1458,6 +1463,16 @@ proc installMessageValidators(node: BeaconNode) = toValidationResult(node.processor[].processSignedBeaconBlock( MsgSource.gossip, signedBlock))) + node.network.addValidator( + getBeaconBlocksTopic(forkDigests.capella), + proc (signedBlock: capella.SignedBeaconBlock): ValidationResult = + if node.shouldSyncOptimistically(node.currentSlot): + toValidationResult( + node.optimisticProcessor.processSignedBeaconBlock(signedBlock)) + else: + toValidationResult(node.processor[].processSignedBeaconBlock( + MsgSource.gossip, signedBlock))) + template installSyncCommitteeeValidators(digest: auto) = for subcommitteeIdx in SyncSubcommitteeIndex: closureScope: @@ -1479,6 +1494,7 @@ proc installMessageValidators(node: BeaconNode) = installSyncCommitteeeValidators(forkDigests.altair) installSyncCommitteeeValidators(forkDigests.bellatrix) + installSyncCommitteeeValidators(forkDigests.capella) node.installLightClientMessageValidators() diff --git a/beacon_chain/nimbus_light_client.nim b/beacon_chain/nimbus_light_client.nim index af5564ceb..66b8ad972 100644 --- a/beacon_chain/nimbus_light_client.nim +++ b/beacon_chain/nimbus_light_client.nim @@ -219,7 +219,8 @@ programMain: isBehind = not shouldSyncOptimistically(slot) targetGossipState = getTargetGossipState( - slot.epoch, cfg.ALTAIR_FORK_EPOCH, cfg.BELLATRIX_FORK_EPOCH, isBehind) + slot.epoch, cfg.ALTAIR_FORK_EPOCH, cfg.BELLATRIX_FORK_EPOCH, + cfg.CAPELLA_FORK_EPOCH, isBehind) template currentGossipState(): auto = blocksGossipState if currentGossipState == targetGossipState: diff --git a/beacon_chain/spec/datatypes/base.nim b/beacon_chain/spec/datatypes/base.nim index 3b3cf8429..f08375f5e 100644 --- a/beacon_chain/spec/datatypes/base.nim +++ b/beacon_chain/spec/datatypes/base.nim @@ -966,7 +966,7 @@ func checkForkConsistency*(cfg: RuntimeConfig) = firstForkEpoch: Epoch, secondForkEpoch: Epoch) = doAssert distinctBase(firstForkEpoch) <= distinctBase(secondForkEpoch) - # TODO https://github.com/ethereum/consensus-specs/issues/2902 multiple + # https://github.com/ethereum/consensus-specs/issues/2902 multiple # fork transitions per epoch don't work in a well-defined way. doAssert distinctBase(firstForkEpoch) < distinctBase(secondForkEpoch) or firstForkEpoch in [GENESIS_EPOCH, FAR_FUTURE_EPOCH] diff --git a/beacon_chain/spec/network.nim b/beacon_chain/spec/network.nim index 220544eb8..7541e155c 100644 --- a/beacon_chain/spec/network.nim +++ b/beacon_chain/spec/network.nim @@ -26,20 +26,20 @@ const topicAggregateAndProofsSuffix* = "beacon_aggregate_and_proof/ssz_snappy" topicBlsToExecutionChangeSuffix* = "bls_to_execution_change/ssz_snappy" - # https://github.com/ethereum/consensus-specs/blob/v1.2.0-rc.2/specs/phase0/p2p-interface.md#configuration + # https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.1/specs/phase0/p2p-interface.md#configuration MAX_CHUNK_SIZE* = 1 * 1024 * 1024 # bytes GOSSIP_MAX_SIZE* = 1 * 1024 * 1024 # bytes TTFB_TIMEOUT* = 5.seconds RESP_TIMEOUT* = 10.seconds - # https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.0/specs/bellatrix/p2p-interface.md#configuration + # https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.1/specs/bellatrix/p2p-interface.md#configuration GOSSIP_MAX_SIZE_BELLATRIX* = 10 * 1024 * 1024 # bytes MAX_CHUNK_SIZE_BELLATRIX* = 10 * 1024 * 1024 # bytes defaultEth2TcpPort* = 9000 defaultEth2TcpPortDesc* = $defaultEth2TcpPort - # This is not part of the spec! But its port which uses Lighthouse + # This is not part of the spec! But it's port which Lighthouse uses defaultEth2RestPort* = 5052 defaultEth2RestPortDesc* = $defaultEth2RestPort @@ -147,44 +147,43 @@ func getDiscoveryForkID*(cfg: RuntimeConfig, # https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.1/specs/altair/p2p-interface.md#transitioning-the-gossip type GossipState* = set[BeaconStateFork] func getTargetGossipState*( - epoch, ALTAIR_FORK_EPOCH, BELLATRIX_FORK_EPOCH: Epoch, isBehind: bool): - GossipState = + epoch, ALTAIR_FORK_EPOCH, BELLATRIX_FORK_EPOCH, CAPELLA_FORK_EPOCH: Epoch, + isBehind: bool): GossipState = if isBehind: - {} + return {} - # The order of these checks doesn't matter. - elif epoch >= BELLATRIX_FORK_EPOCH: - {BeaconStateFork.Bellatrix} - elif epoch + 1 < ALTAIR_FORK_EPOCH: - {BeaconStateFork.Phase0} + # When EIP4844 comes in, can be transformed to discard of that symbol + static: doAssert high(BeaconStateFork) == BeaconStateFork.Capella - # Order remaining checks so ALTAIR_FORK_EPOCH == BELLATRIX_FORK_EPOCH works - # and when the transition zones align contiguously, or are separated by - # intermediate pure-Altair epochs. - # - # In the first case, should never enable Altair, and there's also never - # a Phase -> Altair, or Altair -> Bellatrix gossip transition epoch. In - # contiguous Phase0 -> Altair and Altair -> Bellatrix transitions, that - # pure Altair state gossip state never occurs, but it works without any - # special cases so long as one checks for transition-to-fork+1 before a - # pure fork gossip state. - # - # Therefore, check for transition-to-merge before pure-Altair. - elif epoch + 1 >= BELLATRIX_FORK_EPOCH: - # As there are only two fork epochs and there's no transition to phase0 - {if ALTAIR_FORK_EPOCH == BELLATRIX_FORK_EPOCH: - BeaconStateFork.Phase0 - else: - BeaconStateFork.Altair, - BeaconStateFork.Bellatrix} - elif epoch >= ALTAIR_FORK_EPOCH: - {BeaconStateFork.Altair} + doAssert BELLATRIX_FORK_EPOCH >= ALTAIR_FORK_EPOCH + doAssert CAPELLA_FORK_EPOCH >= BELLATRIX_FORK_EPOCH - # Must be after the case which catches phase0 => merge - elif epoch + 1 >= ALTAIR_FORK_EPOCH: - {BeaconStateFork.Phase0, BeaconStateFork.Altair} - else: - raiseAssert "Unknown target gossip state" + # https://github.com/ethereum/consensus-specs/issues/2902 + # Don't care whether ALTAIR_FORK_EPOCH == BELLATRIX_FORK_EPOCH or + # BELLATRIX_FORK_EPOCH == CAPELLA_FORK_EPOCH works, because those + # theoretically possible networks are ill-defined regardless, and + # consequently prohibited by checkForkConsistency(). Therefore, a + # transitional epoch always exists, for every fork. + var targetForks: GossipState + + template maybeIncludeFork( + targetFork: BeaconStateFork, targetForkEpoch: Epoch, + successiveForkEpoch: Epoch) = + # Subscribe one epoch ahead + if epoch + 1 >= targetForkEpoch and epoch < successiveForkEpoch: + targetForks.incl targetFork + + maybeIncludeFork( + BeaconStateFork.Phase0, GENESIS_EPOCH, ALTAIR_FORK_EPOCH) + maybeIncludeFork( + BeaconStateFork.Altair, ALTAIR_FORK_EPOCH, BELLATRIX_FORK_EPOCH) + maybeIncludeFork( + BeaconStateFork.Bellatrix, BELLATRIX_FORK_EPOCH, CAPELLA_FORK_EPOCH) + maybeIncludeFork( + BeaconStateFork.Capella, CAPELLA_FORK_EPOCH, FAR_FUTURE_EPOCH) + + doAssert len(targetForks) <= 2 + targetForks func nearSyncCommitteePeriod*(epoch: Epoch): Option[uint64] = # https://github.com/ethereum/consensus-specs/blob/v1.3.0-alpha.1/specs/altair/validator.md#sync-committee-subnet-stability diff --git a/beacon_chain/validators/validator_duties.nim b/beacon_chain/validators/validator_duties.nim index ae4985931..a9f26f3bd 100644 --- a/beacon_chain/validators/validator_duties.nim +++ b/beacon_chain/validators/validator_duties.nim @@ -334,6 +334,7 @@ proc forkchoice_updated( head_block_hash finalized_block_hash + discard $capellaImplementationMissing & ": ensure fcU usage updated for capella" let forkchoiceResponse = try: @@ -355,15 +356,18 @@ proc forkchoice_updated( else: none(bellatrix.PayloadID) -proc get_execution_payload( +proc get_execution_payload[EP]( payload_id: Option[bellatrix.PayloadID], execution_engine: Eth1Monitor): - Future[bellatrix.ExecutionPayload] {.async.} = + Future[EP] {.async.} = return if payload_id.isNone(): # Pre-merge, empty payload - default(bellatrix.ExecutionPayload) + default(EP) else: - asConsensusExecutionPayload( - await execution_engine.getPayload(payload_id.get)) + when EP is bellatrix.ExecutionPayload: + asConsensusExecutionPayload( + await execution_engine.getPayload(payload_id.get)) + else: + raiseAssert $capellaImplementationMissing & ": implement getPayload V2" proc getFeeRecipient(node: BeaconNode, pubkey: ValidatorPubKey, @@ -372,6 +376,7 @@ proc getFeeRecipient(node: BeaconNode, node.consensusManager[].getFeeRecipient(pubkey, Opt.some(validatorIdx), epoch) from web3/engine_api_types import PayloadExecutionStatus +from ../spec/datatypes/capella import BeaconBlock, ExecutionPayload proc getExecutionPayload[T]( node: BeaconNode, proposalState: ref ForkedHashedBeaconState, @@ -387,11 +392,17 @@ proc getExecutionPayload[T]( node.getFeeRecipient(pubkey.get().toPubKey(), validator_index, epoch) template empty_execution_payload(): auto = + # Callers should already ensure these match, but type system doesn't + # transmit this information through the Forked types, so this has to + # be re-proven here. withState(proposalState[]): - when stateFork >= BeaconStateFork.Capella: - raiseAssert $capellaImplementationMissing - elif stateFork >= BeaconStateFork.Bellatrix: + when (stateFork == BeaconStateFork.Capella and + T is capella.ExecutionPayload) or + (stateFork == BeaconStateFork.Bellatrix and + T is bellatrix.ExecutionPayload): build_empty_execution_payload(forkyState.data, feeRecipient) + elif stateFork >= BeaconStateFork.Bellatrix: + raiseAssert "getExecutionPayload: mismatched proposalState and ExecutionPayload fork" else: default(T) @@ -444,7 +455,7 @@ proc getExecutionPayload[T]( feeRecipient, node.consensusManager.eth1Monitor)) payload = try: awaitWithTimeout( - get_execution_payload(payload_id, node.consensusManager.eth1Monitor), + get_execution_payload[T](payload_id, node.consensusManager.eth1Monitor), GETPAYLOAD_TIMEOUT): beacon_block_payload_errors.inc() warn "Getting execution payload from Engine API timed out", payload_id @@ -828,9 +839,6 @@ proc makeBlindedBeaconBlockForHeadAndSlot*( return ok constructPlainBlindedBlock[BlindedBeaconBlock]( forkedBlck, executionPayloadHeader) -# TODO once forks re-exports these, use that instead -from ../spec/datatypes/capella import BeaconBlock - proc proposeBlock(node: BeaconNode, validator: AttachedValidator, validator_index: ValidatorIndex, @@ -876,9 +884,13 @@ proc proposeBlock(node: BeaconNode, beacon_block_builder_missed_without_fallback.inc() return newBlockMEV.get - discard $capellaImplementationMissing & ": use capella.ExecutionPayload here as appropriate" - let newBlock = await makeBeaconBlockForHeadAndSlot[bellatrix.ExecutionPayload]( - node, randao, validator_index, node.graffitiBytes, head, slot) + let newBlock = + if slot.epoch >= node.dag.cfg.CAPELLA_FORK_EPOCH: + await makeBeaconBlockForHeadAndSlot[capella.ExecutionPayload]( + node, randao, validator_index, node.graffitiBytes, head, slot) + else: + await makeBeaconBlockForHeadAndSlot[bellatrix.ExecutionPayload]( + node, randao, validator_index, node.graffitiBytes, head, slot) if newBlock.isErr(): return head # already logged elsewhere! diff --git a/tests/test_gossip_transition.nim b/tests/test_gossip_transition.nim index 6c4f10cba..45e70da93 100644 --- a/tests/test_gossip_transition.nim +++ b/tests/test_gossip_transition.nim @@ -1,3 +1,10 @@ +# beacon_chain +# Copyright (c) 2021-2022 Status Research & Development GmbH +# Licensed and distributed under either of +# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT). +# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0). +# at your option. This file may not be copied, modified, or distributed except according to those terms. + {.used.} import @@ -5,60 +12,109 @@ import ./testutil, ../beacon_chain/spec/[forks, network] -template getTargetGossipState(a, b, c: int, isBehind: bool): auto = - getTargetGossipState(a.Epoch, b.Epoch, c.Epoch, isBehind) +template getTargetGossipState(a, b, c, d: int, isBehind: bool): auto = + getTargetGossipState(a.Epoch, b.Epoch, c.Epoch, d.Epoch, isBehind) suite "Gossip fork transition": test "Gossip fork transition": check: - getTargetGossipState(0, 0, 0, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(0, 0, 2, false) == {BeaconStateFork.Altair} - getTargetGossipState(0, 1, 2, false) == {BeaconStateFork.Phase0, BeaconStateFork.Altair} - getTargetGossipState(0, 2, 3, false) == {BeaconStateFork.Phase0} - getTargetGossipState(0, 2, 5, false) == {BeaconStateFork.Phase0} - getTargetGossipState(0, 3, 4, false) == {BeaconStateFork.Phase0} - getTargetGossipState(0, 3, 5, false) == {BeaconStateFork.Phase0} - getTargetGossipState(0, 4, 4, false) == {BeaconStateFork.Phase0} - getTargetGossipState(0, 4, 5, false) == {BeaconStateFork.Phase0} - getTargetGossipState(1, 0, 1, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(1, 0, 5, false) == {BeaconStateFork.Altair} - getTargetGossipState(1, 1, 4, false) == {BeaconStateFork.Altair} - getTargetGossipState(2, 0, 2, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(2, 2, 3, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} - getTargetGossipState(2, 2, 4, false) == {BeaconStateFork.Altair} - getTargetGossipState(2, 3, 4, false) == {BeaconStateFork.Phase0, BeaconStateFork.Altair} - getTargetGossipState(2, 3, 5, true) == {} - getTargetGossipState(2, 5, 5, false) == {BeaconStateFork.Phase0} - getTargetGossipState(3, 0, 2, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(3, 0, 3, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(3, 0, 5, false) == {BeaconStateFork.Altair} - getTargetGossipState(3, 1, 2, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(3, 1, 1, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(3, 1, 3, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(3, 1, 5, true) == {} - getTargetGossipState(3, 1, 4, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} - getTargetGossipState(3, 2, 3, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(3, 3, 4, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} - getTargetGossipState(3, 3, 4, true) == {} - getTargetGossipState(3, 4, 4, false) == {BeaconStateFork.Phase0, BeaconStateFork.Bellatrix} - getTargetGossipState(4, 0, 0, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(4, 0, 1, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(4, 1, 1, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(4, 1, 3, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(4, 2, 4, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(4, 3, 4, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(4, 4, 4, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(4, 5, 5, false) == {BeaconStateFork.Phase0, BeaconStateFork.Bellatrix} - getTargetGossipState(5, 0, 0, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(5, 0, 2, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(5, 0, 4, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(5, 0, 5, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(5, 0, 5, true) == {} - getTargetGossipState(5, 1, 5, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(5, 2, 2, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(5, 2, 4, true) == {} - getTargetGossipState(5, 3, 4, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(5, 3, 5, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(5, 5, 5, false) == {BeaconStateFork.Bellatrix} - getTargetGossipState(2, 0, 3, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} - getTargetGossipState(4, 1, 2, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(0, 1, 6, 7, false) == {BeaconStateFork.Phase0, BeaconStateFork.Altair} + getTargetGossipState(7, 2, 5, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(5, 0, 2, 5, false) == {BeaconStateFork.Capella} + getTargetGossipState(4, 2, 4, 5, false) == {BeaconStateFork.Bellatrix, BeaconStateFork.Capella} + getTargetGossipState(1, 2, 3, 7, false) == {BeaconStateFork.Phase0, BeaconStateFork.Altair} + getTargetGossipState(9, 2, 4, 5, false) == {BeaconStateFork.Capella} + getTargetGossipState(5, 2, 3, 7, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(5, 0, 1, 7, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(7, 2, 6, 7, false) == {BeaconStateFork.Capella} + getTargetGossipState(5, 0, 5, 7, true) == {} + getTargetGossipState(8, 1, 5, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(8, 3, 4, 7, false) == {BeaconStateFork.Capella} + getTargetGossipState(4, 1, 2, 7, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(0, 1, 4, 7, false) == {BeaconStateFork.Phase0, BeaconStateFork.Altair} + getTargetGossipState(9, 1, 4, 7, true) == {} + getTargetGossipState(9, 2, 4, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(4, 0, 1, 5, true) == {} + getTargetGossipState(1, 1, 5, 6, true) == {} + getTargetGossipState(2, 0, 0, 7, true) == {} + getTargetGossipState(7, 1, 5, 7, false) == {BeaconStateFork.Capella} + getTargetGossipState(5, 1, 3, 6, true) == {} + getTargetGossipState(8, 4, 5, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(3, 0, 4, 6, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} + getTargetGossipState(1, 2, 6, 7, false) == {BeaconStateFork.Phase0, BeaconStateFork.Altair} + getTargetGossipState(1, 0, 1, 6, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(6, 0, 3, 5, false) == {BeaconStateFork.Capella} + getTargetGossipState(0, 4, 5, 6, true) == {} + getTargetGossipState(3, 0, 3, 5, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(5, 1, 3, 5, true) == {} + getTargetGossipState(4, 3, 4, 5, false) == {BeaconStateFork.Bellatrix, BeaconStateFork.Capella} + getTargetGossipState(6, 1, 2, 5, true) == {} + getTargetGossipState(8, 3, 5, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(1, 4, 6, 7, false) == {BeaconStateFork.Phase0} + getTargetGossipState(2, 5, 6, 7, false) == {BeaconStateFork.Phase0} + getTargetGossipState(5, 3, 4, 5, false) == {BeaconStateFork.Capella} + getTargetGossipState(5, 1, 4, 5, false) == {BeaconStateFork.Capella} + getTargetGossipState(6, 2, 4, 7, true) == {} + getTargetGossipState(7, 3, 5, 7, false) == {BeaconStateFork.Capella} + getTargetGossipState(6, 0, 1, 7, false) == {BeaconStateFork.Bellatrix, BeaconStateFork.Capella} + getTargetGossipState(0, 1, 4, 5, false) == {BeaconStateFork.Phase0, BeaconStateFork.Altair} + getTargetGossipState(7, 0, 1, 4, true) == {} + getTargetGossipState(6, 0, 4, 5, true) == {} + getTargetGossipState(3, 0, 0, 1, true) == {} + getTargetGossipState(2, 1, 3, 5, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} + getTargetGossipState(8, 0, 2, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(7, 0, 1, 4, false) == {BeaconStateFork.Capella} + getTargetGossipState(8, 1, 2, 7, true) == {} + getTargetGossipState(3, 0, 2, 7, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(9, 1, 2, 5, false) == {BeaconStateFork.Capella} + getTargetGossipState(6, 1, 4, 5, false) == {BeaconStateFork.Capella} + getTargetGossipState(0, 3, 4, 5, true) == {} + getTargetGossipState(9, 1, 3, 4, false) == {BeaconStateFork.Capella} + getTargetGossipState(1, 1, 4, 7, false) == {BeaconStateFork.Altair} + getTargetGossipState(5, 1, 4, 6, false) == {BeaconStateFork.Bellatrix, BeaconStateFork.Capella} + getTargetGossipState(7, 0, 5, 7, false) == {BeaconStateFork.Capella} + getTargetGossipState(9, 0, 0, 5, false) == {BeaconStateFork.Capella} + getTargetGossipState(5, 0, 0, 0, false) == {BeaconStateFork.Capella} + getTargetGossipState(9, 2, 3, 4, false) == {BeaconStateFork.Capella} + getTargetGossipState(3, 0, 0, 5, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(0, 0, 1, 6, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} + getTargetGossipState(4, 1, 4, 6, true) == {} + getTargetGossipState(4, 1, 2, 3, false) == {BeaconStateFork.Capella} + getTargetGossipState(6, 1, 3, 4, false) == {BeaconStateFork.Capella} + getTargetGossipState(4, 0, 0, 5, false) == {BeaconStateFork.Bellatrix, BeaconStateFork.Capella} + getTargetGossipState(8, 0, 3, 7, false) == {BeaconStateFork.Capella} + getTargetGossipState(2, 2, 3, 4, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} + getTargetGossipState(6, 2, 5, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(3, 0, 6, 7, true) == {} + getTargetGossipState(1, 1, 2, 6, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} + getTargetGossipState(2, 2, 4, 5, true) == {} + getTargetGossipState(9, 0, 3, 7, true) == {} + getTargetGossipState(4, 1, 3, 7, true) == {} + getTargetGossipState(7, 0, 0, 3, false) == {BeaconStateFork.Capella} + getTargetGossipState(0, 2, 5, 6, false) == {BeaconStateFork.Phase0} + getTargetGossipState(2, 0, 1, 7, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(9, 1, 6, 7, false) == {BeaconStateFork.Capella} + getTargetGossipState(6, 3, 5, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(2, 0, 0, 3, false) == {BeaconStateFork.Bellatrix, BeaconStateFork.Capella} + getTargetGossipState(3, 1, 3, 4, true) == {} + getTargetGossipState(7, 0, 1, 5, false) == {BeaconStateFork.Capella} + getTargetGossipState(2, 0, 3, 6, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} + getTargetGossipState(2, 0, 2, 5, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(1, 2, 4, 5, false) == {BeaconStateFork.Phase0, BeaconStateFork.Altair} + getTargetGossipState(8, 0, 2, 5, false) == {BeaconStateFork.Capella} + getTargetGossipState(6, 1, 5, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(6, 4, 5, 7, false) == {BeaconStateFork.Bellatrix, BeaconStateFork.Capella} + getTargetGossipState(3, 0, 5, 6, true) == {} + getTargetGossipState(4, 0, 2, 7, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(4, 4, 5, 6, true) == {} + getTargetGossipState(3, 0, 4, 5, true) == {} + getTargetGossipState(6, 0, 2, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(2, 1, 2, 3, false) == {BeaconStateFork.Bellatrix, BeaconStateFork.Capella} + getTargetGossipState(1, 0, 5, 6, true) == {} + getTargetGossipState(5, 2, 5, 6, false) == {BeaconStateFork.Bellatrix, BeaconStateFork.Capella} + getTargetGossipState(8, 0, 1, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(4, 2, 5, 6, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} + getTargetGossipState(1, 1, 2, 5, false) == {BeaconStateFork.Altair, BeaconStateFork.Bellatrix} + getTargetGossipState(9, 1, 4, 6, false) == {BeaconStateFork.Capella} + getTargetGossipState(1, 0, 0, 5, false) == {BeaconStateFork.Bellatrix} + getTargetGossipState(0, 0, 5, 7, false) == {BeaconStateFork.Altair} diff --git a/tests/test_gossip_validation.nim b/tests/test_gossip_validation.nim index 272d229b6..b38489826 100644 --- a/tests/test_gossip_validation.nim +++ b/tests/test_gossip_validation.nim @@ -208,7 +208,8 @@ suite "Gossip validation - Extra": # Not based on preset config const nilCallback = OnBellatrixBlockAdded(nil) dag.addHeadBlock(verifier, blck.bellatrixData, nilCallback) of BeaconBlockFork.Capella: - raiseAssert $capellaImplementationMissing + const nilCallback = OnCapellaBlockAdded(nil) + dag.addHeadBlock(verifier, blck.capellaData, nilCallback) check: added.isOk() dag.updateHead(added[], quarantine[]) dag diff --git a/tests/test_light_client.nim b/tests/test_light_client.nim index 6d02e9fd6..06d98f276 100644 --- a/tests/test_light_client.nim +++ b/tests/test_light_client.nim @@ -68,7 +68,8 @@ suite "Light client" & preset(): const nilCallback = OnBellatrixBlockAdded(nil) dag.addHeadBlock(verifier, blck.bellatrixData, nilCallback) of BeaconBlockFork.Capella: - raiseAssert $capellaImplementationMissing + const nilCallback = OnCapellaBlockAdded(nil) + dag.addHeadBlock(verifier, blck.capellaData, nilCallback) check: added.isOk() dag.updateHead(added[], quarantine) diff --git a/tests/test_light_client_processor.nim b/tests/test_light_client_processor.nim index b036dfc44..0fb1f6e16 100644 --- a/tests/test_light_client_processor.nim +++ b/tests/test_light_client_processor.nim @@ -53,7 +53,8 @@ suite "Light client processor" & preset(): const nilCallback = OnBellatrixBlockAdded(nil) dag.addHeadBlock(verifier, blck.bellatrixData, nilCallback) of BeaconBlockFork.Capella: - raiseAssert $capellaImplementationMissing + const nilCallback = OnCapellaBlockAdded(nil) + dag.addHeadBlock(verifier, blck.capellaData, nilCallback) doAssert added.isOk() dag.updateHead(added[], quarantine[])