Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add infrastructure to select fork choice version #5387

Merged
merged 1 commit into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
8 changes: 8 additions & 0 deletions beacon_chain/conf.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -632,6 +634,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:
Expand Down
3 changes: 2 additions & 1 deletion beacon_chain/consensus_object_pools/attestation_pool.nim
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,15 @@ 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
## holding a zero_root.
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
Expand Down
12 changes: 8 additions & 4 deletions beacon_chain/fork_choice/fork_choice.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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),
Expand Down
7 changes: 7 additions & 0 deletions beacon_chain/fork_choice/fork_choice_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -88,6 +93,7 @@ type
## Subtracted from logical index to get the physical index

ProtoArray* = object
version*: ForkChoiceVersion
currentEpoch*: Epoch
checkpoints*: FinalityCheckpoints
nodes*: ProtoNodes
Expand All @@ -110,6 +116,7 @@ type
balances*: seq[Gwei]

Checkpoints* = object
version*: ForkChoiceVersion
time*: BeaconTime
justified*: BalanceCheckpoint
finalized*: Checkpoint
Expand Down
8 changes: 5 additions & 3 deletions beacon_chain/fork_choice/proto_array.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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())

Expand Down Expand Up @@ -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
Expand Down
6 changes: 4 additions & 2 deletions beacon_chain/nimbus_beacon_node.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -1860,6 +1860,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.} =
Expand Down
4 changes: 3 additions & 1 deletion beacon_chain/rpc/rest_debug_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion beacon_chain/spec/eth2_apis/rest_types.nim
Original file line number Diff line number Diff line change
Expand Up @@ -712,7 +712,7 @@ type
extra_data*: Option[RestNodeExtraData]

RestExtraData* = object
discard
version*: Option[string]

GetForkChoiceResponse* = object
justified_checkpoint*: Checkpoint
Expand Down
3 changes: 2 additions & 1 deletion tests/consensus_spec/test_fixture_fork_choice.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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)

Expand Down
3 changes: 2 additions & 1 deletion tests/test_keymanager_api.nim
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down