Mostly convert to using distinct Slot type (#172)
This commit is contained in:
parent
6dea18c140
commit
50a0948bc0
|
@ -161,13 +161,13 @@ proc slotIndex(
|
|||
attestationSlot = $humaneSlotNum(attestationSlot)
|
||||
pool.startingSlot = state.finalized_epoch.get_epoch_start_slot()
|
||||
|
||||
if pool.startingSlot + pool.slots.len.Slot <= attestationSlot:
|
||||
if pool.startingSlot + pool.slots.len.uint64 <= attestationSlot:
|
||||
debug "Growing attestation pool",
|
||||
attestationSlot = $humaneSlotNum(attestationSlot),
|
||||
startingSlot = $humaneSlotNum(pool.startingSlot)
|
||||
|
||||
# Make sure there's a pool entry for every slot, even when there's a gap
|
||||
while pool.startingSlot + pool.slots.len.Slot <= attestationSlot:
|
||||
while pool.startingSlot + pool.slots.len.uint64 <= attestationSlot:
|
||||
pool.slots.addLast(SlotData())
|
||||
|
||||
if pool.startingSlot < state.finalized_epoch.get_epoch_start_slot():
|
||||
|
@ -193,7 +193,7 @@ proc add*(pool: var AttestationPool,
|
|||
|
||||
let
|
||||
attestationSlot = attestation.data.slot
|
||||
idx = pool.slotIndex(state, attestationSlot)
|
||||
idx = pool.slotIndex(state, attestationSlot.Slot)
|
||||
slotData = addr pool.slots[idx]
|
||||
validation = Validation(
|
||||
aggregation_bitfield: attestation.aggregation_bitfield,
|
||||
|
@ -279,11 +279,11 @@ proc getAttestationsForBlock*(pool: AttestationPool,
|
|||
attestationSlot = newBlockSlot - MIN_ATTESTATION_INCLUSION_DELAY
|
||||
|
||||
if attestationSlot < pool.startingSlot or
|
||||
attestationSlot >= pool.startingSlot + pool.slots.len.Slot:
|
||||
attestationSlot >= pool.startingSlot + pool.slots.len.uint64:
|
||||
info "No attestations",
|
||||
attestationSlot = humaneSlotNum(attestationSlot),
|
||||
startingSlot = humaneSlotNum(pool.startingSlot),
|
||||
endingSlot = humaneSlotNum(pool.startingSlot + pool.slots.len.Slot)
|
||||
endingSlot = humaneSlotNum(pool.startingSlot + pool.slots.len.uint64)
|
||||
|
||||
return
|
||||
|
||||
|
|
|
@ -308,7 +308,7 @@ proc proposeBlock(node: BeaconNode,
|
|||
newBlock.state_root = Eth2Digest(data: hash_tree_root(state))
|
||||
|
||||
let proposal = Proposal(
|
||||
slot: slot,
|
||||
slot: slot.uint64,
|
||||
shard: BEACON_CHAIN_SHARD_NUMBER,
|
||||
block_root: Eth2Digest(data: signed_root(newBlock, "signature")),
|
||||
signature: ValidatorSig(),
|
||||
|
@ -441,7 +441,7 @@ proc scheduleEpochActions(node: BeaconNode, epoch: Epoch) =
|
|||
let start = if epoch == GENESIS_EPOCH: 1.uint64 else: 0.uint64
|
||||
|
||||
for i in start ..< SLOTS_PER_EPOCH:
|
||||
let slot = epoch * SLOTS_PER_EPOCH + i
|
||||
let slot = (epoch * SLOTS_PER_EPOCH + i).Slot
|
||||
nextState.slot = slot # ugly trick, see get_beacon_proposer_index
|
||||
|
||||
block: # Schedule block proposals
|
||||
|
|
|
@ -54,7 +54,7 @@ proc init*(T: type BlockPool, db: BeaconChainDB): BlockPool =
|
|||
var blocksBySlot = initTable[uint64, seq[BlockRef]]()
|
||||
for _, b in tables.pairs(blocks):
|
||||
let slot = db.getBlock(b.root).get().slot
|
||||
blocksBySlot.mgetOrPut(slot, @[]).add(b)
|
||||
blocksBySlot.mgetOrPut(slot.uint64, @[]).add(b)
|
||||
|
||||
BlockPool(
|
||||
pending: initTable[Eth2Digest, BeaconBlock](),
|
||||
|
@ -146,7 +146,7 @@ proc add*(
|
|||
|
||||
pool.blocks[blockRoot] = blockRef
|
||||
|
||||
pool.addSlotMapping(blck.slot, blockRef)
|
||||
pool.addSlotMapping(blck.slot.uint64, blockRef)
|
||||
|
||||
# Resolved blocks should be stored in database
|
||||
pool.db.putBlock(blockRoot, blck)
|
||||
|
@ -229,8 +229,8 @@ proc getOrResolve*(pool: var BlockPool, root: Eth2Digest): BlockRef =
|
|||
if result.isNil:
|
||||
pool.unresolved[root] = UnresolvedBlock()
|
||||
|
||||
iterator blockRootsForSlot*(pool: BlockPool, slot: uint64): Eth2Digest =
|
||||
for br in pool.blocksBySlot.getOrDefault(slot, @[]):
|
||||
iterator blockRootsForSlot*(pool: BlockPool, slot: uint64|Slot): Eth2Digest =
|
||||
for br in pool.blocksBySlot.getOrDefault(slot.uint64, @[]):
|
||||
yield br.root
|
||||
|
||||
proc checkUnresolved*(pool: var BlockPool): seq[Eth2Digest] =
|
||||
|
|
|
@ -280,7 +280,7 @@ func get_attestation_participants*(state: BeaconState,
|
|||
## Return the participant indices at for the ``attestation_data`` and
|
||||
## ``bitfield``.
|
||||
let crosslink_committees = get_crosslink_committees_at_slot(
|
||||
state, attestation_data.slot)
|
||||
state, attestation_data.slot.Slot)
|
||||
doAssert anyIt(
|
||||
crosslink_committees,
|
||||
it[1] == attestation_data.shard)
|
||||
|
@ -367,6 +367,8 @@ proc checkAttestation*(
|
|||
## at the current slot. When acting as a proposer, the same rules need to
|
||||
## be followed!
|
||||
|
||||
let attestation_data_slot = attestation.data.slot.Slot
|
||||
|
||||
if not (attestation.data.slot >= GENESIS_SLOT):
|
||||
warn("Attestation predates genesis slot",
|
||||
attestation_slot = attestation.data.slot,
|
||||
|
@ -386,7 +388,7 @@ proc checkAttestation*(
|
|||
return
|
||||
|
||||
let expected_justified_epoch =
|
||||
if slot_to_epoch(attestation.data.slot + 1) >= get_current_epoch(state):
|
||||
if slot_to_epoch(attestation.data.slot.Slot + 1) >= get_current_epoch(state):
|
||||
state.justified_epoch
|
||||
else:
|
||||
state.previous_justified_epoch
|
||||
|
@ -410,12 +412,12 @@ proc checkAttestation*(
|
|||
attestation.data.latest_crosslink,
|
||||
Crosslink(
|
||||
crosslink_data_root: attestation.data.crosslink_data_root,
|
||||
epoch: slot_to_epoch(attestation.data.slot))]):
|
||||
epoch: slot_to_epoch(attestation_data_slot))]):
|
||||
warn("Unexpected crosslink shard",
|
||||
state_latest_crosslinks_attestation_data_shard =
|
||||
state.latest_crosslinks[attestation.data.shard],
|
||||
attestation_data_latest_crosslink = attestation.data.latest_crosslink,
|
||||
epoch = humaneEpochNum(slot_to_epoch(attestation.data.slot)),
|
||||
epoch = humaneEpochNum(slot_to_epoch(attestation_data_slot)),
|
||||
crosslink_data_root = attestation.data.crosslink_data_root)
|
||||
return
|
||||
|
||||
|
@ -423,7 +425,7 @@ proc checkAttestation*(
|
|||
assert anyIt(attestation.aggregation_bitfield, it != 0)
|
||||
|
||||
let crosslink_committee = mapIt(
|
||||
filterIt(get_crosslink_committees_at_slot(state, attestation.data.slot),
|
||||
filterIt(get_crosslink_committees_at_slot(state, attestation_data_slot),
|
||||
it.shard == attestation.data.shard),
|
||||
it.committee)[0]
|
||||
|
||||
|
@ -475,7 +477,7 @@ proc checkAttestation*(
|
|||
data: attestation.data, custody_bit: true)),
|
||||
],
|
||||
attestation.aggregate_signature,
|
||||
get_domain(state.fork, slot_to_epoch(attestation.data.slot),
|
||||
get_domain(state.fork, slot_to_epoch(attestation.data.slot.Slot),
|
||||
DOMAIN_ATTESTATION),
|
||||
)
|
||||
|
||||
|
@ -513,7 +515,7 @@ proc makeAttestationData*(
|
|||
justified_block_root = get_block_root(state, justified_slot)
|
||||
|
||||
AttestationData(
|
||||
slot: state.slot,
|
||||
slot: state.slot.uint64,
|
||||
shard: shard,
|
||||
beacon_block_root: beacon_block_root,
|
||||
epoch_boundary_root: epoch_boundary_root,
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
# types / composition
|
||||
|
||||
import
|
||||
eth/common, math,
|
||||
eth/common, hashes, math,
|
||||
./crypto, ./digest
|
||||
|
||||
# TODO Data types:
|
||||
|
@ -39,6 +39,11 @@ import
|
|||
|
||||
# TODO Many of these constants should go into a config object that can be used
|
||||
# to run.. well.. a chain with different constants!
|
||||
|
||||
type
|
||||
Slot* = distinct uint64
|
||||
Epoch* = uint64
|
||||
|
||||
const
|
||||
SPEC_VERSION* = "0.4.0" ## \
|
||||
## Spec version we're aiming to be compatible with, right now
|
||||
|
@ -103,8 +108,9 @@ const
|
|||
# Initial values
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#initial-values
|
||||
GENESIS_FORK_VERSION* = 0'u64
|
||||
GENESIS_SLOT* = 2'u64^32
|
||||
GENESIS_EPOCH* = GENESIS_SLOT div SLOTS_PER_EPOCH # slot_to_epoch(GENESIS_SLOT)
|
||||
GENESIS_SLOT* = (2'u64^32).Slot
|
||||
GENESIS_EPOCH* = (GENESIS_SLOT.uint64 div SLOTS_PER_EPOCH).Epoch ##\
|
||||
## slot_to_epoch(GENESIS_SLOT)
|
||||
GENESIS_START_SHARD* = 0'u64
|
||||
FAR_FUTURE_EPOCH* = not 0'u64 # 2^64 - 1 in spec
|
||||
ZERO_HASH* = Eth2Digest()
|
||||
|
@ -172,12 +178,6 @@ const
|
|||
type
|
||||
ValidatorIndex* = range[0'u32 .. 0xFFFFFF'u32] # TODO: wrap-around
|
||||
|
||||
## In principle, these would be better as distinct types. That's a good
|
||||
## TODO eventually, but Danny has confirmed that the SSZ types will use
|
||||
## primitive (uint64, etc) types and helper functions annotated ones so
|
||||
## it would just create pointless casts for now.
|
||||
Slot* = uint64
|
||||
Epoch* = uint64
|
||||
Gwei* = uint64
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#proposerslashing
|
||||
|
@ -246,7 +246,7 @@ type
|
|||
latest_crosslink*: Crosslink ##\
|
||||
## Last crosslink
|
||||
|
||||
justified_epoch*: uint64 ##\
|
||||
justified_epoch*: Epoch ##\
|
||||
## Last justified epoch in the beacon state
|
||||
|
||||
justified_block_root*: Eth2Digest ##\
|
||||
|
@ -284,7 +284,7 @@ type
|
|||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#voluntaryexit
|
||||
VoluntaryExit* = object
|
||||
# Minimum epoch for processing exit
|
||||
epoch*: uint64
|
||||
epoch*: Epoch
|
||||
# Index of the exiting validator
|
||||
validator_index*: uint64
|
||||
# Validator signature
|
||||
|
@ -321,12 +321,12 @@ type
|
|||
## Each block collects attestations, or votes, on past blocks, thus a chain
|
||||
## is formed.
|
||||
|
||||
slot*: uint64
|
||||
slot*: Slot
|
||||
parent_root*: Eth2Digest ##\
|
||||
##\ Root hash of the previous block
|
||||
|
||||
state_root*: Eth2Digest ##\
|
||||
##\ The state root, _after_ this block has been processed
|
||||
## The state root, _after_ this block has been processed
|
||||
|
||||
randao_reveal*: ValidatorSig ##\
|
||||
## Proposer RANDAO reveal
|
||||
|
@ -375,7 +375,7 @@ type
|
|||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#beaconstate
|
||||
BeaconState* = object
|
||||
slot*: uint64
|
||||
slot*: Slot
|
||||
genesis_time*: uint64
|
||||
fork*: Fork ##\
|
||||
## For versioning hard forks
|
||||
|
@ -385,7 +385,7 @@ type
|
|||
validator_balances*: seq[uint64] ##\
|
||||
## Validator balances in Gwei!
|
||||
|
||||
validator_registry_update_epoch*: uint64
|
||||
validator_registry_update_epoch*: Epoch
|
||||
|
||||
# TODO remove or conditionally compile; not in spec anymore
|
||||
validator_registry_delta_chain_tip*: Eth2Digest ##\
|
||||
|
@ -395,16 +395,16 @@ type
|
|||
latest_randao_mixes*: array[LATEST_BLOCK_ROOTS_LENGTH.int, Eth2Digest]
|
||||
previous_shuffling_start_shard*: uint64
|
||||
current_shuffling_start_shard*: uint64
|
||||
previous_shuffling_epoch*: uint64
|
||||
current_shuffling_epoch*: uint64
|
||||
previous_shuffling_epoch*: Epoch
|
||||
current_shuffling_epoch*: Epoch
|
||||
previous_shuffling_seed*: Eth2Digest
|
||||
current_shuffling_seed*: Eth2Digest
|
||||
|
||||
# Finality
|
||||
previous_justified_epoch*: uint64
|
||||
justified_epoch*: uint64
|
||||
previous_justified_epoch*: Epoch
|
||||
justified_epoch*: Epoch
|
||||
justification_bitfield*: uint64
|
||||
finalized_epoch*: uint64
|
||||
finalized_epoch*: Epoch
|
||||
|
||||
# Recent state
|
||||
latest_crosslinks*: array[SHARD_COUNT, Crosslink]
|
||||
|
@ -434,13 +434,13 @@ type
|
|||
withdrawal_credentials*: Eth2Digest ##\
|
||||
## Withdrawal credentials
|
||||
|
||||
activation_epoch*: uint64 ##\
|
||||
activation_epoch*: Epoch ##\
|
||||
## Epoch when validator activated
|
||||
|
||||
exit_epoch*: uint64 ##\
|
||||
exit_epoch*: Epoch ##\
|
||||
## Epoch when validator exited
|
||||
|
||||
withdrawable_epoch*: uint64 ##\
|
||||
withdrawable_epoch*: Epoch ##\
|
||||
## Epoch when validator is eligible to withdraw
|
||||
|
||||
initiated_exit*: bool ##\
|
||||
|
@ -451,7 +451,7 @@ type
|
|||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#crosslink
|
||||
Crosslink* = object
|
||||
epoch*: uint64 ##\
|
||||
epoch*: Epoch ##\
|
||||
## Epoch number
|
||||
|
||||
crosslink_data_root*: Eth2Digest ##\
|
||||
|
@ -462,13 +462,13 @@ type
|
|||
aggregation_bitfield*: seq[byte] # Attester participation bitfield
|
||||
data*: AttestationData # Attestation data
|
||||
custody_bitfield*: seq[byte] # Custody bitfield
|
||||
inclusion_slot*: uint64 # Inclusion slot
|
||||
inclusion_slot*: Slot # Inclusion slot
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#fork
|
||||
Fork* = object
|
||||
previous_version*: uint64 # Previous fork version
|
||||
current_version*: uint64 # Current fork version
|
||||
epoch*: uint64 # Fork epoch number
|
||||
epoch*: Epoch # Fork epoch number
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#eth1data
|
||||
Eth1Data* = object
|
||||
|
@ -522,8 +522,39 @@ type
|
|||
func shortValidatorKey*(state: BeaconState, validatorIdx: int): string =
|
||||
($state.validator_registry[validatorIdx].pubkey)[0..7]
|
||||
|
||||
func humaneSlotNum*(s: Slot): Slot =
|
||||
s - GENESIS_SLOT
|
||||
template ethTimeUnit(typ: type) =
|
||||
proc `+`*(x: typ, y: uint64): typ {.borrow.}
|
||||
proc `-`*(x: typ, y: uint64): typ {.borrow.}
|
||||
proc `-`*(x: uint64, y: typ): typ {.borrow.}
|
||||
|
||||
proc `+=`*(x: var typ, y: uint64) {.borrow.}
|
||||
proc `-=`*(x: var typ, y: uint64) {.borrow.}
|
||||
|
||||
# Not closed over type in question (Slot or Epoch)
|
||||
proc `mod`*(x: typ, y: uint64): uint64 {.borrow.}
|
||||
proc `div`*(x: typ, y: uint64): uint64 {.borrow.}
|
||||
proc `div`*(x: uint64, y: typ): uint64 {.borrow.}
|
||||
proc `-`*(x: typ, y: typ): uint64 {.borrow.}
|
||||
|
||||
# Comparison operators
|
||||
proc `<`*(x: typ, y: typ): bool {.borrow.}
|
||||
proc `<`*(x: typ, y: uint64): bool {.borrow.}
|
||||
proc `<`*(x: uint64, y: typ): bool {.borrow.}
|
||||
proc `<=`*(x: typ, y: typ): bool {.borrow.}
|
||||
proc `<=`*(x: typ, y: uint64): bool {.borrow.}
|
||||
proc `<=`*(x: uint64, y: typ): bool {.borrow.}
|
||||
proc `==`*(x: typ, y: typ): bool {.borrow.}
|
||||
proc `==`*(x: typ, y: uint64): bool {.borrow.}
|
||||
|
||||
# Nim integration
|
||||
proc `$`*(x: typ): string {.borrow.}
|
||||
proc hash*(x: typ): Hash {.borrow.}
|
||||
|
||||
ethTimeUnit(Slot)
|
||||
#ethTimeUnit(Epoch)
|
||||
|
||||
func humaneSlotNum*(s: auto): uint64 =
|
||||
s.Slot - GENESIS_SLOT
|
||||
|
||||
func humaneEpochNum*(e: Epoch): Epoch =
|
||||
e - GENESIS_EPOCH
|
||||
|
|
|
@ -120,13 +120,13 @@ func merkle_root*(values: openArray[Eth2Digest]): Eth2Digest =
|
|||
o[1]
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#slot_to_epoch
|
||||
func slot_to_epoch*(slot: Slot): Epoch =
|
||||
slot div SLOTS_PER_EPOCH
|
||||
func slot_to_epoch*(slot: Slot|uint64): Epoch =
|
||||
(slot div SLOTS_PER_EPOCH).Epoch
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_epoch_start_slot
|
||||
func get_epoch_start_slot*(epoch: Epoch): Slot =
|
||||
# Return the starting slot of the given ``epoch``.
|
||||
epoch * SLOTS_PER_EPOCH
|
||||
(epoch * SLOTS_PER_EPOCH).Slot
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#is_double_vote
|
||||
func is_double_vote*(attestation_data_1: AttestationData,
|
||||
|
@ -134,8 +134,9 @@ func is_double_vote*(attestation_data_1: AttestationData,
|
|||
## Check if ``attestation_data_1`` and ``attestation_data_2`` have the same
|
||||
## target.
|
||||
let
|
||||
target_epoch_1 = slot_to_epoch(attestation_data_1.slot)
|
||||
target_epoch_2 = slot_to_epoch(attestation_data_2.slot)
|
||||
# RLP artifact
|
||||
target_epoch_1 = slot_to_epoch(attestation_data_1.slot.Slot)
|
||||
target_epoch_2 = slot_to_epoch(attestation_data_2.slot.Slot)
|
||||
target_epoch_1 == target_epoch_2
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#is_surround_vote
|
||||
|
@ -145,8 +146,9 @@ func is_surround_vote*(attestation_data_1: AttestationData,
|
|||
let
|
||||
source_epoch_1 = attestation_data_1.justified_epoch
|
||||
source_epoch_2 = attestation_data_2.justified_epoch
|
||||
target_epoch_1 = slot_to_epoch(attestation_data_1.slot)
|
||||
target_epoch_2 = slot_to_epoch(attestation_data_2.slot)
|
||||
# RLP artifact
|
||||
target_epoch_1 = slot_to_epoch(attestation_data_1.slot.Slot)
|
||||
target_epoch_2 = slot_to_epoch(attestation_data_2.slot.Slot)
|
||||
|
||||
source_epoch_1 < source_epoch_2 and target_epoch_2 < target_epoch_1
|
||||
|
||||
|
|
|
@ -126,7 +126,7 @@ func get_previous_epoch*(state: BeaconState): Epoch =
|
|||
max(get_current_epoch(state) - 1, GENESIS_EPOCH)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#get_crosslink_committees_at_slot
|
||||
func get_crosslink_committees_at_slot*(state: BeaconState, slot: Slot,
|
||||
func get_crosslink_committees_at_slot*(state: BeaconState, slot: Slot|uint64,
|
||||
registry_change: bool = false):
|
||||
seq[CrosslinkCommittee] =
|
||||
## Returns the list of ``(committee, shard)`` tuples for the ``slot``.
|
||||
|
|
|
@ -153,6 +153,12 @@ proc endRecord*(w: var SszWriter, memo: RecordWritingMemo) =
|
|||
let finalSize = uint32(w.stream.pos - memo.initialStreamPos - 4)
|
||||
memo.sizePrefixCursor.endWrite(finalSize.toBytesSSZ)
|
||||
|
||||
func toSSZType(x: auto): auto =
|
||||
when x is Slot:
|
||||
x.uint64
|
||||
else:
|
||||
x
|
||||
|
||||
proc writeValue*(w: var SszWriter, obj: auto) =
|
||||
# We are not using overloads here, because this leads to
|
||||
# slightly better error messages when the user provides
|
||||
|
@ -178,10 +184,10 @@ proc writeValue*(w: var SszWriter, obj: auto) =
|
|||
# for research/serialized_sizes, remove when appropriate
|
||||
when defined(debugFieldSizes) and obj is (BeaconState|BeaconBlock):
|
||||
let start = w.stream.pos
|
||||
w.writeValue field
|
||||
w.writeValue field.toSSZType
|
||||
debugEcho fieldName, ": ", w.stream.pos - start
|
||||
else:
|
||||
w.writeValue field
|
||||
w.writeValue field.toSSZType
|
||||
w.endRecord(memo)
|
||||
|
||||
proc readValue*(r: var SszReader, result: var auto) =
|
||||
|
@ -235,7 +241,10 @@ proc readValue*(r: var SszReader, result: var auto) =
|
|||
|
||||
else:
|
||||
result.deserializeFields(fieldName, field):
|
||||
field = r.readValue(field.type)
|
||||
when field is Slot:
|
||||
field = r.readValue(uint64).Slot
|
||||
else:
|
||||
field = r.readValue(field.type)
|
||||
|
||||
if r.stream[].pos != endPos:
|
||||
raise newException(CorruptedDataError, "SSZ includes unexpected bytes past the end of the deserialized object")
|
||||
|
@ -303,7 +312,7 @@ func hash_tree_root*[T: object|tuple](x: T): array[32, byte] =
|
|||
## Containers have their fields recursively hashed, concatenated and hashed
|
||||
withHash:
|
||||
for field in x.fields:
|
||||
h.update hash_tree_root(field)
|
||||
h.update hash_tree_root(field.toSSZType)
|
||||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/simple-serialize.md#signed-roots
|
||||
func signed_root*[T: object](x: T, field_name: string): array[32, byte] =
|
||||
|
@ -316,7 +325,7 @@ func signed_root*[T: object](x: T, field_name: string): array[32, byte] =
|
|||
if name == field_name:
|
||||
found_field_name = true
|
||||
break
|
||||
h.update hash_tree_root(field)
|
||||
h.update hash_tree_root(field.toSSZType)
|
||||
|
||||
doAssert found_field_name
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ func verifyBlockSignature(state: BeaconState, blck: BeaconBlock): bool =
|
|||
proposer =
|
||||
state.validator_registry[get_beacon_proposer_index(state, state.slot)]
|
||||
proposal = Proposal(
|
||||
slot: blck.slot,
|
||||
slot: blck.slot.uint64,
|
||||
shard: BEACON_CHAIN_SHARD_NUMBER,
|
||||
block_root: Eth2Digest(data: signed_root(blck, "signature")),
|
||||
signature: blck.signature)
|
||||
|
@ -361,7 +361,8 @@ proc processTransfers(state: var BeaconState, blck: BeaconBlock,
|
|||
let transfer_message = signed_root(transfer, "signature")
|
||||
if not bls_verify(
|
||||
pubkey=transfer.pubkey, transfer_message, transfer.signature,
|
||||
get_domain(state.fork, slot_to_epoch(transfer.slot), DOMAIN_TRANSFER)):
|
||||
get_domain(
|
||||
state.fork, slot_to_epoch(transfer.slot), DOMAIN_TRANSFER)):
|
||||
notice "Transfer: incorrect signature"
|
||||
return false
|
||||
|
||||
|
@ -611,7 +612,7 @@ func processEpoch(state: var BeaconState) =
|
|||
let
|
||||
previous_epoch_head_attestations =
|
||||
previous_epoch_attestations.filterIt(
|
||||
it.data.beacon_block_root == get_block_root(state, it.data.slot))
|
||||
it.data.beacon_block_root == get_block_root(state, it.data.slot.Slot))
|
||||
|
||||
previous_epoch_head_attester_indices =
|
||||
toSet(get_attester_indices(state, previous_epoch_head_attestations))
|
||||
|
@ -708,8 +709,10 @@ func processEpoch(state: var BeaconState) =
|
|||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#crosslinks
|
||||
block:
|
||||
for slot in get_epoch_start_slot(previous_epoch) ..< get_epoch_start_slot(next_epoch):
|
||||
let crosslink_committees_at_slot = get_crosslink_committees_at_slot(state, slot)
|
||||
for slot in get_epoch_start_slot(previous_epoch).uint64 ..<
|
||||
get_epoch_start_slot(next_epoch).uint64:
|
||||
let crosslink_committees_at_slot =
|
||||
get_crosslink_committees_at_slot(state, slot.Slot)
|
||||
|
||||
for crosslink_committee in crosslink_committees_at_slot:
|
||||
if 3'u64 * total_attesting_balance(crosslink_committee) >=
|
||||
|
@ -737,7 +740,7 @@ func processEpoch(state: var BeaconState) =
|
|||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#justification-and-finalization
|
||||
func inclusion_distances(state: BeaconState): auto =
|
||||
result = initTable[ValidatorIndex, uint64]()
|
||||
result = initTable[ValidatorIndex, Slot]()
|
||||
|
||||
for a in previous_epoch_attestations:
|
||||
for v in get_attestation_participants(
|
||||
|
@ -801,7 +804,7 @@ func processEpoch(state: var BeaconState) =
|
|||
else:
|
||||
## Last case will not occur. If this assumption becomes false,
|
||||
## indexing into distances will fail.
|
||||
initTable[ValidatorIndex, uint64]()
|
||||
initTable[ValidatorIndex, Slot]()
|
||||
|
||||
for index in active_validator_indices:
|
||||
if index notin previous_epoch_attester_indices:
|
||||
|
@ -837,7 +840,7 @@ func processEpoch(state: var BeaconState) =
|
|||
## (reverse) index based on one O(n) scan of previous_epoch_attestations,
|
||||
## then perform O(n) O(1) lookups. Keep same iteration order and rules in
|
||||
## which first match wins and terminates for each ValidatorIndex.
|
||||
var proposer_indexes = initTable[ValidatorIndex, uint64]()
|
||||
var proposer_indexes = initTable[ValidatorIndex, Slot]()
|
||||
|
||||
# This is the loop from inclusion_slot(...)
|
||||
for a in previous_epoch_attestations:
|
||||
|
@ -861,8 +864,10 @@ func processEpoch(state: var BeaconState) =
|
|||
|
||||
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#crosslinks-1
|
||||
block:
|
||||
for slot in get_epoch_start_slot(previous_epoch) ..< get_epoch_start_slot(current_epoch):
|
||||
let crosslink_committees_at_slot = get_crosslink_committees_at_slot(state, slot)
|
||||
for slot in get_epoch_start_slot(previous_epoch).uint64 ..<
|
||||
get_epoch_start_slot(current_epoch).uint64:
|
||||
let crosslink_committees_at_slot =
|
||||
get_crosslink_committees_at_slot(state, slot.Slot)
|
||||
for crosslink_committee in crosslink_committees_at_slot:
|
||||
let
|
||||
committee_attesting_validators =
|
||||
|
|
|
@ -24,7 +24,7 @@ type
|
|||
|
||||
func toHeader(b: BeaconBlock): BeaconBlockHeader =
|
||||
BeaconBlockHeader(
|
||||
slot: b.slot,
|
||||
slot: b.slot.uint64,
|
||||
parent_root: b.parent_root,
|
||||
state_root: b.state_root,
|
||||
randao_reveal: b.randao_reveal,
|
||||
|
@ -35,7 +35,7 @@ func toHeader(b: BeaconBlock): BeaconBlockHeader =
|
|||
|
||||
proc fromHeaderAndBody(b: var BeaconBlock, h: BeaconBlockHeader, body: BeaconBlockBody) =
|
||||
assert(hash_tree_root_final(body) == h.body)
|
||||
b.slot = h.slot
|
||||
b.slot = h.slot.Slot
|
||||
b.parent_root = h.parent_root
|
||||
b.state_root = h.state_root
|
||||
b.randao_reveal = h.randao_reveal
|
||||
|
@ -76,7 +76,7 @@ p2pProtocol BeaconSync(version = 1,
|
|||
latestFinalizedRoot: Eth2Digest # TODO
|
||||
latestFinalizedEpoch: uint64 = node.state.data.finalized_epoch
|
||||
bestRoot: Eth2Digest # TODO
|
||||
bestSlot: uint64 = node.state.data.slot
|
||||
bestSlot: uint64 = node.state.data.slot.uint64
|
||||
|
||||
let m = await handshake(peer, timeout = 500,
|
||||
status(networkId, latestFinalizedRoot,
|
||||
|
|
|
@ -15,7 +15,7 @@ proc stateSize(deposits: int, maxContent = false) =
|
|||
# attestations it may hold, so we'll just add so many of them
|
||||
state.latest_attestations.setLen(MAX_ATTESTATIONS * SLOTS_PER_EPOCH * 2)
|
||||
let
|
||||
crosslink_committees = get_crosslink_committees_at_slot(state, 0)
|
||||
crosslink_committees = get_crosslink_committees_at_slot(state, 0.Slot)
|
||||
validatorsPerCommittee =
|
||||
len(crosslink_committees[0].committee) # close enough..
|
||||
for a in state.latest_attestations.mitems():
|
||||
|
|
|
@ -36,6 +36,8 @@ template withTimerRet(stats: var RunningStat, body: untyped): untyped =
|
|||
|
||||
tmp
|
||||
|
||||
proc `%`*(x: Slot): JsonNode {.borrow.}
|
||||
|
||||
proc writeJson*(prefix, slot, v: auto) =
|
||||
var f: File
|
||||
defer: close(f)
|
||||
|
@ -80,7 +82,7 @@ cli do(slots = 1945,
|
|||
attestations[attestations_idx] = @[]
|
||||
|
||||
let t =
|
||||
if (state.slot + 2.Slot) mod SLOTS_PER_EPOCH == 0: tEpoch
|
||||
if (state.slot + 2) mod SLOTS_PER_EPOCH == 0: tEpoch
|
||||
else: tBlock
|
||||
|
||||
withTimer(timers[t]):
|
||||
|
|
|
@ -57,11 +57,12 @@ suite "Beacon chain DB":
|
|||
check: x == y
|
||||
|
||||
let
|
||||
a0 = BeaconBlock(slot: 0)
|
||||
# TODO Not GENESIS_SLOT?
|
||||
a0 = BeaconBlock(slot: 0.Slot)
|
||||
a0r = hash_tree_root_final(a0)
|
||||
a1 = BeaconBlock(slot: 1, parent_root: a0r)
|
||||
a1 = BeaconBlock(slot: 1.Slot, parent_root: a0r)
|
||||
a1r = hash_tree_root_final(a1)
|
||||
a2 = BeaconBlock(slot: 2, parent_root: a1r)
|
||||
a2 = BeaconBlock(slot: 2.Slot, parent_root: a1r)
|
||||
a2r = hash_tree_root_final(a2)
|
||||
|
||||
doAssert toSeq(db.getAncestors(a0r)) == []
|
||||
|
|
|
@ -74,8 +74,9 @@ suite "Simple serialization":
|
|||
SSZ.roundripTest [1, 2, 3]
|
||||
SSZ.roundripTest @[1, 2, 3]
|
||||
SSZ.roundripTest SigKey.random().getKey()
|
||||
SSZ.roundripTest BeaconBlock(slot: 42, signature: sign(SigKey.random(), 0'u64, ""))
|
||||
SSZ.roundripTest BeaconState(slot: 42)
|
||||
SSZ.roundripTest BeaconBlock(
|
||||
slot: 42.Slot, signature: sign(SigKey.random(), 0'u64, ""))
|
||||
SSZ.roundripTest BeaconState(slot: 42.Slot)
|
||||
|
||||
suite "Tree hashing":
|
||||
# TODO Nothing but smoke tests for now..
|
||||
|
|
|
@ -120,7 +120,7 @@ proc addBlock*(
|
|||
# Once we've collected all the state data, we sign the block data along with
|
||||
# some book-keeping values
|
||||
signed_data = Proposal(
|
||||
slot: new_block.slot,
|
||||
slot: new_block.slot.uint64,
|
||||
shard: BEACON_CHAIN_SHARD_NUMBER,
|
||||
block_root: Eth2Digest(data: signed_root(new_block, "signature")),
|
||||
signature: ValidatorSig(),
|
||||
|
|
Loading…
Reference in New Issue