Initial frozen phase 0/v0.8.0 spec (#305)

* rename slot_to_epoch(...) to compute_epoch_of_slot(...)

* rename aggregation_bitfield/custody_bitfield fields to aggregation_bits/custody_bits; rename convert_to_indexed(...) to get_indexed_attestation(...); mark BeaconBlockHeader as 0.8.0; update minimal preset MIN_ATTESTATION_INCLUSION_DELAY/time parameters in general to 0.8

* fix beacon node compilation; it used slightly different capitalizations of slot_to_epoch/slotToEpoch

* mark integer_squareroot(...), Deposit, VoluntaryExit, and Transfer as 0.8.0; rename get_epoch_start_slot(...) to compute_start_slot_of_epoch(...)

* add new Domain alias for uint64; rename bls_domain(...) to compute_domain(...), MAX_INDICES_PER_ATTESTATION to MAX_VALIDATORS_PER_COMMITTEE, and SignatureDomain to DomainType; update get_domain(...) to 0.8.0

* update/mark initiate_validator_exit(...) and Crosslink as 0.8.0; rename BeaconState.latest_block_roots -> BeaconState.block_roots; mark HistoricalBatch as 0.8.0
This commit is contained in:
Dustin Brody 2019-07-01 07:53:42 +00:00 committed by Mamy Ratsimbazafy
parent 7356905f95
commit e4321dc4ed
22 changed files with 159 additions and 162 deletions

View File

@ -23,8 +23,8 @@ proc combine*(tgt: var Attestation, src: Attestation, flags: UpdateFlags) =
# In a BLS aggregate signature, one needs to count how many times a
# particular public key has been added - since we use a single bit per key, we
# can only it once, thus we can never combine signatures that overlap already!
if not tgt.aggregation_bitfield.overlaps(src.aggregation_bitfield):
tgt.aggregation_bitfield.combine(src.aggregation_bitfield)
if not tgt.aggregation_bits.overlaps(src.aggregation_bits):
tgt.aggregation_bits.combine(src.aggregation_bits)
if skipValidation notin flags:
tgt.signature.combine(src.signature)
@ -40,10 +40,10 @@ proc validate(
let attestationSlot = get_attestation_data_slot(state, attestation.data)
if attestationSlot < state.finalized_epoch.get_epoch_start_slot():
if attestationSlot < state.finalized_epoch.compute_start_slot_of_epoch():
debug "Old attestation",
attestationSlot = humaneSlotNum(attestationSlot),
attestationEpoch = humaneEpochNum(attestationSlot.slot_to_epoch),
attestationEpoch = humaneEpochNum(attestationSlot.compute_epoch_of_slot),
stateSlot = humaneSlotNum(state.slot),
finalizedEpoch = humaneEpochNum(state.finalized_epoch)
@ -55,16 +55,16 @@ proc validate(
if attestationSlot > state.slot + 64:
debug "Future attestation",
attestationSlot = humaneSlotNum(attestationSlot),
attestationEpoch = humaneEpochNum(attestationSlot.slot_to_epoch),
attestationEpoch = humaneEpochNum(attestationSlot.compute_epoch_of_slot),
stateSlot = humaneSlotNum(state.slot),
finalizedEpoch = humaneEpochNum(state.finalized_epoch)
return
if not allIt(attestation.custody_bitfield.bits, it == 0):
if not allIt(attestation.custody_bits.bits, it == 0):
notice "Invalid custody bitfield for phase 0"
return false
if not anyIt(attestation.aggregation_bitfield.bits, it != 0):
if not anyIt(attestation.aggregation_bits.bits, it != 0):
notice "Empty aggregation bitfield"
return false
@ -72,9 +72,9 @@ proc validate(
if skipValidation notin flags:
let
participants = get_attesting_indices_seq(
state, attestation.data, attestation.aggregation_bitfield)
state, attestation.data, attestation.aggregation_bits)
## TODO when the custody_bitfield assertion-to-emptiness disappears do this
## TODO when the custody_bits assertion-to-emptiness disappears do this
## and fix the custody_bit_0_participants check to depend on it.
# custody_bit_1_participants = {nothing, always, because assertion above}
custody_bit_1_participants: seq[ValidatorIndex] = @[]
@ -99,7 +99,7 @@ proc validate(
],
attestation.signature,
get_domain(state, DOMAIN_ATTESTATION,
slot_to_epoch(get_attestation_data_slot(state, attestation.data))),
compute_epoch_of_slot(get_attestation_data_slot(state, attestation.data))),
):
notice "Invalid signature", participants
return false
@ -130,7 +130,7 @@ proc slotIndex(
# earlier than that is thrown out by the above check
info "First attestation!",
attestationSlot = $humaneSlotNum(attestationSlot)
pool.startingSlot = state.finalized_epoch.get_epoch_start_slot()
pool.startingSlot = state.finalized_epoch.compute_start_slot_of_epoch()
if pool.startingSlot + pool.slots.len.uint64 <= attestationSlot:
debug "Growing attestation pool",
@ -141,14 +141,14 @@ proc slotIndex(
while pool.startingSlot + pool.slots.len.uint64 <= attestationSlot:
pool.slots.addLast(SlotData())
if pool.startingSlot < state.finalized_epoch.get_epoch_start_slot():
if pool.startingSlot < state.finalized_epoch.compute_start_slot_of_epoch():
debug "Pruning attestation pool",
startingSlot = $humaneSlotNum(pool.startingSlot),
finalizedSlot =
$humaneSlotNum(state.finalized_epoch.get_epoch_start_slot())
$humaneSlotNum(state.finalized_epoch.compute_start_slot_of_epoch())
# TODO there should be a better way to remove a whole epoch of stuff..
while pool.startingSlot < state.finalized_epoch.get_epoch_start_slot():
while pool.startingSlot < state.finalized_epoch.compute_start_slot_of_epoch():
pool.slots.popFirst()
pool.startingSlot += 1
@ -178,17 +178,17 @@ proc add*(pool: var AttestationPool,
idx = pool.slotIndex(state, attestationSlot)
slotData = addr pool.slots[idx]
validation = Validation(
aggregation_bitfield: attestation.aggregation_bitfield,
custody_bitfield: attestation.custody_bitfield,
aggregation_bits: attestation.aggregation_bits,
custody_bits: attestation.custody_bits,
aggregate_signature: attestation.signature)
participants = get_attesting_indices_seq(
state, attestation.data, validation.aggregation_bitfield)
state, attestation.data, validation.aggregation_bits)
var found = false
for a in slotData.attestations.mitems():
if a.data == attestation.data:
for v in a.validations:
if validation.aggregation_bitfield.isSubsetOf(v.aggregation_bitfield):
if validation.aggregation_bits.isSubsetOf(v.aggregation_bits):
# The validations in the new attestation are a subset of one of the
# attestations that we already have on file - no need to add this
# attestation to the database
@ -197,7 +197,7 @@ proc add*(pool: var AttestationPool,
# and therefore being useful after all?
debug "Ignoring subset attestation",
existingParticipants = get_attesting_indices_seq(
state, a.data, v.aggregation_bitfield),
state, a.data, v.aggregation_bits),
newParticipants = participants
found = true
break
@ -206,11 +206,11 @@ proc add*(pool: var AttestationPool,
# Attestations in the pool that are a subset of the new attestation
# can now be removed per same logic as above
a.validations.keepItIf(
if it.aggregation_bitfield.isSubsetOf(
validation.aggregation_bitfield):
if it.aggregation_bits.isSubsetOf(
validation.aggregation_bits):
debug "Removing subset attestation",
existingParticipants = get_attesting_indices_seq(
state, a.data, it.aggregation_bitfield),
state, a.data, it.aggregation_bits),
newParticipants = participants
false
else:
@ -285,9 +285,9 @@ proc getAttestationsForBlock*(
for a in slotData.attestations:
var
attestation = Attestation(
aggregation_bitfield: a.validations[0].aggregation_bitfield,
aggregation_bits: a.validations[0].aggregation_bits,
data: a.data,
custody_bitfield: a.validations[0].custody_bitfield,
custody_bits: a.validations[0].custody_bits,
signature: a.validations[0].aggregate_signature
)
@ -309,11 +309,11 @@ proc getAttestationsForBlock*(
# and naively add as much as possible in one go, by we could also
# add the same attestation data twice, as long as there's at least
# one new attestation in there
if not attestation.aggregation_bitfield.overlaps(
v.aggregation_bitfield):
attestation.aggregation_bitfield.combine(
v.aggregation_bitfield)
attestation.custody_bitfield.combine(v.custody_bitfield)
if not attestation.aggregation_bits.overlaps(
v.aggregation_bits):
attestation.aggregation_bits.combine(
v.aggregation_bits)
attestation.custody_bits.combine(v.custody_bits)
attestation.signature.combine(v.aggregate_signature)
result.add(attestation)

View File

@ -272,7 +272,7 @@ proc updateHead(node: BeaconNode, slot: Slot): BlockRef =
stateRoot = shortLog(root),
connectedPeers = node.network.peersCount,
stateSlot = humaneSlotNum(state.slot),
stateEpoch = humaneEpochNum(state.slot.slotToEpoch)
stateEpoch = humaneEpochNum(state.slot.computeEpochOfSlot)
let
justifiedHead = node.blockPool.latestJustifiedBlock()
@ -287,7 +287,7 @@ proc updateHead(node: BeaconNode, slot: Slot): BlockRef =
lmdGhost(node.attestationPool, state, justifiedHead)
info "Fork chosen",
newHeadSlot = humaneSlotNum(newHead.slot),
newHeadEpoch = humaneEpochNum(newHead.slot.slotToEpoch),
newHeadEpoch = humaneEpochNum(newHead.slot.computeEpochOfSlot),
newHeadBlockRoot = shortLog(newHead.root)
node.blockPool.updateHead(node.stateCache, newHead)
@ -307,9 +307,9 @@ proc sendAttestation(node: BeaconNode,
var attestation = Attestation(
data: attestationData,
signature: validatorSignature,
aggregation_bitfield: aggregationBitfield,
aggregation_bits: aggregationBitfield,
# Stub in phase0
custody_bitfield: BitField.init(committeeLen)
custody_bits: BitField.init(committeeLen)
)
node.network.broadcast(topicAttestations, attestation)
@ -468,7 +468,7 @@ proc handleAttestations(node: BeaconNode, head: BlockRef, slot: Slot) =
# using empty slots as fillers.
node.blockPool.withState(node.stateCache, attestationHead):
var cache = get_empty_per_epoch_cache()
let epoch = slot_to_epoch(slot)
let epoch = compute_epoch_of_slot(slot)
for committee_index in 0'u64 ..< get_epoch_committee_count(state, epoch):
## TODO verify that this is the correct mapping; it's consistent with
## other code

View File

@ -45,8 +45,8 @@ type
#
# #############################################
Validation* = object
aggregation_bitfield*: BitField
custody_bitfield*: BitField ##\
aggregation_bits*: BitField
custody_bits*: BitField ##\
## Phase 1 - the handling of this field is probably broken..
aggregate_signature*: ValidatorSig

View File

@ -107,8 +107,8 @@ proc init*(T: type BlockPool, db: BeaconChainDB): BlockPool =
# will need revisiting however
headState = db.getState(headStateRoot).get()
finalizedHead =
headRef.findAncestorBySlot(headState.finalized_epoch.get_epoch_start_slot())
justifiedSlot = headState.current_justified_epoch.get_epoch_start_slot()
headRef.findAncestorBySlot(headState.finalized_epoch.compute_start_slot_of_epoch())
justifiedSlot = headState.current_justified_epoch.compute_start_slot_of_epoch()
justifiedHead = headRef.findAncestorBySlot(justifiedSlot)
head = Head(blck: headRef, justified: justifiedHead)
@ -163,7 +163,7 @@ proc addResolvedBlock(
# This block *might* have caused a justification - make sure we stow away
# that information:
let justifiedSlot = state.data.data.current_justified_epoch.get_epoch_start_slot()
let justifiedSlot = state.data.data.current_justified_epoch.compute_start_slot_of_epoch()
var foundHead: Option[Head]
for head in pool.heads.mitems():
@ -515,7 +515,7 @@ proc updateHead*(pool: BlockPool, state: var StateData, blck: BlockRef) =
# Start off by making sure we have the right state
updateStateData(pool, state, BlockSlot(blck: blck, slot: blck.slot))
let justifiedSlot = state.data.data.current_justified_epoch.get_epoch_start_slot()
let justifiedSlot = state.data.data.current_justified_epoch.compute_start_slot_of_epoch()
pool.head = Head(blck: blck, justified: blck.findAncestorBySlot(justifiedSlot))
if lastHead.blck != blck.parent:
@ -538,7 +538,7 @@ proc updateHead*(pool: BlockPool, state: var StateData, blck: BlockRef) =
let
# TODO there might not be a block at the epoch boundary - what then?
finalizedHead =
blck.findAncestorBySlot(state.data.data.finalized_epoch.get_epoch_start_slot())
blck.findAncestorBySlot(state.data.data.finalized_epoch.compute_start_slot_of_epoch())
doAssert (not finalizedHead.blck.isNil),
"Block graph should always lead to a finalized block"

View File

@ -25,7 +25,7 @@ proc lmdGhost*(
let
active_validator_indices =
get_active_validator_indices(
start_state, slot_to_epoch(start_state.slot))
start_state, compute_epoch_of_slot(start_state.slot))
var attestation_targets: seq[tuple[validator: ValidatorIndex, blck: BlockRef]]
for i in active_validator_indices:

View File

@ -29,10 +29,10 @@ func verify_merkle_branch(leaf: Eth2Digest, proof: openarray[Eth2Digest], depth:
value = eth2hash(buf)
value == root
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#increase_balance
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#increase_balance
func increase_balance*(
state: var BeaconState, index: ValidatorIndex, delta: Gwei) =
# Increase validator balance by ``delta``.
# Increase the validator balance at index ``index`` by ``delta``.
state.balances[index] += delta
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#decrease_balance
@ -116,10 +116,10 @@ func get_churn_limit(state: BeaconState): uint64 =
CHURN_LIMIT_QUOTIENT
).uint64
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#initiate_validator_exit
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#initiate_validator_exit
func initiate_validator_exit*(state: var BeaconState,
index: ValidatorIndex) =
# Initiate the validator of the given ``index``.
# Initiate the exit of the validator with index ``index``.
# Return if validator already initiated exit
let validator = addr state.validator_registry[index]
@ -145,7 +145,7 @@ func initiate_validator_exit*(state: var BeaconState,
# Set validator exit epoch and withdrawable epoch
validator.exit_epoch = exit_queue_epoch
validator.withdrawable_epoch =
validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY
(validator.exit_epoch + MIN_VALIDATOR_WITHDRAWABILITY_DELAY).Epoch
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#slash_validator
func slash_validator*(state: var BeaconState, slashed_index: ValidatorIndex,
@ -279,7 +279,7 @@ func get_attestation_data_slot*(state: BeaconState,
offset = (data.crosslink.shard + SHARD_COUNT -
get_epoch_start_shard(state, data.target_epoch)) mod SHARD_COUNT
get_epoch_start_slot(data.target_epoch) + offset div
compute_start_slot_of_epoch(data.target_epoch) + offset div
(committee_count div SLOTS_PER_EPOCH)
# This is the slower (O(n)), spec-compatible signature.
@ -288,21 +288,21 @@ func get_attestation_data_slot*(state: BeaconState,
get_attestation_data_slot(
state, data, get_epoch_committee_count(state, data.target_epoch))
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_block_root_at_slot
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_block_root_at_slot
func get_block_root_at_slot*(state: BeaconState,
slot: Slot): Eth2Digest =
# Return the block root at a recent ``slot``.
doAssert state.slot <= slot + SLOTS_PER_HISTORICAL_ROOT
doAssert slot < state.slot
state.latest_block_roots[slot mod SLOTS_PER_HISTORICAL_ROOT]
state.block_roots[slot mod SLOTS_PER_HISTORICAL_ROOT]
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_block_root
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_block_root
func get_block_root*(state: BeaconState, epoch: Epoch): Eth2Digest =
# Return the block root at a recent ``epoch``.
get_block_root_at_slot(state, get_epoch_start_slot(epoch))
# Return the block root at the start of a recent ``epoch``.
get_block_root_at_slot(state, compute_start_slot_of_epoch(epoch))
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_total_balance
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_total_balance
func get_total_balance*(state: BeaconState, validators: auto): Gwei =
## Return the combined effective balance of the ``indices``. (1 Gwei minimum
## to avoid divisions by zero.)
@ -365,7 +365,7 @@ func validate_indexed_attestation*(
# Verify max number of indices
let combined_len = len(bit_0_indices) + len(bit_1_indices)
if not (1 <= combined_len and combined_len <= MAX_INDICES_PER_ATTESTATION):
if not (1 <= combined_len and combined_len <= MAX_VALIDATORS_PER_COMMITTEE):
return false
# Verify index sets are disjoint
@ -430,18 +430,21 @@ func get_attesting_indices_seq*(
toSeq(items(get_attesting_indices(
state, attestation_data, bitfield, cache)))
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#convert_to_indexed
func convert_to_indexed(state: BeaconState, attestation: Attestation,
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_indexed_attestation
func get_indexed_attestation(state: BeaconState, attestation: Attestation,
stateCache: var StateCache): IndexedAttestation =
# Convert ``attestation`` to (almost) indexed-verifiable form.
# Return the indexed attestation corresponding to ``attestation``.
let
attesting_indices =
get_attesting_indices(
state, attestation.data, attestation.aggregation_bitfield, stateCache)
state, attestation.data, attestation.aggregation_bits, stateCache)
custody_bit_1_indices =
get_attesting_indices(
state, attestation.data, attestation.custody_bitfield, stateCache)
state, attestation.data, attestation.custody_bits, stateCache)
doAssert custody_bit_1_indices <= attesting_indices
let
## TODO quadratic, .items, but first-class iterators, etc
## filterIt can't work on HashSets directly because it is
## assuming int-indexable thing to extract type, because,
@ -452,6 +455,8 @@ func convert_to_indexed(state: BeaconState, attestation: Attestation,
## with (non-closure, etc) iterators no other part of Nim
## can access. As such, this function's doing many copies
## and allocations it has no fundamental reason to do.
## TODO phrased in 0.8 as
## custody_bit_0_indices = attesting_indices.difference(custody_bit_1_indices)
custody_bit_0_indices =
filterIt(toSeq(items(attesting_indices)), it notin custody_bit_1_indices)
@ -506,7 +511,7 @@ proc checkAttestation*(
let pending_attestation = PendingAttestation(
data: data,
aggregation_bitfield: attestation.aggregation_bitfield,
aggregation_bits: attestation.aggregation_bits,
inclusion_delay: state.slot - attestation_slot,
proposer_index: get_beacon_proposer_index(state, stateCache),
)
@ -563,7 +568,7 @@ proc checkAttestation*(
# Check signature and bitfields
if not validate_indexed_attestation(
state, convert_to_indexed(state, attestation, stateCache)):
state, get_indexed_attestation(state, attestation, stateCache)):
warn("checkAttestation: signature or bitfields incorrect")
return
@ -577,7 +582,7 @@ proc makeAttestationData*(
## part of committee - notably, it can't be a newer or older state (!)
let
epoch_start_slot = get_epoch_start_slot(slot_to_epoch(state.slot))
epoch_start_slot = compute_start_slot_of_epoch(compute_epoch_of_slot(state.slot))
target_root =
if epoch_start_slot == state.slot: beacon_block_root
else: get_block_root_at_slot(state, epoch_start_slot)
@ -587,10 +592,10 @@ proc makeAttestationData*(
target_root: target_root,
source_epoch: state.current_justified_epoch,
source_root: state.current_justified_root,
target_epoch: slot_to_epoch(state.slot),
target_epoch: compute_epoch_of_slot(state.slot),
crosslink: Crosslink(
# Alternative is to put this offset into all callers
shard: shard + get_epoch_start_shard(state, slot_to_epoch(state.slot)),
shard: shard + get_epoch_start_shard(state, compute_epoch_of_slot(state.slot)),
parent_root: hash_tree_root(state.current_crosslinks[shard]),
data_root: Eth2Digest(), # Stub in phase0
)

View File

@ -64,7 +64,7 @@ const
# ---------------------------------------------------------------
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#initial-values
GENESIS_EPOCH* = (GENESIS_SLOT.uint64 div SLOTS_PER_EPOCH).Epoch ##\
## slot_to_epoch(GENESIS_SLOT)
## compute_epoch_of_slot(GENESIS_SLOT)
ZERO_HASH* = Eth2Digest()
type
@ -72,6 +72,7 @@ type
Shard* = uint64
Gwei* = uint64
Domain* = uint64
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#proposerslashing
ProposerSlashing* = object
@ -105,13 +106,13 @@ type
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#attestation
Attestation* = object
aggregation_bitfield*: BitField ##\
aggregation_bits*: BitField ##\
## Attester aggregation bitfield
data*: AttestationData ##\
## Attestation data
custody_bitfield*: BitField ##\
custody_bits*: BitField ##\
## Custody bitfield
signature*: ValidatorSig ##\
@ -136,13 +137,12 @@ type
data*: AttestationData
custody_bit*: bool
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#deposit
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#deposit
Deposit* = object
proof*: array[DEPOSIT_CONTRACT_TREE_DEPTH, Eth2Digest] ##\
## Branch in the deposit tree
## Merkle path to deposit data list root
data*: DepositData ##\
## Data
data*: DepositData
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#depositdata
DepositData* = object
@ -160,16 +160,15 @@ type
signature*: ValidatorSig ##\
## Container self-signature
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#voluntaryexit
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#voluntaryexit
VoluntaryExit* = object
# Minimum epoch for processing exit
epoch*: Epoch
# Index of the exiting validator
epoch*: Epoch ##\
## Earliest epoch when voluntary exit can be processed
validator_index*: uint64
# Validator signature
signature*: ValidatorSig
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#transfer
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#transfer
Transfer* = object
sender*: uint64 ##\
## Sender index
@ -177,20 +176,21 @@ type
recipient*: uint64 ##\
## Recipient index
# TODO amount and fee are Gwei-typed
amount*: uint64 ##\
## Amount in Gwei
fee*: uint64 ##\
## Fee in Gwei for block proposer
slot*: uint64 ##\
## Inclusion slot
slot*: Slot ##\
## Slot at which transfer must be processed
pubkey*: ValidatorPubKey ##\
## Sender withdrawal pubkey
## Withdrawal pubkey
signature*: ValidatorSig ##\
## Sender signature
## Signature checked against withdrawal pubkey
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#beaconblock
BeaconBlock* = object
@ -213,7 +213,7 @@ type
signature*: ValidatorSig ##\
## Proposer signature
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#beaconblockheader
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#beaconblockheader
BeaconBlockHeader* = object
slot*: Slot
parent_root*: Eth2Digest
@ -263,7 +263,7 @@ type
# Recent state
current_crosslinks*: array[SHARD_COUNT, Crosslink]
previous_crosslinks*: array[SHARD_COUNT, Crosslink]
latest_block_roots*: array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] ##\
block_roots*: array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] ##\
## Needed to process attestations, older to newer
latest_state_roots*: array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
latest_active_index_roots*: array[LATEST_ACTIVE_INDEX_ROOTS_LENGTH, Eth2Digest]
@ -306,35 +306,28 @@ type
effective_balance*: uint64 ##\
## Effective balance
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#crosslink
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#crosslink
Crosslink* = object
shard*: Shard ##\
## Shard number
shard*: Shard
parent_root*: Eth2Digest
start_epoch*: Epoch
end_epoch*: Epoch ##\
## Crosslinking data from epochs [start....end-1]
## Crosslinking data
parent_root*: Eth2Digest ##\
## Root of the previous crosslink
data_root*: Eth2Digest ##\
## Root of the crosslinked shard data since the previous crosslink
data_root*: Eth2Digest
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#pendingattestation
PendingAttestation* = object
aggregation_bitfield*: BitField ## Attester participation bitfield
aggregation_bits*: BitField ## Attester participation bitfield
data*: AttestationData ## Attestation data
inclusion_delay*: uint64 ## Inclusion delay
proposer_index*: ValidatorIndex ## Proposer index
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#historicalbatch
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#historicalbatch
HistoricalBatch* = object
block_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] ##\
## Block roots
state_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest] ##\
## State roots
block_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
state_roots* : array[SLOTS_PER_HISTORICAL_ROOT, Eth2Digest]
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#fork
Fork* = object

View File

@ -9,10 +9,9 @@
import ./datatypes, ./digest, sequtils, math
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#integer_squareroot
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#integer_squareroot
func integer_squareroot*(n: SomeInteger): SomeInteger =
## The largest integer ``x`` such that ``x**2`` is less than or equal to
## ``n``.
# Return the largest integer ``x`` such that ``x**2 <= n``.
doAssert n >= 0'u64
var
@ -58,13 +57,13 @@ func merkle_root*(values: openArray[Eth2Digest]): Eth2Digest =
o[1]
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#slot_to_epoch
func slot_to_epoch*(slot: Slot|uint64): Epoch =
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#compute_epoch_of_slot
func compute_epoch_of_slot*(slot: Slot|uint64): Epoch =
# Return the epoch number of the given ``slot``.
(slot div SLOTS_PER_EPOCH).Epoch
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_epoch_start_slot
func get_epoch_start_slot*(epoch: Epoch): Slot =
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#compute_start_slot_of_epoch
func compute_start_slot_of_epoch*(epoch: Epoch): Slot =
# Return the starting slot of the given ``epoch``.
(epoch * SLOTS_PER_EPOCH).Slot
@ -89,11 +88,11 @@ func get_epoch_committee_count*(state: BeaconState, epoch: Epoch): uint64 =
len(active_validator_indices) div SLOTS_PER_EPOCH div TARGET_COMMITTEE_SIZE,
1, SHARD_COUNT div SLOTS_PER_EPOCH).uint64 * SLOTS_PER_EPOCH
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_current_epoch
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_current_epoch
func get_current_epoch*(state: BeaconState): Epoch =
# Return the current epoch of the given ``state``.
# Return the current epoch.
doAssert state.slot >= GENESIS_SLOT, $state.slot
slot_to_epoch(state.slot)
compute_epoch_of_slot(state.slot)
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_randao_mix
func get_randao_mix*(state: BeaconState,
@ -152,16 +151,16 @@ func int_to_bytes4*(x: uint64): array[4, byte] =
result[3] = ((x shr 24) and 0xff).byte
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#bls_domain
func bls_domain(domain_type: SignatureDomain, fork_version: array[4, byte]):
func compute_domain(domain_type: DomainType, fork_version: array[4, byte]):
uint64 =
var buf: array[8, byte]
buf[0..3] = fork_version
buf[4..7] = int_to_bytes4(domain_type.uint64)
bytes_to_int(buf)
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#get_domain
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#get_domain
func get_domain*(
state: BeaconState, domain_type: SignatureDomain, message_epoch: Epoch): uint64 =
state: BeaconState, domain_type: DomainType, message_epoch: Epoch): Domain =
## Return the signature domain (fork version concatenated with domain type)
## of a message.
let
@ -170,9 +169,9 @@ func get_domain*(
state.fork.previous_version
else:
state.fork.current_version
bls_domain(domain_type, fork_version)
compute_domain(domain_type, fork_version)
func get_domain*(state: BeaconState, domain_type: SignatureDomain): uint64 =
func get_domain*(state: BeaconState, domain_type: DomainType): Domain =
get_domain(state, domain_type, get_current_epoch(state))
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#generate_seed

View File

@ -44,7 +44,7 @@ const
## with a Verifiable Delay Function (VDF) will improve committee robustness
## and lower the safe minimum committee size.)
MAX_INDICES_PER_ATTESTATION* = 2^12 ##\
MAX_VALIDATORS_PER_COMMITTEE* = 2^12 ##\
## votes
MIN_PER_EPOCH_CHURN_LIMIT* = 4
@ -66,7 +66,7 @@ const
# Gwei values
# ---------------------------------------------------------------
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#gwei-values
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#gwei-values
MIN_DEPOSIT_AMOUNT* = 2'u64^0 * 10'u64^9 ##\
## Minimum amounth of ETH that can be deposited in one call - deposits can
@ -169,7 +169,7 @@ type
# Signature domains
# ---------------------------------------------------------------
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#signature-domains
SignatureDomain* {.pure.} = enum
DomainType* {.pure.} = enum
DOMAIN_BEACON_PROPOSER = 0
DOMAIN_RANDAO = 1
DOMAIN_ATTESTATION = 2

View File

@ -33,7 +33,7 @@ const
TARGET_COMMITTEE_SIZE* = 4
# Unchanged
MAX_INDICES_PER_ATTESTATION* = 4096
MAX_VALIDATORS_PER_COMMITTEE* = 4096
MIN_PER_EPOCH_CHURN_LIMIT* = 4
CHURN_LIMIT_QUOTIENT* = 2^16
BASE_REWARDS_PER_EPOCH* = 5
@ -75,9 +75,9 @@ const
# Unchanged
SECONDS_PER_SLOT*{.intdefine.} = 6'u64
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#time-parameters
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#time-parameters
# Unchanged
MIN_ATTESTATION_INCLUSION_DELAY* = 2'u64^2
MIN_ATTESTATION_INCLUSION_DELAY* = 2'u64^0
# Changed
SLOTS_PER_EPOCH* {.intdefine.} = 64
@ -132,7 +132,7 @@ type
# Signature domains
# ---------------------------------------------------------------
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#signature-domains
SignatureDomain* {.pure.} = enum
DomainType* {.pure.} = enum
DOMAIN_BEACON_PROPOSER = 0
DOMAIN_RANDAO = 1
DOMAIN_ATTESTATION = 2

View File

@ -117,7 +117,7 @@ proc processRandao(
true
# https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_beacon-chain.md#eth1-data
# https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_beacon-chain.md#eth1-data
func processEth1Data(state: var BeaconState, body: BeaconBlockBody) =
state.eth1_data_votes.add body.eth1_data
if state.eth1_data_votes.count(body.eth1_data) * 2 >
@ -144,8 +144,8 @@ proc processProposerSlashings(
let proposer = state.validator_registry[proposer_slashing.proposer_index.int]
# Verify that the epoch is the same
if not (slot_to_epoch(proposer_slashing.header_1.slot) ==
slot_to_epoch(proposer_slashing.header_2.slot)):
if not (compute_epoch_of_slot(proposer_slashing.header_1.slot) ==
compute_epoch_of_slot(proposer_slashing.header_2.slot)):
notice "PropSlash: epoch mismatch"
return false
@ -167,7 +167,7 @@ proc processProposerSlashings(
signing_root(header).data,
header.signature,
get_domain(
state, DOMAIN_BEACON_PROPOSER, slot_to_epoch(header.slot))):
state, DOMAIN_BEACON_PROPOSER, compute_epoch_of_slot(header.slot))):
notice "PropSlash: invalid signature",
signature_index = i
return false
@ -269,7 +269,7 @@ proc processAttestations(
get_attestation_data_slot(state, attestation.data, committee_count)
let pending_attestation = PendingAttestation(
data: attestation.data,
aggregation_bitfield: attestation.aggregation_bitfield,
aggregation_bits: attestation.aggregation_bits,
inclusion_delay: state.slot - attestation_slot,
proposer_index: get_beacon_proposer_index(state, stateCache),
)

View File

@ -72,7 +72,7 @@ func get_unslashed_attesting_indices(
result = initSet[ValidatorIndex]()
for a in attestations:
result = result.union(get_attesting_indices(
state, a.data, a.aggregation_bitfield, stateCache))
state, a.data, a.aggregation_bits, stateCache))
for index in result:
if state.validator_registry[index].slashed:
@ -291,7 +291,7 @@ func get_attestation_deltas(state: BeaconState, stateCache: var StateCache):
var attestation = matching_source_attestations[0]
for a in matching_source_attestations:
if index notin get_attesting_indices(
state, a.data, a.aggregation_bitfield, stateCache):
state, a.data, a.aggregation_bits, stateCache):
continue
if a.inclusion_delay < attestation.inclusion_delay:
attestation = a
@ -421,7 +421,7 @@ func process_final_updates(state: var BeaconState) =
# Set historical root accumulator
if next_epoch mod (SLOTS_PER_HISTORICAL_ROOT div SLOTS_PER_EPOCH).uint64 == 0:
let historical_batch = HistoricalBatch(
block_roots: state.latest_block_roots,
block_roots: state.block_roots,
state_roots: state.latest_state_roots,
)
state.historical_roots.add (hash_tree_root(historical_batch))

View File

@ -57,7 +57,7 @@ func process_slot(state: var BeaconState) =
state.latest_block_header.state_root = previous_state_root
# Cache block root
state.latest_block_roots[state.slot mod SLOTS_PER_HISTORICAL_ROOT] =
state.block_roots[state.slot mod SLOTS_PER_HISTORICAL_ROOT] =
signing_root(state.latest_block_header)
# https://github.com/ethereum/eth2.0-specs/blob/v0.6.3/specs/core/0_beacon-chain.md#state-root-verification
@ -179,7 +179,7 @@ func process_slot(state: var HashedBeaconState) =
state.data.latest_block_header.state_root = previous_slot_state_root
# Cache block root
state.data.latest_block_roots[state.data.slot mod SLOTS_PER_HISTORICAL_ROOT] =
state.data.block_roots[state.data.slot mod SLOTS_PER_HISTORICAL_ROOT] =
signing_root(state.data.latest_block_header)
# Not covered by above 0.7 marking

View File

@ -81,7 +81,7 @@ p2pProtocol BeaconSync(version = 1,
headBlock = blockPool.head.blck
bestRoot = headBlock.root
bestSlot = headBlock.slot
latestFinalizedEpoch = finalizedHead.slot.slot_to_epoch()
latestFinalizedEpoch = finalizedHead.slot.compute_epoch_of_slot()
let m = await peer.hello(networkId, chainId, finalizedHead.blck.root,
latestFinalizedEpoch, bestRoot, bestSlot,

View File

@ -14,7 +14,7 @@ type
## which blocks are valid - in particular, blocks are not valid if they
## come from the future as seen from the local clock.
##
## https://github.com/ethereum/eth2.0-specs/blob/v0.7.1/specs/core/0_fork-choice.md#beacon-chain-processing
## https://github.com/ethereum/eth2.0-specs/blob/v0.8.0/specs/core/0_fork-choice.md#fork-choice
##
# TODO replace time in chronos with a proper unit type, then this code can
# follow:

View File

@ -30,7 +30,7 @@ proc signBlockProposal*(v: AttachedValidator, state: BeaconState, slot: Slot,
if v.kind == inProcess:
await sleepAsync(chronos.milliseconds(1))
result = bls_sign(v.privKey, blockRoot.data,
get_domain(state, DOMAIN_BEACON_PROPOSER, slot_to_epoch(slot)))
get_domain(state, DOMAIN_BEACON_PROPOSER, compute_epoch_of_slot(slot)))
else:
# TODO:
# send RPC
@ -59,8 +59,8 @@ func genRandaoReveal*(k: ValidatorPrivKey, state: BeaconState, slot: Slot):
# Off-by-one? I often get slot == state.slot but the check was "doAssert slot > state.slot" (Mamy)
doAssert slot >= state.slot, "input slot: " & $humaneSlotNum(slot) & " - beacon state slot: " & $humaneSlotNum(state.slot)
bls_sign(k, hash_tree_root(slot_to_epoch(slot).uint64).data,
get_domain(state, DOMAIN_RANDAO, slot_to_epoch(slot)))
bls_sign(k, hash_tree_root(compute_epoch_of_slot(slot).uint64).data,
get_domain(state, DOMAIN_RANDAO, compute_epoch_of_slot(slot)))
func genRandaoReveal*(v: AttachedValidator, state: BeaconState, slot: Slot):
ValidatorSig =

View File

@ -23,7 +23,7 @@ proc stateSize(deposits: int, maxContent = false) =
# validatorsPerCommittee =
# len(crosslink_committees[0].committee) # close enough..
# for a in state.latest_attestations.mitems():
# a.aggregation_bitfield = BitField.init(validatorsPerCommittee)
# a.aggregation_bits = BitField.init(validatorsPerCommittee)
echo "Validators: ", deposits, ", total: ", SSZ.encode(state).len
dispatch(stateSize)

View File

@ -101,7 +101,7 @@ cli do(slots = 448,
# work for every slot - we'll randomize it deterministically to give
# some variation
let
epoch = slot_to_epoch(state.slot)
epoch = compute_epoch_of_slot(state.slot)
scass = withTimerRet(timers[tShuffle]):
mapIt(
0'u64 .. (get_epoch_committee_count(state, epoch) - 1),
@ -148,7 +148,7 @@ cli do(slots = 448,
if (state.slot) mod SLOTS_PER_EPOCH == 0:
echo &" slot: {humaneSlotNum(state.slot)} ",
&"epoch: {humaneEpochNum(state.slot.slot_to_epoch)}"
&"epoch: {humaneEpochNum(state.slot.compute_epoch_of_slot)}"
maybeWrite() # catch that last state as well..

View File

@ -20,7 +20,7 @@ type
SHARD_COUNT*: int
TARGET_COMMITTEE_SIZE*: int
MAX_BALANCE_CHURN_QUOTIENT*: int
MAX_INDICES_PER_ATTESTATION*: int
MAX_VALIDATORS_PER_COMMITTEE*: int
MIN_PER_EPOCH_CHURN_LIMIT*: int
SHUFFLE_ROUND_COUNT*: int
DEPOSIT_CONTRACT_TREE_DEPTH*: int
@ -56,12 +56,12 @@ type
MAX_DEPOSITS*: int
MAX_VOLUNTARY_EXITS*: int
MAX_TRANSFERS*: int
DOMAIN_BEACON_PROPOSER*: SignatureDomain
DOMAIN_RANDAO*: SignatureDomain
DOMAIN_ATTESTATION*: SignatureDomain
DOMAIN_DEPOSIT*: SignatureDomain
DOMAIN_VOLUNTARY_EXIT*: SignatureDomain
DOMAIN_TRANSFER*: SignatureDomain
DOMAIN_BEACON_PROPOSER*: DomainType
DOMAIN_RANDAO*: DomainType
DOMAIN_ATTESTATION*: DomainType
DOMAIN_DEPOSIT*: DomainType
DOMAIN_VOLUNTARY_EXIT*: DomainType
DOMAIN_TRANSFER*: DomainType
Tests*[T] = object
title*: string

View File

@ -40,7 +40,7 @@ suite "Attestation pool processing" & preset():
let
# Create an attestation for slot 1!
crosslink_committee = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 1, cache)
compute_epoch_of_slot(state.data.data.slot), 1, cache)
attestation = makeAttestation(
state.data.data, state.blck.root, crosslink_committee[0])
@ -61,7 +61,7 @@ suite "Attestation pool processing" & preset():
let
# Create an attestation for slot 1!
cc0 = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 1, cache)
compute_epoch_of_slot(state.data.data.slot), 1, cache)
attestation0 = makeAttestation(
state.data.data, state.blck.root, cc0[0])
@ -69,7 +69,7 @@ suite "Attestation pool processing" & preset():
let
cc1 = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 2, cache)
compute_epoch_of_slot(state.data.data.slot), 2, cache)
attestation1 = makeAttestation(
state.data.data, state.blck.root, cc1[0])
@ -92,7 +92,7 @@ suite "Attestation pool processing" & preset():
let
# Create an attestation for slot 1!
cc0 = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 1, cache)
compute_epoch_of_slot(state.data.data.slot), 1, cache)
attestation0 = makeAttestation(
state.data.data, state.blck.root, cc0[0])
attestation1 = makeAttestation(
@ -116,7 +116,7 @@ suite "Attestation pool processing" & preset():
var
# Create an attestation for slot 1!
cc0 = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 1, cache)
compute_epoch_of_slot(state.data.data.slot), 1, cache)
attestation0 = makeAttestation(
state.data.data, state.blck.root, cc0[0])
attestation1 = makeAttestation(
@ -141,7 +141,7 @@ suite "Attestation pool processing" & preset():
var
# Create an attestation for slot 1!
cc0 = get_crosslink_committee(state.data.data,
slot_to_epoch(state.data.data.slot), 1, cache)
compute_epoch_of_slot(state.data.data.slot), 1, cache)
attestation0 = makeAttestation(
state.data.data, state.blck.root, cc0[0])
attestation1 = makeAttestation(

View File

@ -84,7 +84,7 @@ suite "Block processing" & preset():
let
# Create an attestation for slot 1 signed by the only attester we have!
crosslink_committee =
get_crosslink_committee(state, slot_to_epoch(state.slot), 0, cache)
get_crosslink_committee(state, compute_epoch_of_slot(state.slot), 0, cache)
attestation = makeAttestation(
state, previous_block_root, crosslink_committee[0])

View File

@ -121,12 +121,12 @@ proc addBlock*(
# We have a signature - put it in the block and we should be done!
new_block.signature =
bls_sign(proposerPrivkey, block_root.data,
get_domain(state, DOMAIN_BEACON_PROPOSER, slot_to_epoch(new_block.slot)))
get_domain(state, DOMAIN_BEACON_PROPOSER, compute_epoch_of_slot(new_block.slot)))
doAssert bls_verify(
proposer.pubkey,
block_root.data, new_block.signature,
get_domain(state, DOMAIN_BEACON_PROPOSER, slot_to_epoch(new_block.slot))),
get_domain(state, DOMAIN_BEACON_PROPOSER, compute_epoch_of_slot(new_block.slot))),
"we just signed this message - it should pass verification!"
new_block
@ -143,7 +143,7 @@ proc makeBlock*(
proc find_shard_committee(
state: BeaconState, validator_index: ValidatorIndex): auto =
let epoch = slot_to_epoch(state.slot)
let epoch = compute_epoch_of_slot(state.slot)
var cache = get_empty_per_epoch_cache()
for shard in 0'u64 ..< get_epoch_committee_count(state, epoch):
let committee = get_crosslink_committee(state, epoch,
@ -164,8 +164,8 @@ proc makeAttestation*(
doAssert sac_index != -1, "find_shard_committee should guarantee this"
var
aggregation_bitfield = BitField.init(committee.len)
set_bitfield_bit(aggregation_bitfield, sac_index)
aggregation_bits = BitField.init(committee.len)
set_bitfield_bit(aggregation_bits, sac_index)
let
msg = hash_tree_root(
@ -177,15 +177,15 @@ proc makeAttestation*(
get_domain(
state,
DOMAIN_ATTESTATION,
slot_to_epoch(state.slot)))
compute_epoch_of_slot(state.slot)))
else:
ValidatorSig()
Attestation(
data: data,
aggregation_bitfield: aggregation_bitfield,
aggregation_bits: aggregation_bits,
signature: sig,
custody_bitfield: BitField.init(committee.len)
custody_bits: BitField.init(committee.len)
)
proc makeTestDB*(tailState: BeaconState, tailBlock: BeaconBlock): BeaconChainDB =