rename hash tree roots as root
This commit is contained in:
parent
defe2668a0
commit
e0e2fed1b5
|
@ -64,7 +64,7 @@
|
|||
- [`clamp`](#clamp)
|
||||
- [`get_new_shuffling`](#get_new_shuffling)
|
||||
- [`get_shard_committees_at_slot`](#get_shard_committees_at_slot)
|
||||
- [`get_block_hash`](#get_block_hash)
|
||||
- [`get_block_root`](#get_block_root)
|
||||
- [`get_beacon_proposer_index`](#get_beacon_proposer_index)
|
||||
- [`get_updated_ancestor_hashes`](#get_updated_ancestor_hashes)
|
||||
- [`get_attestation_participants`](#get_attestation_participants)
|
||||
|
@ -73,7 +73,7 @@
|
|||
- [`get_new_validator_registry_delta_chain_tip`](#get_new_validator_registry_delta_chain_tip)
|
||||
- [`get_fork_version`](#get_fork_version)
|
||||
- [`get_domain`](#get_domain)
|
||||
- [`SSZTreeHash`](#ssztreehash)
|
||||
- [`hash_tree_root`](#hash_tree_root)
|
||||
- [`verify_casper_votes`](#verify_casper_votes)
|
||||
- [`integer_squareroot`](#integer_squareroot)
|
||||
- [`BLSVerify`](#blsverify)
|
||||
|
@ -322,7 +322,7 @@ Unless otherwise indicated, code appearing in `this style` is to be interpreted
|
|||
# Slot of the last justified beacon block
|
||||
'justified_slot': 'uint64',
|
||||
# Hash of the last justified beacon block
|
||||
'justified_block_hash': 'hash32',
|
||||
'justified_block_root': 'hash32',
|
||||
}
|
||||
```
|
||||
|
||||
|
@ -655,7 +655,7 @@ Processing the beacon chain is similar to processing the Ethereum 1.0 chain. Cli
|
|||
|
||||
For a beacon chain block, `block`, to be processed by a node, the following conditions must be met:
|
||||
|
||||
* The parent block with `SSZTreeHash` `block.ancestor_hashes[0]` has been processed and accepted.
|
||||
* The parent block with `hash_tree_root` `block.ancestor_hashes[0]` has been processed and accepted.
|
||||
* The node has processed its `state` up to slot, `block.slot - 1`.
|
||||
* The Ethereum 1.0 block pointed to by the `state.processed_pow_receipt_root` has been processed and accepted.
|
||||
* The node's local clock time is greater than or equal to `state.genesis_time + block.slot * SLOT_DURATION`.
|
||||
|
@ -869,10 +869,10 @@ def get_shard_committees_at_slot(state: BeaconState,
|
|||
return state.shard_committees_at_slots[slot - earliest_slot_in_array]
|
||||
```
|
||||
|
||||
#### `get_block_hash`
|
||||
#### `get_block_root`
|
||||
|
||||
```python
|
||||
def get_block_hash(state: BeaconState,
|
||||
def get_block_root(state: BeaconState,
|
||||
slot: int) -> Hash32:
|
||||
"""
|
||||
Returns the block hash at a recent ``slot``.
|
||||
|
@ -882,7 +882,7 @@ def get_block_hash(state: BeaconState,
|
|||
return state.latest_block_hashes[slot - earliest_slot_in_array]
|
||||
```
|
||||
|
||||
`get_block_hash(_, s)` should always return `SSZTreeHash` of the block in the beacon chain at slot `s`, and `get_shard_committees_at_slot(_, s)` should not change unless the [validator](#dfn-validator) registry changes.
|
||||
`get_block_root(_, s)` should always return `hash_tree_root` of the block in the beacon chain at slot `s`, and `get_shard_committees_at_slot(_, s)` should not change unless the [validator](#dfn-validator) registry changes.
|
||||
|
||||
#### `get_beacon_proposer_index`
|
||||
|
||||
|
@ -987,9 +987,9 @@ def get_domain(fork_data: ForkData,
|
|||
) * 2**32 + domain_type
|
||||
```
|
||||
|
||||
#### `SSZTreeHash`
|
||||
#### `hash_tree_root`
|
||||
|
||||
`SSZTreeHash` is a function for hashing objects into a single root utilizing a hash tree structure. `SSZTreeHash` is defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#tree-hash).
|
||||
`hash_tree_root` is a function for hashing objects into a single root utilizing a hash tree structure. `hash_tree_root` is defined in the [SimpleSerialize spec](https://github.com/ethereum/eth2.0-specs/blob/master/specs/simple-serialize.md#tree-hash).
|
||||
|
||||
#### `verify_casper_votes`
|
||||
|
||||
|
@ -1000,7 +1000,7 @@ def verify_casper_votes(state: BeaconState, votes: SlashableVoteData) -> bool:
|
|||
|
||||
pubs = [aggregate_pubkey([state.validators[i].pubkey for i in votes.aggregate_signature_poc_0_indices]),
|
||||
aggregate_pubkey([state.validators[i].pubkey for i in votes.aggregate_signature_poc_1_indices])]
|
||||
return BLSMultiVerify(pubkeys=pubs, msgs=[SSZTreeHash(votes)+bytes1(0), SSZTreeHash(votes)+bytes1(1), sig=aggregate_signature)
|
||||
return BLSMultiVerify(pubkeys=pubs, msgs=[hash_tree_root(votes)+bytes1(0), hash_tree_root(votes)+bytes1(1), sig=aggregate_signature)
|
||||
```
|
||||
|
||||
#### `integer_squareroot`
|
||||
|
@ -1292,9 +1292,9 @@ def exit_validator(state: BeaconState,
|
|||
Below are the processing steps that happen at every slot.
|
||||
|
||||
* Let `latest_block` be the latest `BeaconBlock` that was processed in the chain.
|
||||
* Let `latest_hash` be the `SSZTreeHash` of `latest_block`.
|
||||
* Let `latest_hash` be the `hash_tree_root` of `latest_block`.
|
||||
* Set `state.slot += 1`
|
||||
* Set `state.latest_block_hashes = state.latest_block_hashes + [latest_hash]`. (The output of `get_block_hash` should not change, except that it will no longer throw for `state.slot - 1`).
|
||||
* Set `state.latest_block_hashes = state.latest_block_hashes + [latest_hash]`. (The output of `get_block_root` should not change, except that it will no longer throw for `state.slot - 1`).
|
||||
|
||||
If there is a block from the proposer for `state.slot`, we process that incoming block:
|
||||
|
||||
|
@ -1309,8 +1309,8 @@ If there is no block from the proposer at state.slot:
|
|||
|
||||
### Proposer signature
|
||||
|
||||
* Let `block_hash_without_sig` be the `SSZTreeHash` of `block` where `block.signature` is set to `[0, 0]`.
|
||||
* Let `proposal_hash = SSZTreeHash(ProposalSignedData(state.slot, BEACON_CHAIN_SHARD_NUMBER, block_hash_without_sig))`.
|
||||
* Let `block_hash_without_sig` be the `hash_tree_root` of `block` where `block.signature` is set to `[0, 0]`.
|
||||
* Let `proposal_hash = hash_tree_root(ProposalSignedData(state.slot, BEACON_CHAIN_SHARD_NUMBER, block_hash_without_sig))`.
|
||||
* Verify that `BLSVerify(pubkey=state.validator_registry[get_beacon_proposer_index(state, state.slot)].pubkey, data=proposal_hash, sig=block.signature, domain=get_domain(state.fork_data, state.slot, DOMAIN_PROPOSAL))`.
|
||||
|
||||
### RANDAO
|
||||
|
@ -1336,8 +1336,8 @@ Verify that `len(block.body.proposer_slashings) <= MAX_PROPOSER_SLASHINGS`.
|
|||
For each `proposer_slashing` in `block.body.proposer_slashings`:
|
||||
|
||||
* Let `proposer = state.validator_registry[proposer_slashing.proposer_index]`.
|
||||
* Verify that `BLSVerify(pubkey=proposer.pubkey, msg=SSZTreeHash(proposer_slashing.proposal_data_1), sig=proposer_slashing.proposal_signature_1, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_1.slot, DOMAIN_PROPOSAL))`.
|
||||
* Verify that `BLSVerify(pubkey=proposer.pubkey, msg=SSZTreeHash(proposer_slashing.proposal_data_2), sig=proposer_slashing.proposal_signature_2, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_2.slot, DOMAIN_PROPOSAL))`.
|
||||
* Verify that `BLSVerify(pubkey=proposer.pubkey, msg=hash_tree_root(proposer_slashing.proposal_data_1), sig=proposer_slashing.proposal_signature_1, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_1.slot, DOMAIN_PROPOSAL))`.
|
||||
* Verify that `BLSVerify(pubkey=proposer.pubkey, msg=hash_tree_root(proposer_slashing.proposal_data_2), sig=proposer_slashing.proposal_signature_2, domain=get_domain(state.fork_data, proposer_slashing.proposal_data_2.slot, DOMAIN_PROPOSAL))`.
|
||||
* Verify that `proposer_slashing.proposal_data_1.slot == proposer_slashing.proposal_data_2.slot`.
|
||||
* Verify that `proposer_slashing.proposal_data_1.shard == proposer_slashing.proposal_data_2.shard`.
|
||||
* Verify that `proposer_slashing.proposal_data_1.block_hash != proposer_slashing.proposal_data_2.block_hash`.
|
||||
|
@ -1368,12 +1368,12 @@ For each `attestation` in `block.body.attestations`:
|
|||
* Verify that `attestation.data.slot + MIN_ATTESTATION_INCLUSION_DELAY <= state.slot`.
|
||||
* Verify that `attestation.data.slot + EPOCH_LENGTH >= state.slot`.
|
||||
* Verify that `attestation.data.justified_slot` is equal to `state.justified_slot if attestation.data.slot >= state.slot - (state.slot % EPOCH_LENGTH) else state.previous_justified_slot`.
|
||||
* Verify that `attestation.data.justified_block_hash` is equal to `get_block_hash(state, attestation.data.justified_slot)`.
|
||||
* Verify that `attestation.data.justified_block_root` is equal to `get_block_root(state, attestation.data.justified_slot)`.
|
||||
* Verify that either `attestation.data.latest_crosslink_hash` or `attestation.data.shard_block_hash` equals `state.latest_crosslinks[shard].shard_block_hash`.
|
||||
* `aggregate_signature` verification:
|
||||
* Let `participants = get_attestation_participants(state, attestation.data, attestation.participation_bitfield)`.
|
||||
* Let `group_public_key = BLSAddPubkeys([state.validator_registry[v].pubkey for v in participants])`.
|
||||
* Verify that `BLSVerify(pubkey=group_public_key, msg=SSZTreeHash(attestation.data) + bytes1(0), sig=attestation.aggregate_signature, domain=get_domain(state.fork_data, attestation.data.slot, DOMAIN_ATTESTATION))`.
|
||||
* Verify that `BLSVerify(pubkey=group_public_key, msg=hash_tree_root(attestation.data) + bytes1(0), sig=attestation.aggregate_signature, domain=get_domain(state.fork_data, attestation.data.slot, DOMAIN_ATTESTATION))`.
|
||||
* [TO BE REMOVED IN PHASE 1] Verify that `attestation.data.shard_block_hash == ZERO_HASH`.
|
||||
* Append `PendingAttestationRecord(data=attestation.data, participation_bitfield=attestation.participation_bitfield, custody_bitfield=attestation.custody_bitfield, slot_included=state.slot)` to `state.latest_attestations`.
|
||||
|
||||
|
@ -1457,7 +1457,7 @@ All [validators](#dfn-validator):
|
|||
[Validators](#dfn-Validator) justifying the epoch boundary block at the start of the current epoch:
|
||||
|
||||
* Let `this_epoch_attestations = [a for a in state.latest_attestations if state.slot - EPOCH_LENGTH <= a.data.slot < state.slot]`. (Note: this is the set of attestations of slots in the epoch `state.slot-EPOCH_LENGTH...state.slot-1`, _not_ attestations that got included in the chain during the epoch `state.slot-EPOCH_LENGTH...state.slot-1`.)
|
||||
* Let `this_epoch_boundary_attestations = [a for a in this_epoch_attestations if a.data.epoch_boundary_hash == get_block_hash(state, state.slot-EPOCH_LENGTH) and a.justified_slot == state.justified_slot]`.
|
||||
* Let `this_epoch_boundary_attestations = [a for a in this_epoch_attestations if a.data.epoch_boundary_hash == get_block_root(state, state.slot-EPOCH_LENGTH) and a.justified_slot == state.justified_slot]`.
|
||||
* Let `this_epoch_boundary_attester_indices` be the union of the [validator](#dfn-validator) index sets given by `[get_attestation_participants(state, a.data, a.participation_bitfield) for a in this_epoch_boundary_attestations]`.
|
||||
* Let `this_epoch_boundary_attesters = [state.validator_registry[i] for indices in this_epoch_boundary_attester_indices for i in indices]`.
|
||||
* Let `this_epoch_boundary_attesting_balance = sum([get_effective_balance(v) for v in this_epoch_boundary_attesters])`.
|
||||
|
@ -1465,7 +1465,7 @@ All [validators](#dfn-validator):
|
|||
[Validators](#dfn-Validator) justifying the epoch boundary block at the start of the previous epoch:
|
||||
|
||||
* Let `previous_epoch_attestations = [a for a in state.latest_attestations if state.slot - 2 * EPOCH_LENGTH <= a.slot < state.slot - EPOCH_LENGTH]`.
|
||||
* Let `previous_epoch_boundary_attestations = [a for a in this_epoch_attestations + previous_epoch_attestations if a.epoch_boundary_hash == get_block_hash(state, state.slot - 2 * EPOCH_LENGTH) and a.justified_slot == state.previous_justified_slot]`.
|
||||
* Let `previous_epoch_boundary_attestations = [a for a in this_epoch_attestations + previous_epoch_attestations if a.epoch_boundary_hash == justified_block_root(state, state.slot - 2 * EPOCH_LENGTH) and a.justified_slot == state.previous_justified_slot]`.
|
||||
* Let `previous_epoch_boundary_attester_indices` be the union of the validator index sets given by `[get_attestation_participants(state, a.data, a.participation_bitfield) for a in previous_epoch_boundary_attestations]`.
|
||||
* Let `previous_epoch_boundary_attesters = [state.validator_registry[i] for indices in previous_epoch_boundary_attester_indices for i in indices]`.
|
||||
* Let `previous_epoch_boundary_attesting_balance = sum([get_effective_balance(v) for v in previous_epoch_boundary_attesters])`.
|
||||
|
@ -1660,7 +1660,7 @@ while len(state.persistent_committee_reassignments) > 0 and state.persistent_com
|
|||
|
||||
## State root processing
|
||||
|
||||
Verify `block.state_root == SSZTreeHash(state)` if there exists a `block` for the slot being processed.
|
||||
Verify `block.state_root == hash_tree_root(state)` if there exists a `block` for the slot being processed.
|
||||
|
||||
# Appendix
|
||||
## Appendix A - Hash function
|
||||
|
|
|
@ -41,7 +41,7 @@ A `ShardBlock` object has the following fields:
|
|||
# What shard is it on
|
||||
'shard_id': 'uint64',
|
||||
# Parent block hash
|
||||
'parent_hash': 'hash32',
|
||||
'parent_root': 'hash32',
|
||||
# Beacon chain block
|
||||
'beacon_chain_ref': 'hash32',
|
||||
# Depth of the Merkle tree
|
||||
|
@ -62,16 +62,16 @@ A `ShardBlock` object has the following fields:
|
|||
|
||||
For a block on a shard to be processed by a node, the following conditions must be met:
|
||||
|
||||
* The `ShardBlock` pointed to by `parent_hash` has already been processed and accepted
|
||||
* The `ShardBlock` pointed to by `parent_root` has already been processed and accepted
|
||||
* The signature for the block from the _proposer_ (see below for definition) of that block is included along with the block in the network message object
|
||||
|
||||
To validate a block header on shard `shard_id`, compute as follows:
|
||||
|
||||
* Verify that `beacon_chain_ref` is the hash of a block in the beacon chain with slot less than or equal to `slot`. Verify that `beacon_chain_ref` is equal to or a descendant of the `beacon_chain_ref` specified in the `ShardBlock` pointed to by `parent_hash`.
|
||||
* Verify that `beacon_chain_ref` is the hash of a block in the beacon chain with slot less than or equal to `slot`. Verify that `beacon_chain_ref` is equal to or a descendant of the `beacon_chain_ref` specified in the `ShardBlock` pointed to by `parent_root`.
|
||||
* Let `state` be the state of the beacon chain block referred to by `beacon_chain_ref`. Let `validators` be `[validators[i] for i in state.current_persistent_committees[shard_id]]`.
|
||||
* Assert `len(attester_bitfield) == ceil_div8(len(validators))`
|
||||
* Let `proposer_index = hash(state.randao_mix + bytes8(shard_id) + bytes8(slot)) % len(validators)`. Let `msg` be the block but with the `block.signature` set to `[0, 0]`. Verify that `BLSVerify(pub=validators[proposer_index].pubkey, msg=hash(msg), sig=block.signature, domain=get_domain(state, slot, SHARD_PROPOSER_DOMAIN))` passes.
|
||||
* Generate the `group_public_key` by adding the public keys of all the validators for whom the corresponding position in the bitfield is set to 1. Verify that `BLSVerify(pub=group_public_key, msg=parent_hash, sig=block.aggregate_sig, domain=get_domain(state, slot, SHARD_ATTESTER_DOMAIN))` passes.
|
||||
* Generate the `group_public_key` by adding the public keys of all the validators for whom the corresponding position in the bitfield is set to 1. Verify that `BLSVerify(pub=group_public_key, msg=parent_root, sig=block.aggregate_sig, domain=get_domain(state, slot, SHARD_ATTESTER_DOMAIN))` passes.
|
||||
|
||||
### Block Merklization helper
|
||||
|
||||
|
|
|
@ -390,7 +390,7 @@ return typ(**values), item_index
|
|||
|
||||
### Tree Hash
|
||||
|
||||
The below `SSZTreeHash` algorithm is defined recursively in the case of lists and containers, and it outputs a value equal to or less than 32 bytes in size. For the final output only (ie. not intermediate outputs), if the output is less than 32 bytes, right-zero-pad it to 32 bytes. The goal is collision resistance *within* each type, not between types.
|
||||
The below `hash_tree_root` algorithm is defined recursively in the case of lists and containers, and it outputs a value equal to or less than 32 bytes in size. For the final output only (ie. not intermediate outputs), if the output is less than 32 bytes, right-zero-pad it to 32 bytes. The goal is collision resistance *within* each type, not between types.
|
||||
|
||||
Refer to [Appendix A](https://github.com/ethereum/eth2.0-specs/blob/master/specs/core/0_beacon-chain.md#appendix-a---hash-function) of Phase 0 of the [Eth2.0 specs](https://github.com/ethereum/eth2.0-specs) for a definition of the hash function used below, `hash(x)`.
|
||||
|
||||
|
@ -435,13 +435,13 @@ def merkle_hash(lst):
|
|||
return hash(chunkz[0] + datalen)
|
||||
```
|
||||
|
||||
To `SSZTreeHash` a list, we simply do:
|
||||
To `hash_tree_root` a list, we simply do:
|
||||
|
||||
```python
|
||||
return merkle_hash([SSZTreeHash(item) for item in value])
|
||||
return merkle_hash([hash_tree_root(item) for item in value])
|
||||
```
|
||||
|
||||
Where the inner `SSZTreeHash` is a recursive application of the tree-hashing function (returning less than 32 bytes for short single values).
|
||||
Where the inner `hash_tree_root` is a recursive application of the tree-hashing function (returning less than 32 bytes for short single values).
|
||||
|
||||
|
||||
#### Container
|
||||
|
@ -449,7 +449,7 @@ Where the inner `SSZTreeHash` is a recursive application of the tree-hashing fun
|
|||
Recursively tree hash the values in the container in order sorted by key, and return the hash of the concatenation of the results.
|
||||
|
||||
```python
|
||||
return hash(b''.join([SSZTreeHash(getattr(x, field)) for field in sorted(value.fields)))
|
||||
return hash(b''.join([hash_tree_root(getattr(x, field)) for field in sorted(value.fields)))
|
||||
```
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue