mirror of
https://github.com/status-im/nimbus-eth2.git
synced 2025-02-03 02:05:03 +00:00
more abstraction over BeaconState (#2509)
* more abstraction over BeaconState * use HashedBeaconState copy of htr
This commit is contained in:
parent
85acf55ad8
commit
99fccaee6e
24
beacon_chain/consensus_object_pools/statedata_helpers.nim
Normal file
24
beacon_chain/consensus_object_pools/statedata_helpers.nim
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# beacon_chain
|
||||||
|
# Copyright (c) 2021 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.
|
||||||
|
|
||||||
|
{.push raises: [Defect].}
|
||||||
|
|
||||||
|
import
|
||||||
|
../spec/[datatypes, digest, helpers, presets],
|
||||||
|
./block_pools_types, ./blockchain_dag
|
||||||
|
|
||||||
|
# State-related functions implemented based on StateData instead of BeaconState
|
||||||
|
|
||||||
|
# https://github.com/ethereum/eth2.0-specs/blob/v1.0.1/specs/phase0/beacon-chain.md#get_current_epoch
|
||||||
|
func get_current_epoch*(stateData: StateData): Epoch =
|
||||||
|
## Return the current epoch.
|
||||||
|
getStateField(stateData, slot).epoch
|
||||||
|
|
||||||
|
template hash_tree_root*(stateData: StateData): Eth2Digest =
|
||||||
|
# Dispatch here based on type/fork of state. Since StateData is a ref object
|
||||||
|
# type, if Nim chooses the wrong overload, it will simply fail to compile.
|
||||||
|
stateData.data.root
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2018-2020 Status Research & Development GmbH
|
# Copyright (c) 2018-2021 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * 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).
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
@ -9,7 +9,7 @@ import
|
|||||||
chronicles,
|
chronicles,
|
||||||
nimcrypto/utils as ncrutils,
|
nimcrypto/utils as ncrutils,
|
||||||
../beacon_node_common, ../networking/eth2_network,
|
../beacon_node_common, ../networking/eth2_network,
|
||||||
../consensus_object_pools/[blockchain_dag, exit_pool],
|
../consensus_object_pools/[blockchain_dag, exit_pool, statedata_helpers],
|
||||||
../gossip_processing/gossip_validation,
|
../gossip_processing/gossip_validation,
|
||||||
../validators/validator_duties,
|
../validators/validator_duties,
|
||||||
../spec/[crypto, digest, validator, datatypes, network],
|
../spec/[crypto, digest, validator, datatypes, network],
|
||||||
@ -127,9 +127,9 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||||||
router.api(MethodGet, "/api/eth/v1/beacon/genesis") do () -> RestApiResponse:
|
router.api(MethodGet, "/api/eth/v1/beacon/genesis") do () -> RestApiResponse:
|
||||||
return RestApiResponse.jsonResponse(
|
return RestApiResponse.jsonResponse(
|
||||||
(
|
(
|
||||||
genesis_time: node.chainDag.headState.data.data.genesis_time,
|
genesis_time: getStateField(node.chainDag.headState, genesis_time),
|
||||||
genesis_validators_root:
|
genesis_validators_root:
|
||||||
node.chainDag.headState.data.data.genesis_validators_root,
|
getStateField(node.chainDag.headState, genesis_validators_root),
|
||||||
genesis_fork_version: node.runtimePreset.GENESIS_FORK_VERSION
|
genesis_fork_version: node.runtimePreset.GENESIS_FORK_VERSION
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@ -268,7 +268,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||||||
(res1, res2)
|
(res1, res2)
|
||||||
|
|
||||||
node.withStateForBlockSlot(bslot):
|
node.withStateForBlockSlot(bslot):
|
||||||
let current_epoch = get_current_epoch(node.chainDag.headState.data.data)
|
let current_epoch = get_current_epoch(node.chainDag.headState)
|
||||||
var res: seq[RestValidatorTuple]
|
var res: seq[RestValidatorTuple]
|
||||||
for index, validator in getStateField(stateData, validators).pairs():
|
for index, validator in getStateField(stateData, validators).pairs():
|
||||||
let includeFlag =
|
let includeFlag =
|
||||||
@ -309,7 +309,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||||||
return RestApiResponse.jsonError(Http400, InvalidValidatorIdValueError,
|
return RestApiResponse.jsonError(Http400, InvalidValidatorIdValueError,
|
||||||
$validator_id.error())
|
$validator_id.error())
|
||||||
node.withStateForBlockSlot(bslot):
|
node.withStateForBlockSlot(bslot):
|
||||||
let current_epoch = get_current_epoch(node.chainDag.headState.data.data)
|
let current_epoch = get_current_epoch(node.chainDag.headState)
|
||||||
let vid = validator_id.get()
|
let vid = validator_id.get()
|
||||||
case vid.kind
|
case vid.kind
|
||||||
of ValidatorQueryKind.Key:
|
of ValidatorQueryKind.Key:
|
||||||
@ -416,7 +416,7 @@ proc installBeaconApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||||||
res2.incl(vitem)
|
res2.incl(vitem)
|
||||||
(res1, res2)
|
(res1, res2)
|
||||||
node.withStateForBlockSlot(bslot):
|
node.withStateForBlockSlot(bslot):
|
||||||
let current_epoch = get_current_epoch(node.chainDag.headState.data.data)
|
let current_epoch = get_current_epoch(node.chainDag.headState)
|
||||||
var res: seq[RestValidatorBalanceTuple]
|
var res: seq[RestValidatorBalanceTuple]
|
||||||
for index, validator in getStateField(stateData, validators).pairs():
|
for index, validator in getStateField(stateData, validators).pairs():
|
||||||
let includeFlag =
|
let includeFlag =
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2018-2020 Status Research & Development GmbH
|
# Copyright (c) 2018-2021 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * 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).
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
@ -28,7 +28,7 @@ proc installConfigApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||||||
# TODO: Implemenation needs a fix, when forks infrastructure will be
|
# TODO: Implemenation needs a fix, when forks infrastructure will be
|
||||||
# established.
|
# established.
|
||||||
return RestApiResponse.jsonResponse(
|
return RestApiResponse.jsonResponse(
|
||||||
[node.chainDag.headState.data.data.fork]
|
[getStateField(node.chainDag.headState, fork)]
|
||||||
)
|
)
|
||||||
|
|
||||||
router.api(MethodGet,
|
router.api(MethodGet,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2018-2020 Status Research & Development GmbH
|
# Copyright (c) 2018-2021 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * 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).
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
@ -96,8 +96,9 @@ proc installNimbusApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||||||
router.api(MethodGet, "/api/nimbus/v1/chain/head") do() -> RestApiResponse:
|
router.api(MethodGet, "/api/nimbus/v1/chain/head") do() -> RestApiResponse:
|
||||||
let
|
let
|
||||||
head = node.chainDag.head
|
head = node.chainDag.head
|
||||||
finalized = node.chainDag.headState.data.data.finalized_checkpoint
|
finalized = getStateField(node.chainDag.headState, finalized_checkpoint)
|
||||||
justified = node.chainDag.headState.data.data.current_justified_checkpoint
|
justified =
|
||||||
|
getStateField(node.chainDag.headState, current_justified_checkpoint)
|
||||||
return RestApiResponse.jsonResponse(
|
return RestApiResponse.jsonResponse(
|
||||||
(
|
(
|
||||||
head_slot: head.slot,
|
head_slot: head.slot,
|
||||||
|
@ -509,7 +509,7 @@ proc getBlockSlot*(node: BeaconNode,
|
|||||||
ok(node.chainDag.finalizedHead)
|
ok(node.chainDag.finalizedHead)
|
||||||
of StateIdentType.Justified:
|
of StateIdentType.Justified:
|
||||||
ok(node.chainDag.head.atEpochStart(
|
ok(node.chainDag.head.atEpochStart(
|
||||||
node.chainDag.headState.data.data.current_justified_checkpoint.epoch))
|
getStateField(node.chainDag.headState, current_justified_checkpoint).epoch))
|
||||||
|
|
||||||
proc getBlockDataFromBlockIdent*(node: BeaconNode,
|
proc getBlockDataFromBlockIdent*(node: BeaconNode,
|
||||||
id: BlockIdent): Result[BlockData, cstring] =
|
id: BlockIdent): Result[BlockData, cstring] =
|
||||||
@ -537,7 +537,7 @@ proc getBlockDataFromBlockIdent*(node: BeaconNode,
|
|||||||
template withStateForBlockSlot*(node: BeaconNode,
|
template withStateForBlockSlot*(node: BeaconNode,
|
||||||
blockSlot: BlockSlot, body: untyped): untyped =
|
blockSlot: BlockSlot, body: untyped): untyped =
|
||||||
template isState(state: StateData): bool =
|
template isState(state: StateData): bool =
|
||||||
state.blck.atSlot(state.data.data.slot) == blockSlot
|
state.blck.atSlot(getStateField(state, slot)) == blockSlot
|
||||||
|
|
||||||
if isState(node.chainDag.headState):
|
if isState(node.chainDag.headState):
|
||||||
withStateVars(node.chainDag.headState):
|
withStateVars(node.chainDag.headState):
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
# Copyright (c) 2018-2020 Status Research & Development GmbH
|
# Copyright (c) 2018-2021 Status Research & Development GmbH
|
||||||
# Licensed and distributed under either of
|
# Licensed and distributed under either of
|
||||||
# * MIT license (license terms in the root directory or at https://opensource.org/licenses/MIT).
|
# * 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).
|
# * Apache v2 license (license terms in the root directory or at https://www.apache.org/licenses/LICENSE-2.0).
|
||||||
@ -362,10 +362,10 @@ proc installValidatorApiHandlers*(router: var RestRouter, node: BeaconNode) =
|
|||||||
block:
|
block:
|
||||||
let idx = request.validator_index
|
let idx = request.validator_index
|
||||||
if uint64(idx) >=
|
if uint64(idx) >=
|
||||||
lenu64(node.chainDag.headState.data.data.validators):
|
lenu64(getStateField(node.chainDag.headState, validators)):
|
||||||
return RestApiResponse.jsonError(Http400,
|
return RestApiResponse.jsonError(Http400,
|
||||||
InvalidValidatorIndexValueError)
|
InvalidValidatorIndexValueError)
|
||||||
node.chainDag.headState.data.data.validators[idx].pubkey
|
getStateField(node.chainDag.headState, validators)[idx].pubkey
|
||||||
|
|
||||||
let wallSlot = node.beaconClock.now.slotOrZero
|
let wallSlot = node.beaconClock.now.slotOrZero
|
||||||
if wallSlot > request.slot + 1:
|
if wallSlot > request.slot + 1:
|
||||||
|
@ -66,16 +66,17 @@ proc findValidator(validators: auto, pubKey: ValidatorPubKey):
|
|||||||
else:
|
else:
|
||||||
some(idx.ValidatorIndex)
|
some(idx.ValidatorIndex)
|
||||||
|
|
||||||
proc addLocalValidator*(node: BeaconNode,
|
proc addLocalValidator(node: BeaconNode,
|
||||||
state: BeaconState,
|
stateData: StateData,
|
||||||
privKey: ValidatorPrivKey) =
|
privKey: ValidatorPrivKey) =
|
||||||
let pubKey = privKey.toPubKey()
|
let pubKey = privKey.toPubKey()
|
||||||
node.attachedValidators[].addLocalValidator(
|
node.attachedValidators[].addLocalValidator(
|
||||||
pubKey, privKey, findValidator(state.validators, pubKey))
|
pubKey, privKey,
|
||||||
|
findValidator(getStateField(stateData, validators), pubKey))
|
||||||
|
|
||||||
proc addLocalValidators*(node: BeaconNode) =
|
proc addLocalValidators*(node: BeaconNode) =
|
||||||
for validatorKey in node.config.validatorKeys:
|
for validatorKey in node.config.validatorKeys:
|
||||||
node.addLocalValidator node.chainDag.headState.data.data, validatorKey
|
node.addLocalValidator node.chainDag.headState, validatorKey
|
||||||
|
|
||||||
proc addRemoteValidators*(node: BeaconNode) {.raises: [Defect, OSError, IOError].} =
|
proc addRemoteValidators*(node: BeaconNode) {.raises: [Defect, OSError, IOError].} =
|
||||||
# load all the validators from the child process - loop until `end`
|
# load all the validators from the child process - loop until `end`
|
||||||
|
@ -224,7 +224,7 @@ cli do(slots = SLOTS_PER_EPOCH * 5,
|
|||||||
|
|
||||||
# TODO if attestation pool was smarter, it would include older attestations
|
# TODO if attestation pool was smarter, it would include older attestations
|
||||||
# too!
|
# too!
|
||||||
verifyConsensus(chainDag.headState.data.data, attesterRatio * blockRatio)
|
verifyConsensus(chainDag.headState, attesterRatio * blockRatio)
|
||||||
|
|
||||||
if t == tEpoch:
|
if t == tEpoch:
|
||||||
echo &". slot: {shortLog(slot)} ",
|
echo &". slot: {shortLog(slot)} ",
|
||||||
@ -241,4 +241,4 @@ cli do(slots = SLOTS_PER_EPOCH * 5,
|
|||||||
|
|
||||||
echo "Done!"
|
echo "Done!"
|
||||||
|
|
||||||
printTimers(chainDag.headState.data.data, attesters, true, timers)
|
printTimers(chainDag.headState, attesters, true, timers)
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
import
|
import
|
||||||
stats, os, strformat, times,
|
stats, os, strformat, times,
|
||||||
../tests/[testblockutil],
|
../tests/testblockutil,
|
||||||
../beacon_chain/[extras, beacon_chain_db],
|
../beacon_chain/[extras, beacon_chain_db],
|
||||||
../beacon_chain/ssz/[merkleization, ssz_serialization],
|
../beacon_chain/ssz/[merkleization, ssz_serialization],
|
||||||
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest, helpers, presets],
|
../beacon_chain/spec/[beaconstate, crypto, datatypes, digest, helpers, presets],
|
||||||
|
../beacon_chain/consensus_object_pools/[
|
||||||
|
blockchain_dag, block_pools_types, statedata_helpers],
|
||||||
../beacon_chain/eth1/eth1_monitor
|
../beacon_chain/eth1/eth1_monitor
|
||||||
|
|
||||||
template withTimer*(stats: var RunningStat, body: untyped) =
|
template withTimer*(stats: var RunningStat, body: untyped) =
|
||||||
@ -41,6 +43,24 @@ func verifyConsensus*(state: BeaconState, attesterRatio: auto) =
|
|||||||
if current_epoch >= 4:
|
if current_epoch >= 4:
|
||||||
doAssert state.finalized_checkpoint.epoch + 2 >= current_epoch
|
doAssert state.finalized_checkpoint.epoch + 2 >= current_epoch
|
||||||
|
|
||||||
|
func verifyConsensus*(state: StateData, attesterRatio: auto) =
|
||||||
|
if attesterRatio < 0.63:
|
||||||
|
doAssert getStateField(state, current_justified_checkpoint).epoch == 0
|
||||||
|
doAssert getStateField(state, finalized_checkpoint).epoch == 0
|
||||||
|
|
||||||
|
# Quorum is 2/3 of validators, and at low numbers, quantization effects
|
||||||
|
# can dominate, so allow for play above/below attesterRatio of 2/3.
|
||||||
|
if attesterRatio < 0.72:
|
||||||
|
return
|
||||||
|
|
||||||
|
let current_epoch = get_current_epoch(state)
|
||||||
|
if current_epoch >= 3:
|
||||||
|
doAssert getStateField(
|
||||||
|
state, current_justified_checkpoint).epoch + 1 >= current_epoch
|
||||||
|
if current_epoch >= 4:
|
||||||
|
doAssert getStateField(
|
||||||
|
state, finalized_checkpoint).epoch + 2 >= current_epoch
|
||||||
|
|
||||||
proc loadGenesis*(validators: Natural, validate: bool):
|
proc loadGenesis*(validators: Natural, validate: bool):
|
||||||
(ref HashedBeaconState, DepositContractSnapshot) =
|
(ref HashedBeaconState, DepositContractSnapshot) =
|
||||||
let
|
let
|
||||||
@ -122,3 +142,10 @@ proc printTimers*[Timers: enum](
|
|||||||
echo "Validators: ", state.validators.len, ", epoch length: ", SLOTS_PER_EPOCH
|
echo "Validators: ", state.validators.len, ", epoch length: ", SLOTS_PER_EPOCH
|
||||||
echo "Validators per attestation (mean): ", attesters.mean
|
echo "Validators per attestation (mean): ", attesters.mean
|
||||||
printTimers(validate, timers)
|
printTimers(validate, timers)
|
||||||
|
|
||||||
|
proc printTimers*[Timers: enum](
|
||||||
|
state: StateData, attesters: RunningStat, validate: bool,
|
||||||
|
timers: array[Timers, RunningStat]) =
|
||||||
|
echo "Validators: ", getStateField(state, validators).len, ", epoch length: ", SLOTS_PER_EPOCH
|
||||||
|
echo "Validators per attestation (mean): ", attesters.mean
|
||||||
|
printTimers(validate, timers)
|
||||||
|
@ -67,13 +67,13 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
cache = StateCache()
|
cache = StateCache()
|
||||||
# Slot 0 is a finalized slot - won't be making attestations for it..
|
# Slot 0 is a finalized slot - won't be making attestations for it..
|
||||||
check:
|
check:
|
||||||
process_slots(state.data, state.data.data.slot + 1, cache)
|
process_slots(state.data, getStateField(state, slot) + 1, cache)
|
||||||
|
|
||||||
timedTest "Can add and retrieve simple attestations" & preset():
|
timedTest "Can add and retrieve simple attestations" & preset():
|
||||||
let
|
let
|
||||||
# Create an attestation for slot 1!
|
# Create an attestation for slot 1!
|
||||||
bc0 = get_beacon_committee(
|
bc0 = get_beacon_committee(
|
||||||
state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
|
state.data.data, getStateField(state, slot), 0.CommitteeIndex, cache)
|
||||||
attestation = makeAttestation(
|
attestation = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[0], cache)
|
state.data.data, state.blck.root, bc0[0], cache)
|
||||||
|
|
||||||
@ -98,7 +98,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
none(Slot), some(CommitteeIndex(attestation.data.index + 1)))) == []
|
none(Slot), some(CommitteeIndex(attestation.data.index + 1)))) == []
|
||||||
|
|
||||||
process_slots(
|
process_slots(
|
||||||
state.data, state.data.data.slot + MIN_ATTESTATION_INCLUSION_DELAY, cache)
|
state.data,
|
||||||
|
getStateField(state, slot) + MIN_ATTESTATION_INCLUSION_DELAY, cache)
|
||||||
|
|
||||||
let attestations = pool[].getAttestationsForBlock(state.data.data, cache)
|
let attestations = pool[].getAttestationsForBlock(state.data.data, cache)
|
||||||
|
|
||||||
@ -111,13 +112,14 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
state.data, state.blck.root,
|
state.data, state.blck.root,
|
||||||
cache, attestations = attestations, nextSlot = false).root
|
cache, attestations = attestations, nextSlot = false).root
|
||||||
bc1 = get_beacon_committee(
|
bc1 = get_beacon_committee(
|
||||||
state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
|
state.data.data, getStateField(state, slot), 0.CommitteeIndex, cache)
|
||||||
att1 = makeAttestation(
|
att1 = makeAttestation(
|
||||||
state.data.data, root1, bc1[0], cache)
|
state.data.data, root1, bc1[0], cache)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
process_slots(
|
process_slots(
|
||||||
state.data, state.data.data.slot + MIN_ATTESTATION_INCLUSION_DELAY, cache)
|
state.data,
|
||||||
|
getStateField(state, slot) + MIN_ATTESTATION_INCLUSION_DELAY, cache)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
# shouldn't include already-included attestations
|
# shouldn't include already-included attestations
|
||||||
@ -176,7 +178,7 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
let
|
let
|
||||||
# Create an attestation for slot 1!
|
# Create an attestation for slot 1!
|
||||||
bc0 = get_beacon_committee(
|
bc0 = get_beacon_committee(
|
||||||
state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
|
state.data.data, getStateField(state, slot), 0.CommitteeIndex, cache)
|
||||||
|
|
||||||
var
|
var
|
||||||
att0 = makeAttestation(state.data.data, state.blck.root, bc0[0], cache)
|
att0 = makeAttestation(state.data.data, state.blck.root, bc0[0], cache)
|
||||||
@ -194,7 +196,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
|
|
||||||
check:
|
check:
|
||||||
process_slots(
|
process_slots(
|
||||||
state.data, state.data.data.slot + MIN_ATTESTATION_INCLUSION_DELAY, cache)
|
state.data,
|
||||||
|
getStateField(state, slot) + MIN_ATTESTATION_INCLUSION_DELAY, cache)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
pool[].getAttestationsForBlock(state.data.data, cache).len() == 2
|
pool[].getAttestationsForBlock(state.data.data, cache).len() == 2
|
||||||
@ -230,7 +233,7 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
root.data[0..<8] = toBytesBE(i.uint64)
|
root.data[0..<8] = toBytesBE(i.uint64)
|
||||||
let
|
let
|
||||||
bc0 = get_beacon_committee(
|
bc0 = get_beacon_committee(
|
||||||
state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
|
state.data.data, getStateField(state, slot), 0.CommitteeIndex, cache)
|
||||||
|
|
||||||
for j in 0..<bc0.len():
|
for j in 0..<bc0.len():
|
||||||
root.data[8..<16] = toBytesBE(j.uint64)
|
root.data[8..<16] = toBytesBE(j.uint64)
|
||||||
@ -239,7 +242,7 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
inc attestations
|
inc attestations
|
||||||
|
|
||||||
check:
|
check:
|
||||||
process_slots(state.data, state.data.data.slot + 1, cache)
|
process_slots(state.data, getStateField(state, slot) + 1, cache)
|
||||||
|
|
||||||
doAssert attestations.uint64 > MAX_ATTESTATIONS,
|
doAssert attestations.uint64 > MAX_ATTESTATIONS,
|
||||||
"6*SLOTS_PER_EPOCH validators > 128 mainnet MAX_ATTESTATIONS"
|
"6*SLOTS_PER_EPOCH validators > 128 mainnet MAX_ATTESTATIONS"
|
||||||
@ -247,23 +250,24 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
# Fill block with attestations
|
# Fill block with attestations
|
||||||
pool[].getAttestationsForBlock(state.data.data, cache).lenu64() ==
|
pool[].getAttestationsForBlock(state.data.data, cache).lenu64() ==
|
||||||
MAX_ATTESTATIONS
|
MAX_ATTESTATIONS
|
||||||
pool[].getAggregatedAttestation(state.data.data.slot - 1, 0.CommitteeIndex).isSome()
|
pool[].getAggregatedAttestation(
|
||||||
|
getStateField(state, slot) - 1, 0.CommitteeIndex).isSome()
|
||||||
|
|
||||||
timedTest "Attestations may arrive in any order" & preset():
|
timedTest "Attestations may arrive in any order" & preset():
|
||||||
var cache = StateCache()
|
var cache = StateCache()
|
||||||
let
|
let
|
||||||
# Create an attestation for slot 1!
|
# Create an attestation for slot 1!
|
||||||
bc0 = get_beacon_committee(
|
bc0 = get_beacon_committee(
|
||||||
state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
|
state.data.data, getStateField(state, slot), 0.CommitteeIndex, cache)
|
||||||
attestation0 = makeAttestation(
|
attestation0 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[0], cache)
|
state.data.data, state.blck.root, bc0[0], cache)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
process_slots(state.data, state.data.data.slot + 1, cache)
|
process_slots(state.data, getStateField(state, slot) + 1, cache)
|
||||||
|
|
||||||
let
|
let
|
||||||
bc1 = get_beacon_committee(state.data.data,
|
bc1 = get_beacon_committee(state.data.data,
|
||||||
state.data.data.slot, 0.CommitteeIndex, cache)
|
getStateField(state, slot), 0.CommitteeIndex, cache)
|
||||||
attestation1 = makeAttestation(
|
attestation1 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc1[0], cache)
|
state.data.data, state.blck.root, bc1[0], cache)
|
||||||
|
|
||||||
@ -286,7 +290,7 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
let
|
let
|
||||||
# Create an attestation for slot 1!
|
# Create an attestation for slot 1!
|
||||||
bc0 = get_beacon_committee(
|
bc0 = get_beacon_committee(
|
||||||
state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
|
state.data.data, getStateField(state, slot), 0.CommitteeIndex, cache)
|
||||||
attestation0 = makeAttestation(
|
attestation0 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[0], cache)
|
state.data.data, state.blck.root, bc0[0], cache)
|
||||||
attestation1 = makeAttestation(
|
attestation1 = makeAttestation(
|
||||||
@ -311,7 +315,7 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
var
|
var
|
||||||
# Create an attestation for slot 1!
|
# Create an attestation for slot 1!
|
||||||
bc0 = get_beacon_committee(
|
bc0 = get_beacon_committee(
|
||||||
state.data.data, state.data.data.slot, 0.CommitteeIndex, cache)
|
state.data.data, getStateField(state, slot), 0.CommitteeIndex, cache)
|
||||||
attestation0 = makeAttestation(
|
attestation0 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[0], cache)
|
state.data.data, state.blck.root, bc0[0], cache)
|
||||||
attestation1 = makeAttestation(
|
attestation1 = makeAttestation(
|
||||||
@ -337,7 +341,7 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
var
|
var
|
||||||
# Create an attestation for slot 1!
|
# Create an attestation for slot 1!
|
||||||
bc0 = get_beacon_committee(state.data.data,
|
bc0 = get_beacon_committee(state.data.data,
|
||||||
state.data.data.slot, 0.CommitteeIndex, cache)
|
getStateField(state, slot), 0.CommitteeIndex, cache)
|
||||||
attestation0 = makeAttestation(
|
attestation0 = makeAttestation(
|
||||||
state.data.data, state.blck.root, bc0[0], cache)
|
state.data.data, state.blck.root, bc0[0], cache)
|
||||||
attestation1 = makeAttestation(
|
attestation1 = makeAttestation(
|
||||||
@ -412,7 +416,7 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
pool[].addForkChoice(epochRef, blckRef, signedBlock.message, blckRef.slot)
|
||||||
|
|
||||||
bc1 = get_beacon_committee(
|
bc1 = get_beacon_committee(
|
||||||
state.data.data, state.data.data.slot - 1, 1.CommitteeIndex, cache)
|
state.data.data, getStateField(state, slot) - 1, 1.CommitteeIndex, cache)
|
||||||
attestation0 = makeAttestation(state.data.data, b10.root, bc1[0], cache)
|
attestation0 = makeAttestation(state.data.data, b10.root, bc1[0], cache)
|
||||||
|
|
||||||
pool[].addAttestation(
|
pool[].addAttestation(
|
||||||
@ -521,7 +525,8 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
attestations.setlen(0)
|
attestations.setlen(0)
|
||||||
for index in 0'u64 ..< committees_per_slot:
|
for index in 0'u64 ..< committees_per_slot:
|
||||||
let committee = get_beacon_committee(
|
let committee = get_beacon_committee(
|
||||||
state.data.data, state.data.data.slot, index.CommitteeIndex, cache)
|
state.data.data, getStateField(state, slot), index.CommitteeIndex,
|
||||||
|
cache)
|
||||||
|
|
||||||
# Create a bitfield filled with the given count per attestation,
|
# Create a bitfield filled with the given count per attestation,
|
||||||
# exactly on the right-most part of the committee field.
|
# exactly on the right-most part of the committee field.
|
||||||
@ -532,7 +537,7 @@ suiteReport "Attestation pool processing" & preset():
|
|||||||
attestations.add Attestation(
|
attestations.add Attestation(
|
||||||
aggregation_bits: aggregation_bits,
|
aggregation_bits: aggregation_bits,
|
||||||
data: makeAttestationData(
|
data: makeAttestationData(
|
||||||
state.data.data, state.data.data.slot,
|
state.data.data, getStateField(state, slot),
|
||||||
index.CommitteeIndex, blockroot)
|
index.CommitteeIndex, blockroot)
|
||||||
# signature: ValidatorSig()
|
# signature: ValidatorSig()
|
||||||
)
|
)
|
||||||
@ -569,7 +574,7 @@ suiteReport "Attestation validation " & preset():
|
|||||||
batchCrypto = BatchCrypto.new(keys.newRng())
|
batchCrypto = BatchCrypto.new(keys.newRng())
|
||||||
# Slot 0 is a finalized slot - won't be making attestations for it..
|
# Slot 0 is a finalized slot - won't be making attestations for it..
|
||||||
check:
|
check:
|
||||||
process_slots(state.data, state.data.data.slot + 1, cache)
|
process_slots(state.data, getStateField(state, slot) + 1, cache)
|
||||||
|
|
||||||
timedTest "Validation sanity":
|
timedTest "Validation sanity":
|
||||||
# TODO: refactor tests to avoid skipping BLS validation
|
# TODO: refactor tests to avoid skipping BLS validation
|
||||||
|
@ -15,7 +15,8 @@ import
|
|||||||
../beacon_chain/spec/[datatypes, digest, helpers, state_transition, presets],
|
../beacon_chain/spec/[datatypes, digest, helpers, state_transition, presets],
|
||||||
../beacon_chain/beacon_node_types,
|
../beacon_chain/beacon_node_types,
|
||||||
../beacon_chain/ssz,
|
../beacon_chain/ssz,
|
||||||
../beacon_chain/consensus_object_pools/[blockchain_dag, block_quarantine, block_clearance]
|
../beacon_chain/consensus_object_pools/[
|
||||||
|
blockchain_dag, block_quarantine, block_clearance, statedata_helpers]
|
||||||
|
|
||||||
when isMainModule:
|
when isMainModule:
|
||||||
import chronicles # or some random compile error happens...
|
import chronicles # or some random compile error happens...
|
||||||
@ -174,7 +175,7 @@ suiteReport "Block pool processing" & preset():
|
|||||||
|
|
||||||
# Skip one slot to get a gap
|
# Skip one slot to get a gap
|
||||||
check:
|
check:
|
||||||
process_slots(stateData.data, stateData.data.data.slot + 1, cache)
|
process_slots(stateData.data, getStateField(stateData, slot) + 1, cache)
|
||||||
|
|
||||||
let
|
let
|
||||||
b4 = addTestBlock(stateData.data, b2.root, cache)
|
b4 = addTestBlock(stateData.data, b2.root, cache)
|
||||||
@ -262,7 +263,7 @@ suiteReport "Block pool processing" & preset():
|
|||||||
check:
|
check:
|
||||||
# ensure we loaded the correct head state
|
# ensure we loaded the correct head state
|
||||||
dag2.head.root == b2.root
|
dag2.head.root == b2.root
|
||||||
hash_tree_root(dag2.headState.data.data) == b2.message.state_root
|
hash_tree_root(dag2.headState) == b2.message.state_root
|
||||||
dag2.get(b1.root).isSome()
|
dag2.get(b1.root).isSome()
|
||||||
dag2.get(b2.root).isSome()
|
dag2.get(b2.root).isSome()
|
||||||
dag2.heads.len == 1
|
dag2.heads.len == 1
|
||||||
@ -286,7 +287,7 @@ suiteReport "Block pool processing" & preset():
|
|||||||
|
|
||||||
check:
|
check:
|
||||||
dag.head == b1Add[]
|
dag.head == b1Add[]
|
||||||
dag.headState.data.data.slot == b1Add[].slot
|
getStateField(dag.headState, slot) == b1Add[].slot
|
||||||
|
|
||||||
wrappedTimedTest "updateStateData sanity" & preset():
|
wrappedTimedTest "updateStateData sanity" & preset():
|
||||||
let
|
let
|
||||||
@ -304,38 +305,38 @@ suiteReport "Block pool processing" & preset():
|
|||||||
|
|
||||||
check:
|
check:
|
||||||
tmpState.blck == b1Add[]
|
tmpState.blck == b1Add[]
|
||||||
tmpState.data.data.slot == bs1.slot
|
getStateField(tmpState, slot) == bs1.slot
|
||||||
|
|
||||||
# Skip slots
|
# Skip slots
|
||||||
dag.updateStateData(tmpState[], bs1_3, false, cache) # skip slots
|
dag.updateStateData(tmpState[], bs1_3, false, cache) # skip slots
|
||||||
|
|
||||||
check:
|
check:
|
||||||
tmpState.blck == b1Add[]
|
tmpState.blck == b1Add[]
|
||||||
tmpState.data.data.slot == bs1_3.slot
|
getStateField(tmpState, slot) == bs1_3.slot
|
||||||
|
|
||||||
# Move back slots, but not blocks
|
# Move back slots, but not blocks
|
||||||
dag.updateStateData(tmpState[], bs1_3.parent(), false, cache)
|
dag.updateStateData(tmpState[], bs1_3.parent(), false, cache)
|
||||||
check:
|
check:
|
||||||
tmpState.blck == b1Add[]
|
tmpState.blck == b1Add[]
|
||||||
tmpState.data.data.slot == bs1_3.parent().slot
|
getStateField(tmpState, slot) == bs1_3.parent().slot
|
||||||
|
|
||||||
# Move to different block and slot
|
# Move to different block and slot
|
||||||
dag.updateStateData(tmpState[], bs2_3, false, cache)
|
dag.updateStateData(tmpState[], bs2_3, false, cache)
|
||||||
check:
|
check:
|
||||||
tmpState.blck == b2Add[]
|
tmpState.blck == b2Add[]
|
||||||
tmpState.data.data.slot == bs2_3.slot
|
getStateField(tmpState, slot) == bs2_3.slot
|
||||||
|
|
||||||
# Move back slot and block
|
# Move back slot and block
|
||||||
dag.updateStateData(tmpState[], bs1, false, cache)
|
dag.updateStateData(tmpState[], bs1, false, cache)
|
||||||
check:
|
check:
|
||||||
tmpState.blck == b1Add[]
|
tmpState.blck == b1Add[]
|
||||||
tmpState.data.data.slot == bs1.slot
|
getStateField(tmpState, slot) == bs1.slot
|
||||||
|
|
||||||
# Move back to genesis
|
# Move back to genesis
|
||||||
dag.updateStateData(tmpState[], bs1.parent(), false, cache)
|
dag.updateStateData(tmpState[], bs1.parent(), false, cache)
|
||||||
check:
|
check:
|
||||||
tmpState.blck == b1Add[].parent
|
tmpState.blck == b1Add[].parent
|
||||||
tmpState.data.data.slot == bs1.parent.slot
|
getStateField(tmpState, slot) == bs1.parent.slot
|
||||||
|
|
||||||
suiteReport "chain DAG finalization tests" & preset():
|
suiteReport "chain DAG finalization tests" & preset():
|
||||||
setup:
|
setup:
|
||||||
@ -431,8 +432,7 @@ suiteReport "chain DAG finalization tests" & preset():
|
|||||||
dag2.head.root == dag.head.root
|
dag2.head.root == dag.head.root
|
||||||
dag2.finalizedHead.blck.root == dag.finalizedHead.blck.root
|
dag2.finalizedHead.blck.root == dag.finalizedHead.blck.root
|
||||||
dag2.finalizedHead.slot == dag.finalizedHead.slot
|
dag2.finalizedHead.slot == dag.finalizedHead.slot
|
||||||
hash_tree_root(dag2.headState.data.data) ==
|
hash_tree_root(dag2.headState) == hash_tree_root(dag.headState)
|
||||||
hash_tree_root(dag.headState.data.data)
|
|
||||||
|
|
||||||
wrappedTimedTest "orphaned epoch block" & preset():
|
wrappedTimedTest "orphaned epoch block" & preset():
|
||||||
var prestate = (ref HashedBeaconState)()
|
var prestate = (ref HashedBeaconState)()
|
||||||
@ -496,7 +496,7 @@ suiteReport "chain DAG finalization tests" & preset():
|
|||||||
dag.headState.data, dag.head.root, cache,
|
dag.headState.data, dag.head.root, cache,
|
||||||
attestations = makeFullAttestations(
|
attestations = makeFullAttestations(
|
||||||
dag.headState.data.data, dag.head.root,
|
dag.headState.data.data, dag.head.root,
|
||||||
dag.headState.data.data.slot, cache, {}))
|
getStateField(dag.headState, slot), cache, {}))
|
||||||
|
|
||||||
let added = dag.addRawBlock(quarantine, blck, nil)
|
let added = dag.addRawBlock(quarantine, blck, nil)
|
||||||
check: added.isOk()
|
check: added.isOk()
|
||||||
@ -512,5 +512,4 @@ suiteReport "chain DAG finalization tests" & preset():
|
|||||||
dag2.head.root == dag.head.root
|
dag2.head.root == dag.head.root
|
||||||
dag2.finalizedHead.blck.root == dag.finalizedHead.blck.root
|
dag2.finalizedHead.blck.root == dag.finalizedHead.blck.root
|
||||||
dag2.finalizedHead.slot == dag.finalizedHead.slot
|
dag2.finalizedHead.slot == dag.finalizedHead.slot
|
||||||
hash_tree_root(dag2.headState.data.data) ==
|
hash_tree_root(dag2.headState) == hash_tree_root(dag.headState)
|
||||||
hash_tree_root(dag.headState.data.data)
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user