From 9989f2fe560606383352e5063511b3f5791f6dbc Mon Sep 17 00:00:00 2001 From: Mamy Ratsimbazafy Date: Thu, 22 Nov 2018 11:17:05 +0100 Subject: [PATCH] "Stub" hashSSZ function for BeaconBlock (#18) * FIx hash_ssz in the generic case * Add a stub hash function for BeaconBlocks --- beacon_chain/datatypes.nim | 6 ++-- beacon_chain/ssz.nim | 58 ++++++++++++++++++++++++++++++++++++-- tests/test_ssz.nim | 5 ++++ 3 files changed, 63 insertions(+), 6 deletions(-) diff --git a/beacon_chain/datatypes.nim b/beacon_chain/datatypes.nim index f5bd03695..5f0350695 100644 --- a/beacon_chain/datatypes.nim +++ b/beacon_chain/datatypes.nim @@ -44,7 +44,7 @@ type state_root*: Blake2_256_Digest # State root attestations*: seq[AttestationRecord] # Attestations specials*: seq[SpecialRecord] # Specials (e.g. logouts, penalties) - proposer_signature*: Signature # Proposer signature + proposer_signature*: BLSSig # Proposer signature ProposalSignedData* = object fork_version*: uint64 # Fork version @@ -87,8 +87,8 @@ type # Root of data between last hash and this one attester_bitfield*: IntSet # Attester participation bitfield (1 bit per attester) justified_slot*: uint64 # Slot of last justified beacon block - justified_block_hash: Blake2_256_Digest # Hash of last justified beacon block - aggregate_sig*: Signature # BLS aggregate signature + justified_block_hash*: Blake2_256_Digest # Hash of last justified beacon block + aggregate_sig*: BLSSig # BLS aggregate signature BeaconState* = object validator_set_change_slot*: uint64 # Slot of last validator set change diff --git a/beacon_chain/ssz.nim b/beacon_chain/ssz.nim index 344a7cdf8..a4f7c2856 100644 --- a/beacon_chain/ssz.nim +++ b/beacon_chain/ssz.nim @@ -9,7 +9,12 @@ # See https://github.com/ethereum/beacon_chain/issues/100 # and https://github.com/ethereum/beacon_chain/tree/master/ssz -import ./datatypes, eth_common, endians, typetraits, options, nimcrypto +import + endians, typetraits, options, algorithm, + eth_common, nimcrypto, + ./datatypes + +from milagro_crypto import getRaw # ################### Helper functions ################################### @@ -206,7 +211,7 @@ func hashSSZ*(x: ShardAndCommittee): array[32, byte] = h.update hashSSZ(x.shard_id) h.update merkleHash(x.committee) -func hashSSZ*[T](x: T): array[32, byte] = +func hashSSZ*[T: not enum](x: T): array[32, byte] = when T is seq: ## Sequences are tree-hashed return merkleHash(x) @@ -215,12 +220,59 @@ func hashSSZ*[T](x: T): array[32, byte] = # XXX could probaby compile-time-macro-sort fields... var fields: seq[tuple[name: string, value: seq[byte]]] for name, field in x.fieldPairs: - fields.add (name, hashSSZ(field)) + fields.add (name, @(hashSSZ(field))) return withHash: for name, value in fields.sortedByIt(it.name): h.update hashSSZ(value.value) +# ################################# +# HashSSZ not part of official spec +func hashSSZ*(x: enum): array[32, byte] = + ## TODO - Warning ⚠️: not part of the spec + ## as of https://github.com/ethereum/beacon_chain/pull/133/files + ## This is a "stub" needed for BeaconBlock hashing + static: assert x.sizeof == 1 # Check that the enum fits in 1 byte + withHash: + h.update [uint8 x] + +func hashSSZ*(x: BLSsig): array[32, byte] = + ## TODO - Warning ⚠️: not part of the spec + ## as of https://github.com/ethereum/beacon_chain/pull/133/files + ## This is a "stub" needed for BeaconBlock hashing + x.getraw().hash() + +func hashSSZ*(x: AttestationRecord): array[32, byte] = + ## TODO - Warning ⚠️: not part of the spec + ## as of https://github.com/ethereum/beacon_chain/pull/133/files + ## This is a "stub" needed for BeaconBlock hashing + withHash: + h.update hashSSZ(x.slot) + h.update hashSSZ(x.shard) + h.update hashSSZ(x.oblique_parent_hashes) + h.update hashSSZ(x.shard_block_hash) + h.update hashSSZ(x.last_crosslink_hash) + h.update hashSSZ(x.shard_block_combined_data_root) + # h.update hashSSZ(attester_bitfield) # TODO - the bitfield as a specific serialisation format + h.update hashSSZ(x.justified_slot) + h.update hashSSZ(x.justified_block_hash) + h.update hashSSZ(x.aggregate_sig) + +func hashSSZ*(x: BeaconBlock): array[32, byte] = + ## TODO - Warning ⚠️: not part of the spec + ## as of https://github.com/ethereum/beacon_chain/pull/133/files + ## This is a "stub" needed for fork_choice_rule + ## and networking + withHash: + h.update hashSSZ(x.slot) + h.update hashSSZ(x.randao_reveal) + h.update hashSSZ(x.candidate_pow_receipt_root) + h.update hashSSZ(x.ancestor_hashes) + h.update hashSSZ(x.state_root) + h.update hashSSZ(x.attestations) + h.update hashSSZ(x.specials) + h.update hashSSZ(x.proposer_signature) + # ################### Tree hash ################################### func merkleHash[T](lst: seq[T]): array[32, byte] = diff --git a/tests/test_ssz.nim b/tests/test_ssz.nim index e301dc95a..83944170e 100644 --- a/tests/test_ssz.nim +++ b/tests/test_ssz.nim @@ -70,6 +70,11 @@ suite "Tree hashing": let sc = ShardAndCommittee() check: hashSSZ(sc).len > 0 + test "Hash BeaconBlock": + ## TODO: Test genesis hash when spec is updated + let bb = BeaconBlock() + check: hashSSZ(bb).len > 0 + test "Hash integer": check: hashSSZ(0x01'u32) == [0'u8, 0, 0, 1] # big endian! check: hashSSZ(Uint24(0x01)) == [0'u8, 0, 1] # big endian!