parent
7ea51d5b0b
commit
5b35b6c2dc
|
@ -82,7 +82,7 @@ func on_startup*(initial_validator_entries: openArray[InitialValidator],
|
||||||
|
|
||||||
# Recent state
|
# Recent state
|
||||||
latest_state_recalculation_slot: INITIAL_SLOT_NUMBER,
|
latest_state_recalculation_slot: INITIAL_SLOT_NUMBER,
|
||||||
latest_block_hashes: repeat(ZERO_HASH, EPOCH_LENGTH * 2),
|
latest_block_roots: repeat(ZERO_HASH, EPOCH_LENGTH * 2),
|
||||||
|
|
||||||
# PoW receipt root
|
# PoW receipt root
|
||||||
processed_pow_receipt_root: processed_pow_receipt_root,
|
processed_pow_receipt_root: processed_pow_receipt_root,
|
||||||
|
@ -95,19 +95,19 @@ func on_startup*(initial_validator_entries: openArray[InitialValidator],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
||||||
func get_block_hash*(state: BeaconState,
|
func get_block_root*(state: BeaconState,
|
||||||
slot: uint64): Eth2Digest =
|
slot: uint64): Eth2Digest =
|
||||||
let earliest_slot_in_array =
|
let earliest_slot_in_array =
|
||||||
state.slot - len(state.latest_block_hashes).uint64
|
state.slot - len(state.latest_block_roots).uint64
|
||||||
assert earliest_slot_in_array <= slot
|
assert earliest_slot_in_array <= slot
|
||||||
assert slot < state.slot
|
assert slot < state.slot
|
||||||
state.latest_block_hashes[(slot - earliest_slot_in_array).int]
|
state.latest_block_roots[(slot - earliest_slot_in_array).int]
|
||||||
|
|
||||||
func append_to_recent_block_hashes*(old_block_hashes: seq[Eth2Digest],
|
func append_to_recent_block_roots*(old_block_roots: seq[Eth2Digest],
|
||||||
parent_slot, current_slot: uint64,
|
parent_slot, current_slot: uint64,
|
||||||
parent_hash: Eth2Digest): seq[Eth2Digest] =
|
parent_hash: Eth2Digest): seq[Eth2Digest] =
|
||||||
let d = current_slot - parent_slot
|
let d = current_slot - parent_slot
|
||||||
result = old_block_hashes
|
result = old_block_roots
|
||||||
result.add repeat(parent_hash, d)
|
result.add repeat(parent_hash, d)
|
||||||
|
|
||||||
func get_attestation_participants*(state: BeaconState,
|
func get_attestation_participants*(state: BeaconState,
|
||||||
|
@ -180,14 +180,14 @@ func checkAttestation*(state: BeaconState, attestation: Attestation): bool =
|
||||||
if attestation.data.justified_slot != expected_justified_slot:
|
if attestation.data.justified_slot != expected_justified_slot:
|
||||||
return
|
return
|
||||||
|
|
||||||
let expected_justified_block_hash =
|
let expected_justified_block_root =
|
||||||
get_block_hash(state, attestation.data.justified_slot)
|
get_block_root(state, attestation.data.justified_slot)
|
||||||
if attestation.data.justified_block_hash != expected_justified_block_hash:
|
if attestation.data.justified_block_root != expected_justified_block_root:
|
||||||
return
|
return
|
||||||
|
|
||||||
if state.latest_crosslinks[attestation.data.shard].shard_block_hash notin [
|
if state.latest_crosslinks[attestation.data.shard].shard_block_root notin [
|
||||||
attestation.data.latest_crosslink_hash,
|
attestation.data.latest_crosslink_root,
|
||||||
attestation.data.shard_block_hash]:
|
attestation.data.shard_block_root]:
|
||||||
return
|
return
|
||||||
|
|
||||||
let
|
let
|
||||||
|
@ -197,7 +197,7 @@ func checkAttestation*(state: BeaconState, attestation: Attestation): bool =
|
||||||
participants, state.validator_registry[it].pubkey))
|
participants, state.validator_registry[it].pubkey))
|
||||||
|
|
||||||
# Verify that aggregate_signature verifies using the group pubkey.
|
# Verify that aggregate_signature verifies using the group pubkey.
|
||||||
let msg = hashSSZ(attestation.data)
|
let msg = hash_tree_root(attestation.data)
|
||||||
|
|
||||||
if not BLSVerify(
|
if not BLSVerify(
|
||||||
group_public_key, @msg & @[0'u8], attestation.aggregate_signature,
|
group_public_key, @msg & @[0'u8], attestation.aggregate_signature,
|
||||||
|
@ -206,7 +206,7 @@ func checkAttestation*(state: BeaconState, attestation: Attestation): bool =
|
||||||
return
|
return
|
||||||
|
|
||||||
# To be removed in Phase1:
|
# To be removed in Phase1:
|
||||||
if attestation.data.shard_block_hash != ZERO_HASH:
|
if attestation.data.shard_block_root != ZERO_HASH:
|
||||||
return
|
return
|
||||||
|
|
||||||
true
|
true
|
||||||
|
|
|
@ -154,22 +154,22 @@ type
|
||||||
AttestationData* = object
|
AttestationData* = object
|
||||||
slot*: uint64
|
slot*: uint64
|
||||||
shard*: uint64
|
shard*: uint64
|
||||||
beacon_block_hash*: Eth2Digest ##\
|
beacon_block_root*: Eth2Digest ##\
|
||||||
## Hash of the block we're signing
|
## Hash of the block we're signing
|
||||||
|
|
||||||
epoch_boundary_hash*: Eth2Digest ##\
|
epoch_boundary_root*: Eth2Digest ##\
|
||||||
## Hash of the ancestor at the cycle boundary
|
## Hash of the ancestor at the cycle boundary
|
||||||
|
|
||||||
shard_block_hash*: Eth2Digest ##\
|
shard_block_root*: Eth2Digest ##\
|
||||||
## Shard block hash being attested to
|
## Shard block hash being attested to
|
||||||
|
|
||||||
latest_crosslink_hash*: Eth2Digest ##\
|
latest_crosslink_root*: Eth2Digest ##\
|
||||||
## Last crosslink hash
|
## Last crosslink hash
|
||||||
|
|
||||||
justified_slot*: uint64 ##\
|
justified_slot*: uint64 ##\
|
||||||
## Slot of last justified beacon block
|
## Slot of last justified beacon block
|
||||||
|
|
||||||
justified_block_hash*: Eth2Digest ##\
|
justified_block_root*: Eth2Digest ##\
|
||||||
## Hash of last justified beacon block
|
## Hash of last justified beacon block
|
||||||
|
|
||||||
Deposit* = object
|
Deposit* = object
|
||||||
|
@ -237,7 +237,7 @@ type
|
||||||
slot*: uint64
|
slot*: uint64
|
||||||
shard*: uint64 ##\
|
shard*: uint64 ##\
|
||||||
## Shard number (or `BEACON_CHAIN_SHARD_NUMBER` for beacon chain)
|
## Shard number (or `BEACON_CHAIN_SHARD_NUMBER` for beacon chain)
|
||||||
block_hash*: Eth2Digest
|
block_root*: Eth2Digest
|
||||||
|
|
||||||
BeaconState* = object
|
BeaconState* = object
|
||||||
slot*: uint64
|
slot*: uint64
|
||||||
|
@ -269,7 +269,7 @@ type
|
||||||
|
|
||||||
latest_crosslinks*: array[SHARD_COUNT, CrosslinkRecord]
|
latest_crosslinks*: array[SHARD_COUNT, CrosslinkRecord]
|
||||||
latest_state_recalculation_slot*: uint64
|
latest_state_recalculation_slot*: uint64
|
||||||
latest_block_hashes*: seq[Eth2Digest] ##\
|
latest_block_roots*: seq[Eth2Digest] ##\
|
||||||
## Needed to process attestations, older to newer
|
## Needed to process attestations, older to newer
|
||||||
latest_penalized_exit_balances*: seq[uint64] ##\
|
latest_penalized_exit_balances*: seq[uint64] ##\
|
||||||
## Balances penalized in the current withdrawal period
|
## Balances penalized in the current withdrawal period
|
||||||
|
@ -290,7 +290,7 @@ type
|
||||||
|
|
||||||
CrosslinkRecord* = object
|
CrosslinkRecord* = object
|
||||||
slot*: uint64 # Slot number
|
slot*: uint64 # Slot number
|
||||||
shard_block_hash*: Eth2Digest # Shard chain block hash
|
shard_block_root*: Eth2Digest # Shard chain block hash
|
||||||
|
|
||||||
ShardCommittee* = object
|
ShardCommittee* = object
|
||||||
shard*: uint64 # Shard number
|
shard*: uint64 # Shard number
|
||||||
|
|
|
@ -68,15 +68,15 @@ func split*[T](lst: openArray[T], N: Positive): seq[seq[T]] =
|
||||||
for i in 0 ..< N:
|
for i in 0 ..< N:
|
||||||
result[i] = lst[lst.len * i div N ..< lst.len * (i+1) div N] # TODO: avoid alloc via toOpenArray
|
result[i] = lst[lst.len * i div N ..< lst.len * (i+1) div N] # TODO: avoid alloc via toOpenArray
|
||||||
|
|
||||||
func get_new_recent_block_hashes*(old_block_hashes: seq[Eth2Digest],
|
func get_new_recent_block_roots*(old_block_roots: seq[Eth2Digest],
|
||||||
parent_slot, current_slot: int64,
|
parent_slot, current_slot: int64,
|
||||||
parent_hash: Eth2Digest
|
parent_hash: Eth2Digest
|
||||||
): seq[Eth2Digest] =
|
): seq[Eth2Digest] =
|
||||||
|
|
||||||
# Should throw for `current_slot - CYCLE_LENGTH * 2 - 1` according to spec comment
|
# Should throw for `current_slot - CYCLE_LENGTH * 2 - 1` according to spec comment
|
||||||
let d = current_slot - parent_slot
|
let d = current_slot - parent_slot
|
||||||
result = old_block_hashes[d .. ^1]
|
result = old_block_roots[d .. ^1]
|
||||||
for _ in 0 ..< min(d, old_block_hashes.len):
|
for _ in 0 ..< min(d, old_block_roots.len):
|
||||||
result.add parent_hash
|
result.add parent_hash
|
||||||
|
|
||||||
func ceil_div8*(v: int): int = (v + 7) div 8 # TODO use a proper bitarray!
|
func ceil_div8*(v: int): int = (v + 7) div 8 # TODO use a proper bitarray!
|
||||||
|
|
|
@ -36,7 +36,7 @@ func get_new_validators*(current_validators: seq[ValidatorRecord],
|
||||||
#
|
#
|
||||||
# Check that validator really did register
|
# Check that validator really did register
|
||||||
# TODO fix tests and enable (nightmare)
|
# TODO fix tests and enable (nightmare)
|
||||||
# let msg = hashSSZ((pubkey, withdrawal_credentials, randao_commitment))
|
# let msg = hash_tree_root((pubkey, withdrawal_credentials, randao_commitment))
|
||||||
# assert BLSVerify(
|
# assert BLSVerify(
|
||||||
# pubkey, msg, proof_of_possession,
|
# pubkey, msg, proof_of_possession,
|
||||||
# get_domain(fork_data, current_slot, DOMAIN_DEPOSIT))
|
# get_domain(fork_data, current_slot, DOMAIN_DEPOSIT))
|
||||||
|
@ -121,10 +121,10 @@ func get_new_validator_registry_delta_chain_tip(
|
||||||
## Compute the next hash in the validator registry delta hash chain.
|
## Compute the next hash in the validator registry delta hash chain.
|
||||||
|
|
||||||
withEth2Hash:
|
withEth2Hash:
|
||||||
h.update hashSSZ(current_validator_registry_delta_chain_tip)
|
h.update hash_tree_root(current_validator_registry_delta_chain_tip)
|
||||||
h.update hashSSZ(flag.uint8)
|
h.update hash_tree_root(flag.uint8)
|
||||||
h.update hashSSZ(index)
|
h.update hash_tree_root(index)
|
||||||
h.update hashSSZ(pubkey)
|
h.update hash_tree_root(pubkey)
|
||||||
|
|
||||||
func get_effective_balance*(validator: ValidatorRecord): uint64 =
|
func get_effective_balance*(validator: ValidatorRecord): uint64 =
|
||||||
min(validator.balance, MAX_DEPOSIT)
|
min(validator.balance, MAX_DEPOSIT)
|
||||||
|
|
|
@ -130,7 +130,7 @@ func serialize*[T](value: T): seq[byte] =
|
||||||
|
|
||||||
# ################### Hashing ###################################
|
# ################### Hashing ###################################
|
||||||
|
|
||||||
# Sample hashSSZ implementation based on:
|
# Sample hash_tree_root implementation based on:
|
||||||
# https://github.com/ethereum/eth2.0-specs/blob/98312f40b5742de6aa73f24e6225ee68277c4614/specs/simple-serialize.md
|
# https://github.com/ethereum/eth2.0-specs/blob/98312f40b5742de6aa73f24e6225ee68277c4614/specs/simple-serialize.md
|
||||||
# and
|
# and
|
||||||
# https://github.com/ethereum/beacon_chain/pull/134
|
# https://github.com/ethereum/beacon_chain/pull/134
|
||||||
|
@ -163,46 +163,46 @@ func merkleHash[T](lst: seq[T]): array[32, byte]
|
||||||
|
|
||||||
# ################### Hashing interface ###################################
|
# ################### Hashing interface ###################################
|
||||||
|
|
||||||
func hashSSZ*(x: SomeInteger): array[sizeof(x), byte] =
|
func hash_tree_root*(x: SomeInteger): array[sizeof(x), byte] =
|
||||||
## Convert directly to bytes the size of the int. (e.g. ``uint16 = 2 bytes``)
|
## Convert directly to bytes the size of the int. (e.g. ``uint16 = 2 bytes``)
|
||||||
## All integers are serialized as **big endian**.
|
## All integers are serialized as **big endian**.
|
||||||
toBytesSSZ(x)
|
toBytesSSZ(x)
|
||||||
|
|
||||||
func hashSSZ*(x: Uint24): array[3, byte] =
|
func hash_tree_root*(x: Uint24): array[3, byte] =
|
||||||
## Convert directly to bytes the size of the int. (e.g. ``uint16 = 2 bytes``)
|
## Convert directly to bytes the size of the int. (e.g. ``uint16 = 2 bytes``)
|
||||||
## All integers are serialized as **big endian**.
|
## All integers are serialized as **big endian**.
|
||||||
toBytesSSZ(x)
|
toBytesSSZ(x)
|
||||||
|
|
||||||
func hashSSZ*(x: EthAddress): array[sizeof(x), byte] =
|
func hash_tree_root*(x: EthAddress): array[sizeof(x), byte] =
|
||||||
## Addresses copied as-is
|
## Addresses copied as-is
|
||||||
toBytesSSZ(x)
|
toBytesSSZ(x)
|
||||||
|
|
||||||
func hashSSZ*(x: Eth2Digest): array[32, byte] =
|
func hash_tree_root*(x: Eth2Digest): array[32, byte] =
|
||||||
## Hash32 copied as-is
|
## Hash32 copied as-is
|
||||||
toBytesSSZ(x)
|
toBytesSSZ(x)
|
||||||
|
|
||||||
func hashSSZ*(x: openArray[byte]): array[32, byte] =
|
func hash_tree_root*(x: openArray[byte]): array[32, byte] =
|
||||||
## Blobs are hashed
|
## Blobs are hashed
|
||||||
hash(x)
|
hash(x)
|
||||||
|
|
||||||
func hashSSZ*(x: ValidatorRecord): array[32, byte] =
|
func hash_tree_root*(x: ValidatorRecord): array[32, byte] =
|
||||||
## Containers have their fields recursively hashed, concatenated and hashed
|
## Containers have their fields recursively hashed, concatenated and hashed
|
||||||
# TODO hash_ssz.py code contains special cases for some types, why?
|
# TODO hash_ssz.py code contains special cases for some types, why?
|
||||||
withHash:
|
withHash:
|
||||||
# tmp.add(x.pubkey) # TODO uncertain future of public key format
|
# tmp.add(x.pubkey) # TODO uncertain future of public key format
|
||||||
h.update hashSSZ(x.withdrawal_credentials)
|
h.update hash_tree_root(x.withdrawal_credentials)
|
||||||
h.update hashSSZ(x.randao_skips)
|
h.update hash_tree_root(x.randao_skips)
|
||||||
h.update hashSSZ(x.balance)
|
h.update hash_tree_root(x.balance)
|
||||||
# h.update hashSSZ(x.status) # TODO it's an enum, deal with it
|
# h.update hash_tree_root(x.status) # TODO it's an enum, deal with it
|
||||||
h.update hashSSZ(x.latest_status_change_slot)
|
h.update hash_tree_root(x.latest_status_change_slot)
|
||||||
h.update hashSSZ(x.exit_count)
|
h.update hash_tree_root(x.exit_count)
|
||||||
|
|
||||||
func hashSSZ*(x: ShardCommittee): array[32, byte] =
|
func hash_tree_root*(x: ShardCommittee): array[32, byte] =
|
||||||
withHash:
|
withHash:
|
||||||
h.update hashSSZ(x.shard)
|
h.update hash_tree_root(x.shard)
|
||||||
h.update merkleHash(x.committee)
|
h.update merkleHash(x.committee)
|
||||||
|
|
||||||
func hashSSZ*[T: not enum](x: T): array[32, byte] =
|
func hash_tree_root*[T: not enum](x: T): array[32, byte] =
|
||||||
when T is seq:
|
when T is seq:
|
||||||
## Sequences are tree-hashed
|
## Sequences are tree-hashed
|
||||||
merkleHash(x)
|
merkleHash(x)
|
||||||
|
@ -212,15 +212,15 @@ func hashSSZ*[T: not enum](x: T): array[32, byte] =
|
||||||
# TODO or.. https://github.com/ethereum/eth2.0-specs/issues/275
|
# TODO or.. https://github.com/ethereum/eth2.0-specs/issues/275
|
||||||
var fields: seq[tuple[name: string, value: seq[byte]]]
|
var fields: seq[tuple[name: string, value: seq[byte]]]
|
||||||
for name, field in x.fieldPairs:
|
for name, field in x.fieldPairs:
|
||||||
fields.add (name, @(hashSSZ(field)))
|
fields.add (name, @(hash_tree_root(field)))
|
||||||
|
|
||||||
withHash:
|
withHash:
|
||||||
for name, value in fields.sortedByIt(it.name):
|
for name, value in fields.sortedByIt(it.name):
|
||||||
h.update hashSSZ(value.value)
|
h.update hash_tree_root(value.value)
|
||||||
|
|
||||||
# #################################
|
# #################################
|
||||||
# HashSSZ not part of official spec
|
# hash_tree_root not part of official spec
|
||||||
func hashSSZ*(x: enum): array[32, byte] =
|
func hash_tree_root*(x: enum): array[32, byte] =
|
||||||
## TODO - Warning ⚠️: not part of the spec
|
## TODO - Warning ⚠️: not part of the spec
|
||||||
## as of https://github.com/ethereum/beacon_chain/pull/133/files
|
## as of https://github.com/ethereum/beacon_chain/pull/133/files
|
||||||
## This is a "stub" needed for BeaconBlock hashing
|
## This is a "stub" needed for BeaconBlock hashing
|
||||||
|
@ -228,13 +228,13 @@ func hashSSZ*(x: enum): array[32, byte] =
|
||||||
withHash:
|
withHash:
|
||||||
h.update [uint8 x]
|
h.update [uint8 x]
|
||||||
|
|
||||||
func hashSSZ*(x: ValidatorPubKey): array[32, byte] =
|
func hash_tree_root*(x: ValidatorPubKey): array[32, byte] =
|
||||||
## TODO - Warning ⚠️: not part of the spec
|
## TODO - Warning ⚠️: not part of the spec
|
||||||
## as of https://github.com/ethereum/beacon_chain/pull/133/files
|
## as of https://github.com/ethereum/beacon_chain/pull/133/files
|
||||||
## This is a "stub" needed for BeaconBlock hashing
|
## This is a "stub" needed for BeaconBlock hashing
|
||||||
x.getRaw().hash()
|
x.getRaw().hash()
|
||||||
|
|
||||||
func hashSSZ*(x: ValidatorSig): array[32, byte] =
|
func hash_tree_root*(x: ValidatorSig): array[32, byte] =
|
||||||
## TODO - Warning ⚠️: not part of the spec
|
## TODO - Warning ⚠️: not part of the spec
|
||||||
## as of https://github.com/ethereum/beacon_chain/pull/133/files
|
## as of https://github.com/ethereum/beacon_chain/pull/133/files
|
||||||
## This is a "stub" needed for BeaconBlock hashing
|
## This is a "stub" needed for BeaconBlock hashing
|
||||||
|
@ -258,9 +258,9 @@ func merkleHash[T](lst: seq[T]): array[32, byte] =
|
||||||
|
|
||||||
if len(lst) == 0:
|
if len(lst) == 0:
|
||||||
chunkz.add @emptyChunk
|
chunkz.add @emptyChunk
|
||||||
elif sizeof(hashSSZ(lst[0])) < CHUNK_SIZE:
|
elif sizeof(hash_tree_root(lst[0])) < CHUNK_SIZE:
|
||||||
# See how many items fit in a chunk
|
# See how many items fit in a chunk
|
||||||
let itemsPerChunk = CHUNK_SIZE div sizeof(hashSSZ(lst[0]))
|
let itemsPerChunk = CHUNK_SIZE div sizeof(hash_tree_root(lst[0]))
|
||||||
|
|
||||||
chunkz.setLen((len(lst) + itemsPerChunk - 1) div itemsPerChunk)
|
chunkz.setLen((len(lst) + itemsPerChunk - 1) div itemsPerChunk)
|
||||||
|
|
||||||
|
@ -270,12 +270,12 @@ func merkleHash[T](lst: seq[T]): array[32, byte] =
|
||||||
if i == chunkz.len - 1:
|
if i == chunkz.len - 1:
|
||||||
let idx = i * itemsPerChunk + j
|
let idx = i * itemsPerChunk + j
|
||||||
if idx >= lst.len: break # Last chunk may be partial!
|
if idx >= lst.len: break # Last chunk may be partial!
|
||||||
chunkz[i].add hashSSZ(lst[i * itemsPerChunk + j])
|
chunkz[i].add hash_tree_root(lst[i * itemsPerChunk + j])
|
||||||
else:
|
else:
|
||||||
# Leave large items alone
|
# Leave large items alone
|
||||||
chunkz.setLen(len(lst))
|
chunkz.setLen(len(lst))
|
||||||
for i in 0..<len(lst):
|
for i in 0..<len(lst):
|
||||||
chunkz[i].add hashSSZ(lst[i])
|
chunkz[i].add hash_tree_root(lst[i])
|
||||||
|
|
||||||
while chunkz.len() > 1:
|
while chunkz.len() > 1:
|
||||||
if chunkz.len() mod 2 == 1:
|
if chunkz.len() mod 2 == 1:
|
||||||
|
|
|
@ -72,10 +72,10 @@ func verifyProposerSignature(state: BeaconState, blck: BeaconBlock): bool =
|
||||||
blck_without_sig.signature = ValidatorSig()
|
blck_without_sig.signature = ValidatorSig()
|
||||||
|
|
||||||
let
|
let
|
||||||
proposal_hash = hashSSZ(ProposalSignedData(
|
proposal_hash = hash_tree_root(ProposalSignedData(
|
||||||
slot: state.slot,
|
slot: state.slot,
|
||||||
shard: BEACON_CHAIN_SHARD,
|
shard: BEACON_CHAIN_SHARD,
|
||||||
block_hash: Eth2Digest(data: hashSSZ(blck_without_sig))
|
block_root: Eth2Digest(data: hash_tree_root(blck_without_sig))
|
||||||
))
|
))
|
||||||
|
|
||||||
let validator_idx = get_beacon_proposer_index(state, state.slot)
|
let validator_idx = get_beacon_proposer_index(state, state.slot)
|
||||||
|
@ -139,13 +139,13 @@ func processSlot(state: var BeaconState, latest_block: BeaconBlock): bool =
|
||||||
# TODO state not rolled back in case of failure
|
# TODO state not rolled back in case of failure
|
||||||
|
|
||||||
let
|
let
|
||||||
latest_hash = Eth2Digest(data: hashSSZ(latest_block))
|
latest_hash = Eth2Digest(data: hash_tree_root(latest_block))
|
||||||
|
|
||||||
state.slot += 1
|
state.slot += 1
|
||||||
state.latest_block_hashes.add latest_hash
|
state.latest_block_roots.add latest_hash
|
||||||
|
|
||||||
if state.latest_block_hashes.len < 2 or
|
if state.latest_block_roots.len < 2 or
|
||||||
state.latest_block_hashes[^2] != state.latest_block_hashes[^1]:
|
state.latest_block_roots[^2] != state.latest_block_roots[^1]:
|
||||||
# TODO a bit late for the following checks?
|
# TODO a bit late for the following checks?
|
||||||
# https://github.com/ethereum/eth2.0-specs/issues/284
|
# https://github.com/ethereum/eth2.0-specs/issues/284
|
||||||
if latest_block.slot != state.slot:
|
if latest_block.slot != state.slot:
|
||||||
|
@ -181,7 +181,7 @@ func boundary_attestations(
|
||||||
): seq[PendingAttestationRecord] =
|
): seq[PendingAttestationRecord] =
|
||||||
# TODO spec - add as helper?
|
# TODO spec - add as helper?
|
||||||
filterIt(attestations,
|
filterIt(attestations,
|
||||||
it.data.epoch_boundary_hash == boundary_hash and
|
it.data.epoch_boundary_root == boundary_hash and
|
||||||
it.data.justified_slot == state.justified_slot)
|
it.data.justified_slot == state.justified_slot)
|
||||||
|
|
||||||
func sum_effective_balances(
|
func sum_effective_balances(
|
||||||
|
@ -193,7 +193,7 @@ func sum_effective_balances(
|
||||||
|
|
||||||
func lowerThan(candidate, current: Eth2Digest): bool =
|
func lowerThan(candidate, current: Eth2Digest): bool =
|
||||||
# return true iff candidate is "lower" than current, per spec rule:
|
# return true iff candidate is "lower" than current, per spec rule:
|
||||||
# "ties broken by favoring lower `shard_block_hash` values"
|
# "ties broken by favoring lower `shard_block_root` values"
|
||||||
# TODO spec - clarify hash ordering..
|
# TODO spec - clarify hash ordering..
|
||||||
for i, v in current.data:
|
for i, v in current.data:
|
||||||
if v > candidate.data[i]: return true
|
if v > candidate.data[i]: return true
|
||||||
|
@ -220,7 +220,7 @@ func processEpoch(state: var BeaconState, blck: BeaconBlock): bool =
|
||||||
reward_quotient = BASE_REWARD_QUOTIENT * int_sqrt(total_balance_in_eth)
|
reward_quotient = BASE_REWARD_QUOTIENT * int_sqrt(total_balance_in_eth)
|
||||||
|
|
||||||
# TODO not in spec, convenient
|
# TODO not in spec, convenient
|
||||||
epoch_boundary_hash = get_block_hash(state, s)
|
epoch_boundary_root = get_block_root(state, s)
|
||||||
|
|
||||||
proc base_reward(v: ValidatorRecord): uint64 =
|
proc base_reward(v: ValidatorRecord): uint64 =
|
||||||
get_effective_balance(v) div reward_quotient.uint64
|
get_effective_balance(v) div reward_quotient.uint64
|
||||||
|
@ -232,7 +232,7 @@ func processEpoch(state: var BeaconState, blck: BeaconBlock): bool =
|
||||||
s <= it.data.slot and it.data.slot < s + EPOCH_LENGTH)
|
s <= it.data.slot and it.data.slot < s + EPOCH_LENGTH)
|
||||||
|
|
||||||
this_epoch_boundary_attestations =
|
this_epoch_boundary_attestations =
|
||||||
boundary_attestations(state, epoch_boundary_hash,
|
boundary_attestations(state, epoch_boundary_root,
|
||||||
this_epoch_attestations)
|
this_epoch_attestations)
|
||||||
|
|
||||||
this_epoch_boundary_attesters =
|
this_epoch_boundary_attesters =
|
||||||
|
@ -246,7 +246,7 @@ func processEpoch(state: var BeaconState, blck: BeaconBlock): bool =
|
||||||
s <= it.data.slot + EPOCH_LENGTH and it.data.slot < s)
|
s <= it.data.slot + EPOCH_LENGTH and it.data.slot < s)
|
||||||
|
|
||||||
previous_epoch_boundary_attestations =
|
previous_epoch_boundary_attestations =
|
||||||
boundary_attestations(state, epoch_boundary_hash,
|
boundary_attestations(state, epoch_boundary_root,
|
||||||
previous_epoch_attestations)
|
previous_epoch_attestations)
|
||||||
|
|
||||||
previous_epoch_boundary_attesters =
|
previous_epoch_boundary_attesters =
|
||||||
|
@ -260,23 +260,23 @@ func processEpoch(state: var BeaconState, blck: BeaconBlock): bool =
|
||||||
# these closures outside this scope, but still..
|
# these closures outside this scope, but still..
|
||||||
let statePtr = state.addr
|
let statePtr = state.addr
|
||||||
func attesting_validators(
|
func attesting_validators(
|
||||||
obj: ShardCommittee, shard_block_hash: Eth2Digest): seq[Uint24] =
|
obj: ShardCommittee, shard_block_root: Eth2Digest): seq[Uint24] =
|
||||||
flatten(
|
flatten(
|
||||||
mapIt(
|
mapIt(
|
||||||
filterIt(concat(this_epoch_attestations, previous_epoch_attestations),
|
filterIt(concat(this_epoch_attestations, previous_epoch_attestations),
|
||||||
it.data.shard == obj.shard and
|
it.data.shard == obj.shard and
|
||||||
it.data.shard_block_hash == shard_block_hash),
|
it.data.shard_block_root == shard_block_root),
|
||||||
get_attestation_participants(statePtr[], it.data, it.participation_bitfield)))
|
get_attestation_participants(statePtr[], it.data, it.participation_bitfield)))
|
||||||
|
|
||||||
func winning_hash(obj: ShardCommittee): Eth2Digest =
|
func winning_hash(obj: ShardCommittee): Eth2Digest =
|
||||||
# * Let `winning_hash(obj)` be the winning `shard_block_hash` value.
|
# * Let `winning_hash(obj)` be the winning `shard_block_root` value.
|
||||||
# ... such that `sum([get_effective_balance(v) for v in attesting_validators(obj, shard_block_hash)])`
|
# ... such that `sum([get_effective_balance(v) for v in attesting_validators(obj, shard_block_root)])`
|
||||||
# is maximized (ties broken by favoring lower `shard_block_hash` values).
|
# is maximized (ties broken by favoring lower `shard_block_root` values).
|
||||||
let candidates =
|
let candidates =
|
||||||
mapIt(
|
mapIt(
|
||||||
filterIt(concat(this_epoch_attestations, previous_epoch_attestations),
|
filterIt(concat(this_epoch_attestations, previous_epoch_attestations),
|
||||||
it.data.shard == obj.shard),
|
it.data.shard == obj.shard),
|
||||||
it.data.shard_block_hash)
|
it.data.shard_block_root)
|
||||||
|
|
||||||
var max_hash = candidates[0]
|
var max_hash = candidates[0]
|
||||||
var max_val =
|
var max_val =
|
||||||
|
@ -351,7 +351,7 @@ func processEpoch(state: var BeaconState, blck: BeaconBlock): bool =
|
||||||
2'u64 * total_balance_sac(obj):
|
2'u64 * total_balance_sac(obj):
|
||||||
state.latest_crosslinks[obj.shard] = CrosslinkRecord(
|
state.latest_crosslinks[obj.shard] = CrosslinkRecord(
|
||||||
slot: state.latest_state_recalculation_slot + EPOCH_LENGTH,
|
slot: state.latest_state_recalculation_slot + EPOCH_LENGTH,
|
||||||
shard_block_hash: winning_hash(obj))
|
shard_block_root: winning_hash(obj))
|
||||||
|
|
||||||
block: # Justification and finalization rewards and penalties
|
block: # Justification and finalization rewards and penalties
|
||||||
let
|
let
|
||||||
|
@ -468,7 +468,7 @@ func processEpoch(state: var BeaconState, blck: BeaconBlock): bool =
|
||||||
|
|
||||||
block: # Final updates
|
block: # Final updates
|
||||||
# TODO Remove all attestation records older than slot `s`.
|
# TODO Remove all attestation records older than slot `s`.
|
||||||
state.latest_block_hashes = state.latest_block_hashes[EPOCH_LENGTH..^1]
|
state.latest_block_roots = state.latest_block_roots[EPOCH_LENGTH..^1]
|
||||||
|
|
||||||
true
|
true
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@ func attestation_signed_data(
|
||||||
slot: int64,
|
slot: int64,
|
||||||
shard_id: int16,
|
shard_id: int16,
|
||||||
parent_hashes: seq[array[32, byte]],
|
parent_hashes: seq[array[32, byte]],
|
||||||
shard_block_hash: array[32, byte],
|
shard_block_root: array[32, byte],
|
||||||
justified_slot: int64
|
justified_slot: int64
|
||||||
): MDigest[256]=
|
): MDigest[256]=
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ func attestation_signed_data(
|
||||||
bigEndian16(be_shard_id.addr, shard_id.unsafeAddr)
|
bigEndian16(be_shard_id.addr, shard_id.unsafeAddr)
|
||||||
ctx.update be_shard_id
|
ctx.update be_shard_id
|
||||||
|
|
||||||
ctx.update shard_block_hash
|
ctx.update shard_block_root
|
||||||
|
|
||||||
var be_justified_slot: array[8, byte]
|
var be_justified_slot: array[8, byte]
|
||||||
bigEndian64(be_justified_slot[0].addr, justified_slot.unsafeAddr)
|
bigEndian64(be_justified_slot[0].addr, justified_slot.unsafeAddr)
|
||||||
|
@ -55,7 +55,7 @@ proc main(nb_samples: Natural) =
|
||||||
slot = rand(4096 .. 4096 + 256) # 256 slots = 1.1 hour
|
slot = rand(4096 .. 4096 + 256) # 256 slots = 1.1 hour
|
||||||
shard_id = int16 rand(high(int16))
|
shard_id = int16 rand(high(int16))
|
||||||
parent_hashes = newSeqWith(num_parent_hashes, randBytes32())
|
parent_hashes = newSeqWith(num_parent_hashes, randBytes32())
|
||||||
shard_block_hash = randBytes32()
|
shard_block_root = randBytes32()
|
||||||
|
|
||||||
echo '\n'
|
echo '\n'
|
||||||
echo "######################"
|
echo "######################"
|
||||||
|
@ -70,7 +70,7 @@ proc main(nb_samples: Natural) =
|
||||||
echo &"Slot: {slot:>64}"
|
echo &"Slot: {slot:>64}"
|
||||||
echo &"Shard_id: {shard_id:>64}"
|
echo &"Shard_id: {shard_id:>64}"
|
||||||
echo &"Parent_hash[0]: {parent_hashes[0].toHex:>64}"
|
echo &"Parent_hash[0]: {parent_hashes[0].toHex:>64}"
|
||||||
echo &"Shard_block_hash: {shard_block_hash.toHex:>64}"
|
echo &"shard_block_root: {shard_block_root.toHex:>64}"
|
||||||
echo &"justified_slot: {justified_slot:>64}"
|
echo &"justified_slot: {justified_slot:>64}"
|
||||||
|
|
||||||
echo '\n'
|
echo '\n'
|
||||||
|
@ -102,7 +102,7 @@ proc main(nb_samples: Natural) =
|
||||||
slot,
|
slot,
|
||||||
shard_id,
|
shard_id,
|
||||||
parent_hashes,
|
parent_hashes,
|
||||||
shard_block_hash,
|
shard_block_root,
|
||||||
justified_slot
|
justified_slot
|
||||||
)
|
)
|
||||||
stop = cpuTime()
|
stop = cpuTime()
|
||||||
|
|
|
@ -64,17 +64,17 @@ suite "Tree hashing":
|
||||||
|
|
||||||
test "Hash ValidatorRecord":
|
test "Hash ValidatorRecord":
|
||||||
let vr = ValidatorRecord()
|
let vr = ValidatorRecord()
|
||||||
check: hashSSZ(vr).len > 0
|
check: hash_tree_root(vr).len > 0
|
||||||
|
|
||||||
test "Hash ShardCommittee":
|
test "Hash ShardCommittee":
|
||||||
let sc = ShardCommittee()
|
let sc = ShardCommittee()
|
||||||
check: hashSSZ(sc).len > 0
|
check: hash_tree_root(sc).len > 0
|
||||||
|
|
||||||
test "Hash BeaconBlock":
|
test "Hash BeaconBlock":
|
||||||
## TODO: Test genesis hash when spec is updated
|
## TODO: Test genesis hash when spec is updated
|
||||||
let bb = BeaconBlock()
|
let bb = BeaconBlock()
|
||||||
check: hashSSZ(bb).len > 0
|
check: hash_tree_root(bb).len > 0
|
||||||
|
|
||||||
test "Hash integer":
|
test "Hash integer":
|
||||||
check: hashSSZ(0x01'u32) == [0'u8, 0, 0, 1] # big endian!
|
check: hash_tree_root(0x01'u32) == [0'u8, 0, 0, 1] # big endian!
|
||||||
check: hashSSZ(Uint24(0x01)) == [0'u8, 0, 1] # big endian!
|
check: hash_tree_root(Uint24(0x01)) == [0'u8, 0, 1] # big endian!
|
||||||
|
|
Loading…
Reference in New Issue