Finish the Spec/Epoch types refactoring

This commit is contained in:
Zahary Karadjov 2019-03-13 23:23:01 +02:00
parent e69702bab5
commit 562eafe124
5 changed files with 53 additions and 35 deletions

View File

@ -218,7 +218,7 @@ func get_genesis_beacon_state*(
for i in 0 ..< SHARD_COUNT:
state.latest_crosslinks[i] = Crosslink(
epoch: GENESIS_EPOCH.uint64, crosslink_data_root: ZERO_HASH)
epoch: GENESIS_EPOCH, crosslink_data_root: ZERO_HASH)
# Process genesis deposits
for deposit in genesis_validator_deposits:
@ -401,8 +401,7 @@ proc checkAttestation*(
return
let expected_justified_block_root =
get_block_root(
state, get_epoch_start_slot(attestation.data.justified_epoch.Epoch))
get_block_root(state, get_epoch_start_slot(attestation.data.justified_epoch))
if not (attestation.data.justified_block_root == expected_justified_block_root):
warn("Unexpected justified block root",
attestation_justified_block_root = attestation.data.justified_block_root,
@ -413,7 +412,7 @@ proc checkAttestation*(
attestation.data.latest_crosslink,
Crosslink(
crosslink_data_root: attestation.data.crosslink_data_root,
epoch: slot_to_epoch(attestation_data_slot).uint64)]):
epoch: slot_to_epoch(attestation_data_slot))]):
warn("Unexpected crosslink shard",
state_latest_crosslinks_attestation_data_shard =
state.latest_crosslinks[attestation.data.shard],
@ -516,12 +515,12 @@ proc makeAttestationData*(
justified_block_root = get_block_root(state, justified_slot)
AttestationData(
slot: state.slot.uint64,
slot: state.slot,
shard: shard,
beacon_block_root: beacon_block_root,
epoch_boundary_root: epoch_boundary_root,
crosslink_data_root: Eth2Digest(), # Stub in phase0
latest_crosslink: state.latest_crosslinks[shard],
justified_epoch: state.justified_epoch.uint64,
justified_epoch: state.justified_epoch,
justified_block_root: justified_block_root,
)

View File

@ -18,7 +18,8 @@
# types / composition
import
eth/common, hashes, math,
hashes, math,
eth/[common, rlp],
./crypto, ./digest
# TODO Data types:
@ -228,7 +229,7 @@ type
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#attestationdata
AttestationData* = object
slot*: uint64 ##\
slot*: Slot ##\
## Slot number
shard*: uint64 ##\
@ -246,7 +247,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 +285,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
@ -451,7 +452,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 ##\
@ -522,7 +523,7 @@ type
func shortValidatorKey*(state: BeaconState, validatorIdx: int): string =
($state.validator_registry[validatorIdx].pubkey)[0..7]
template ethTimeUnit(typ: type) =
template ethTimeUnit(typ: type) {.dirty.} =
proc `+`*(x: typ, y: uint64): typ {.borrow.}
proc `-`*(x: typ, y: uint64): typ {.borrow.}
proc `-`*(x: uint64, y: typ): typ {.borrow.}
@ -554,13 +555,26 @@ template ethTimeUnit(typ: type) =
proc `$`*(x: typ): string {.borrow.}
proc hash*(x: typ): Hash {.borrow.}
ethTimeUnit(Slot)
ethTimeUnit(Epoch)
# Serialization
proc read*(rlp: var Rlp, T: type typ): typ {.inline.} =
typ(rlp.read(uint64))
func humaneSlotNum*(s: auto): uint64 =
proc append*(writer: var RlpWriter, value: typ) =
writer.append uint64(value)
proc writeValue*(writer: var JsonWriter, value: typ) =
writeValue(writer, uint64 value)
proc readValue*(reader: var JsonReader, value: var typ) =
value = typ reader.readValue(uint64)
ethTimeUnit Slot
ethTimeUnit Epoch
func humaneSlotNum*(s: Slot): uint64 =
s.Slot - GENESIS_SLOT
func humaneEpochNum*(e: auto): uint64 =
func humaneEpochNum*(e: Epoch): uint64 =
e.Epoch - GENESIS_EPOCH
import nimcrypto, json_serialization

View File

@ -218,11 +218,13 @@ func bytes_to_int*(data: seq[byte]): uint64 =
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#int_to_bytes1-int_to_bytes2-
# Have 1, 4, and 32-byte versions. 2+ more and maybe worth metaprogramming.
func int_to_bytes32*(x: uint64|Epoch) : array[32, byte] =
func int_to_bytes32*(x: uint64): array[32, byte] =
## Little-endian data representation
## TODO remove uint64 when those callers fade away
for i in 0 ..< 8:
result[24 + i] = byte((x.uint64 shr i*8) and 0xff)
result[24 + i] = byte((x shr i*8) and 0xff)
func int_to_bytes32*(x: Epoch): array[32, byte] {.borrow.}
func int_to_bytes1*(x: int): array[1, byte] =
assert x >= 0

View File

@ -304,7 +304,7 @@ proc processExits(
if skipValidation notin flags:
if not bls_verify(
validator.pubkey, signed_root(exit, "signature"), exit.signature,
get_domain(state.fork, exit.epoch.Epoch, DOMAIN_EXIT)):
get_domain(state.fork, exit.epoch, DOMAIN_EXIT)):
notice "Exit: invalid signature"
return false
@ -717,7 +717,7 @@ func processEpoch(state: var BeaconState) =
if 3'u64 * total_attesting_balance(crosslink_committee) >=
2'u64 * get_total_balance(state, crosslink_committee.committee):
state.latest_crosslinks[crosslink_committee.shard] = Crosslink(
epoch: slot_to_epoch(slot).uint64,
epoch: slot_to_epoch(slot),
crosslink_data_root: winning_root(crosslink_committee))
# https://github.com/ethereum/eth2.0-specs/blob/0.4.0/specs/core/0_beacon-chain.md#rewards-and-penalties
@ -745,7 +745,7 @@ func processEpoch(state: var BeaconState) =
for v in get_attestation_participants(
state, a.data, a.aggregation_bitfield):
if v notin result:
result[v] = a.inclusion_slot - a.data.slot
result[v] = Slot(a.inclusion_slot - a.data.slot)
block: # Justification and finalization
let

View File

@ -1,7 +1,7 @@
import
options, tables,
chronicles, chronos, ranges/bitranges,
spec/[datatypes, crypto, digest],
spec/[datatypes, crypto, digest], eth/rlp,
beacon_node_types, eth2_network, beacon_chain_db, block_pool, time, ssz
from beacon_node import onBeaconBlock
@ -43,7 +43,10 @@ proc fromHeaderAndBody(b: var BeaconBlock, h: BeaconBlockHeader, body: BeaconBlo
b.signature = h.signature
b.body = body
proc importBlocks(node: BeaconNode, roots: openarray[(Eth2Digest, uint64)], headers: openarray[BeaconBlockHeader], bodies: openarray[BeaconBlockBody]) =
proc importBlocks(node: BeaconNode,
roots: openarray[(Eth2Digest, Slot)],
headers: openarray[BeaconBlockHeader],
bodies: openarray[BeaconBlockBody]) =
var bodyMap = initTable[Eth2Digest, int]()
for i, b in bodies:
@ -74,9 +77,9 @@ p2pProtocol BeaconSync(version = 1,
var
latestFinalizedRoot: Eth2Digest # TODO
latestFinalizedEpoch: uint64 = node.state.data.finalized_epoch.uint64
latestFinalizedEpoch = node.state.data.finalized_epoch
bestRoot: Eth2Digest # TODO
bestSlot: uint64 = node.state.data.slot.uint64
bestSlot = node.state.data.slot
let m = await handshake(peer, timeout = 500,
status(networkId, latestFinalizedRoot,
@ -94,11 +97,11 @@ p2pProtocol BeaconSync(version = 1,
# Send roots
# TODO: Currently we send all block roots in one "packet". Maybe
# they should be split to multiple packets.
type Root = (Eth2Digest, uint64)
type Root = (Eth2Digest, Slot)
var roots = newSeqOfCap[Root](128)
for i in m.bestSlot .. bestSlot:
for r in blockPool.blockRootsForSlot(i):
roots.add((r, i))
for i in int(m.bestSlot) .. int(bestSlot):
for r in blockPool.blockRootsForSlot(i.Slot):
roots.add((r, i.Slot))
await peer.beaconBlockRoots(roots)
else:
@ -115,28 +118,28 @@ p2pProtocol BeaconSync(version = 1,
peer: Peer,
networkId: int,
latestFinalizedRoot: Eth2Digest,
latestFinalizedEpoch: uint64,
latestFinalizedEpoch: Epoch,
bestRoot: Eth2Digest,
bestSlot: uint64) {.libp2pProtocol("hello", "1.0.0").}
bestSlot: Slot) {.libp2pProtocol("hello", "1.0.0").}
proc beaconBlockRoots(
peer: Peer,
roots: openarray[(Eth2Digest, uint64)]) {.libp2pProtocol("rpc/beacon_block_roots", "1.0.0").}
roots: openarray[(Eth2Digest, Slot)]) {.libp2pProtocol("rpc/beacon_block_roots", "1.0.0").}
requestResponse:
proc getBeaconBlockHeaders(
peer: Peer,
blockRoot: Eth2Digest,
slot: uint64,
slot: Slot,
maxHeaders: int,
skipSlots: int) {.libp2pProtocol("rpc/beacon_block_headers", "1.0.0").} =
# TODO: validate maxHeaders and implement slipSlots
var s = slot
var s = slot.int
var headers = newSeqOfCap[BeaconBlockHeader](maxHeaders)
let db = peer.networkState.db
let blockPool = peer.networkState.node.blockPool
while headers.len < maxHeaders:
for r in blockPool.blockRootsForSlot(s):
for r in blockPool.blockRootsForSlot(s.Slot):
headers.add(db.getBlock(r).get().toHeader)
if headers.len == maxHeaders: break
inc s