add infrastructure to select fork choice version (#5387)
To allow testing https://github.com/ethereum/consensus-specs/issues/3466 add support for selecting fork choice version at launch. This means we can deploy a different logic when `DENEB_FORK_EPOCH != FAR_FUTURE_EPOCH` that won't be used on Mainnet.
This commit is contained in:
parent
a06c0c550f
commit
8fa5580c50
|
@ -29,6 +29,8 @@ import
|
|||
./el/el_conf,
|
||||
./filepath
|
||||
|
||||
from fork_choice/fork_choice_types
|
||||
import ForkChoiceVersion
|
||||
from consensus_object_pools/block_pools_types_light_client
|
||||
import LightClientDataImportMode
|
||||
|
||||
|
@ -641,6 +643,12 @@ type
|
|||
desc: "Bandwidth estimate for the node (bits per second)"
|
||||
name: "debug-bandwidth-estimate" .}: Option[Natural]
|
||||
|
||||
forkChoiceVersion* {.
|
||||
hidden
|
||||
desc: "Forkchoice version to use. " &
|
||||
"Must be one of: stable"
|
||||
name: "debug-forkchoice-version" .}: Option[ForkChoiceVersion]
|
||||
|
||||
of BNStartUpCmd.wallets:
|
||||
case walletsCmd* {.command.}: WalletsCmd
|
||||
of WalletsCmd.create:
|
||||
|
|
|
@ -90,6 +90,7 @@ declareGauge attestation_pool_block_attestation_packing_time,
|
|||
|
||||
proc init*(T: type AttestationPool, dag: ChainDAGRef,
|
||||
quarantine: ref Quarantine,
|
||||
forkChoiceVersion = ForkChoiceVersion.Stable,
|
||||
onAttestation: OnAttestationCallback = nil): T =
|
||||
## Initialize an AttestationPool from the dag `headState`
|
||||
## The `finalized_root` works around the finalized_checkpoint of the genesis block
|
||||
|
@ -97,7 +98,7 @@ proc init*(T: type AttestationPool, dag: ChainDAGRef,
|
|||
let finalizedEpochRef = dag.getFinalizedEpochRef()
|
||||
|
||||
var forkChoice = ForkChoice.init(
|
||||
finalizedEpochRef, dag.finalizedHead.blck)
|
||||
finalizedEpochRef, dag.finalizedHead.blck, forkChoiceVersion)
|
||||
|
||||
# Feed fork choice with unfinalized history - during startup, block pool only
|
||||
# keeps track of a single history so we just need to follow it
|
||||
|
|
|
@ -49,11 +49,13 @@ func compute_deltas(
|
|||
logScope: topics = "fork_choice"
|
||||
|
||||
func init*(
|
||||
T: type ForkChoiceBackend, checkpoints: FinalityCheckpoints): T =
|
||||
T(proto_array: ProtoArray.init(checkpoints))
|
||||
T: type ForkChoiceBackend, checkpoints: FinalityCheckpoints,
|
||||
version: ForkChoiceVersion): T =
|
||||
T(proto_array: ProtoArray.init(checkpoints, version))
|
||||
|
||||
proc init*(
|
||||
T: type ForkChoice, epochRef: EpochRef, blck: BlockRef): T =
|
||||
T: type ForkChoice, epochRef: EpochRef, blck: BlockRef,
|
||||
version: ForkChoiceVersion): T =
|
||||
## Initialize a fork choice context for a finalized state - in the finalized
|
||||
## state, the justified and finalized checkpoints are the same, so only one
|
||||
## is used here
|
||||
|
@ -65,8 +67,10 @@ proc init*(
|
|||
backend: ForkChoiceBackend.init(
|
||||
FinalityCheckpoints(
|
||||
justified: checkpoint,
|
||||
finalized: checkpoint)),
|
||||
finalized: checkpoint),
|
||||
version),
|
||||
checkpoints: Checkpoints(
|
||||
version: version,
|
||||
justified: BalanceCheckpoint(
|
||||
checkpoint: checkpoint,
|
||||
balances: epochRef.effective_balances),
|
||||
|
|
|
@ -29,6 +29,11 @@ import
|
|||
# ----------------------------------------------------------------------
|
||||
|
||||
type
|
||||
ForkChoiceVersion* {.pure.} = enum
|
||||
## Controls which version of fork choice to run.
|
||||
Stable = "stable"
|
||||
## Use current version from stable Ethereum consensus specifications
|
||||
|
||||
fcKind* = enum
|
||||
## Fork Choice Error Kinds
|
||||
fcFinalizedNodeUnknown
|
||||
|
@ -88,6 +93,7 @@ type
|
|||
## Subtracted from logical index to get the physical index
|
||||
|
||||
ProtoArray* = object
|
||||
version*: ForkChoiceVersion
|
||||
currentEpoch*: Epoch
|
||||
checkpoints*: FinalityCheckpoints
|
||||
nodes*: ProtoNodes
|
||||
|
@ -110,6 +116,7 @@ type
|
|||
balances*: seq[Gwei]
|
||||
|
||||
Checkpoints* = object
|
||||
version*: ForkChoiceVersion
|
||||
time*: BeaconTime
|
||||
justified*: BalanceCheckpoint
|
||||
finalized*: Checkpoint
|
||||
|
|
|
@ -90,7 +90,8 @@ func nodeLeadsToViableHead(
|
|||
# ----------------------------------------------------------------------
|
||||
|
||||
func init*(
|
||||
T: type ProtoArray, checkpoints: FinalityCheckpoints): T =
|
||||
T: type ProtoArray, checkpoints: FinalityCheckpoints,
|
||||
version: ForkChoiceVersion): T =
|
||||
let node = ProtoNode(
|
||||
bid: BlockId(
|
||||
slot: checkpoints.finalized.epoch.start_slot,
|
||||
|
@ -102,7 +103,8 @@ func init*(
|
|||
bestChild: none(int),
|
||||
bestDescendant: none(int))
|
||||
|
||||
T(checkpoints: checkpoints,
|
||||
T(version: version,
|
||||
checkpoints: checkpoints,
|
||||
nodes: ProtoNodes(buf: @[node], offset: 0),
|
||||
indices: {node.bid.root: 0}.toTable())
|
||||
|
||||
|
@ -541,7 +543,7 @@ func nodeIsViableForHead(
|
|||
correctJustified =
|
||||
unrealized.justified.epoch >= self.checkpoints.justified.epoch and
|
||||
node.checkpoints.justified.epoch + 2 >= self.currentEpoch
|
||||
|
||||
|
||||
return
|
||||
if not correctJustified:
|
||||
false
|
||||
|
|
|
@ -313,8 +313,8 @@ proc initFullNode(
|
|||
let
|
||||
quarantine = newClone(
|
||||
Quarantine.init())
|
||||
attestationPool = newClone(
|
||||
AttestationPool.init(dag, quarantine, onAttestationReceived))
|
||||
attestationPool = newClone(AttestationPool.init(
|
||||
dag, quarantine, config.forkChoiceVersion.get, onAttestationReceived))
|
||||
syncCommitteeMsgPool = newClone(
|
||||
SyncCommitteeMsgPool.init(rng, dag.cfg, onSyncContribution))
|
||||
lightClientPool = newClone(
|
||||
|
@ -1902,6 +1902,8 @@ proc doRunBeaconNode(config: var BeaconNodeConf, rng: ref HmacDrbgContext) {.rai
|
|||
# works
|
||||
for node in metadata.bootstrapNodes:
|
||||
config.bootstrapNodes.add node
|
||||
if config.forkChoiceVersion.isNone:
|
||||
config.forkChoiceVersion = some(ForkChoiceVersion.Stable)
|
||||
|
||||
## Ctrl+C handling
|
||||
proc controlCHandler() {.noconv.} =
|
||||
|
|
|
@ -87,7 +87,9 @@ proc installDebugApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||
|
||||
var response = GetForkChoiceResponse(
|
||||
justified_checkpoint: forkChoice.checkpoints.justified.checkpoint,
|
||||
finalized_checkpoint: forkChoice.checkpoints.finalized)
|
||||
finalized_checkpoint: forkChoice.checkpoints.finalized,
|
||||
extra_data: RestExtraData(
|
||||
version: some($forkChoice.backend.proto_array.version)))
|
||||
|
||||
for item in forkChoice.backend.proto_array:
|
||||
let
|
||||
|
|
|
@ -574,7 +574,7 @@ type
|
|||
extra_data*: Option[RestNodeExtraData]
|
||||
|
||||
RestExtraData* = object
|
||||
discard
|
||||
version*: Option[string]
|
||||
|
||||
GetForkChoiceResponse* = object
|
||||
justified_checkpoint*: Checkpoint
|
||||
|
|
|
@ -123,7 +123,8 @@ proc initialLoad(
|
|||
dag = ChainDAGRef.init(
|
||||
forkedState[].kind.genesisTestRuntimeConfig, db, validatorMonitor, {})
|
||||
fkChoice = newClone(ForkChoice.init(
|
||||
dag.getFinalizedEpochRef(), dag.finalizedHead.blck))
|
||||
dag.getFinalizedEpochRef(), dag.finalizedHead.blck,
|
||||
ForkChoiceVersion.Stable))
|
||||
|
||||
(dag, fkChoice)
|
||||
|
||||
|
|
|
@ -295,7 +295,8 @@ proc startBeaconNode(basePort: int) {.raises: [CatchableError].} =
|
|||
"--keymanager-port=" & $(basePort + PortKind.KeymanagerBN.ord),
|
||||
"--keymanager-token-file=" & tokenFilePath,
|
||||
"--suggested-fee-recipient=" & $defaultFeeRecipient,
|
||||
"--doppelganger-detection=off"], it))
|
||||
"--doppelganger-detection=off",
|
||||
"--debug-forkchoice-version=stable"], it))
|
||||
except Exception as exc: # TODO fix confutils exceptions
|
||||
raiseAssert exc.msg
|
||||
|
||||
|
|
Loading…
Reference in New Issue