Refactor tree hashing (#861)

* Pre-allocated tree hash caches

* Add SmallVec to tree hash cache

* Avoid allocation for validator.pubkey

* Avoid iterator which seems to be doing heap alloc

* Add more smallvecs

* MOAR SMALLVEC

* Move non-test code to Hash256 tree hash

* Fix byte ordering error

* Add incomplete but working merkle stream impl

* Fix zero hash error

* Add zero hash fn

* Add MerkleStream comments

* Add smallvec, tidy

* Integrate into tree hash derive

* Update ssz_types tree hash

* Don't heap alloc for mix in length

* Add byte-level streaming to MerkleStream

* Avoid recursion in write method

* Update BLS to MerkleStream

* Fix some not-compiling tests

* Remove debug profiling

* Remove code duplication

* Move beacon state tree hash to new hasher

* Fix failing tests

* Update comments

* Add some fast-paths to tree_hash::merkle_root

* Remove unncessary test

* Rename MerkleStream -> MerkleHasher

* Rename new_with_leaf_count -> with_leaves

* Tidy

* Remove NonZeroUsize

* Remove todo

* Update smallvec
This commit is contained in:
Paul Hauner
2020-03-05 08:07:27 +11:00
committed by GitHub
parent 12999fb06c
commit 7f6ae4c2f5
43 changed files with 1076 additions and 292 deletions

View File

@@ -31,7 +31,7 @@ pub fn initialize_beacon_state_from_eth1<T: EthSpec>(
for deposit in deposits.iter() {
deposit_tree
.push_leaf(Hash256::from_slice(&deposit.data.tree_hash_root()))
.push_leaf(deposit.data.tree_hash_root())
.map_err(BlockProcessingError::MerkleTreeError)?;
state.eth1_data.deposit_root = deposit_tree.root();
process_deposit(&mut state, &deposit, spec, true)?;

View File

@@ -144,8 +144,7 @@ pub fn process_block_header<T: EthSpec>(
) -> Result<(), BlockOperationError<HeaderInvalid>> {
verify!(block.slot == state.slot, HeaderInvalid::StateSlotMismatch);
let expected_previous_block_root =
Hash256::from_slice(&state.latest_block_header.tree_hash_root());
let expected_previous_block_root = state.latest_block_header.tree_hash_root();
verify!(
block.parent_root == expected_previous_block_root,
HeaderInvalid::ParentBlockRootMismatch {

View File

@@ -50,9 +50,7 @@ impl<T: EthSpec> BlockProcessingBuilder<T> {
match previous_block_root {
Some(root) => builder.set_parent_root(root),
None => builder.set_parent_root(Hash256::from_slice(
&state.latest_block_header.tree_hash_root(),
)),
None => builder.set_parent_root(state.latest_block_header.tree_hash_root()),
}
let proposer_index = state.get_beacon_proposer_index(state.slot, spec).unwrap();
@@ -92,9 +90,7 @@ impl<T: EthSpec> BlockProcessingBuilder<T> {
match previous_block_root {
Some(root) => builder.set_parent_root(root),
None => builder.set_parent_root(Hash256::from_slice(
&state.latest_block_header.tree_hash_root(),
)),
None => builder.set_parent_root(state.latest_block_header.tree_hash_root()),
}
let proposer_index = state.get_beacon_proposer_index(state.slot, spec).unwrap();
@@ -149,9 +145,7 @@ impl<T: EthSpec> BlockProcessingBuilder<T> {
match previous_block_root {
Some(root) => builder.set_parent_root(root),
None => builder.set_parent_root(Hash256::from_slice(
&state.latest_block_header.tree_hash_root(),
)),
None => builder.set_parent_root(state.latest_block_header.tree_hash_root()),
}
let proposer_index = state.get_beacon_proposer_index(state.slot, spec).unwrap();
@@ -192,9 +186,7 @@ impl<T: EthSpec> BlockProcessingBuilder<T> {
match previous_block_root {
Some(root) => builder.set_parent_root(root),
None => builder.set_parent_root(Hash256::from_slice(
&state.latest_block_header.tree_hash_root(),
)),
None => builder.set_parent_root(state.latest_block_header.tree_hash_root()),
}
let proposer_index = state.get_beacon_proposer_index(state.slot, spec).unwrap();
@@ -241,9 +233,7 @@ impl<T: EthSpec> BlockProcessingBuilder<T> {
match previous_block_root {
Some(root) => builder.set_parent_root(root),
None => builder.set_parent_root(Hash256::from_slice(
&state.latest_block_header.tree_hash_root(),
)),
None => builder.set_parent_root(state.latest_block_header.tree_hash_root()),
}
let proposer_index = state.get_beacon_proposer_index(state.slot, spec).unwrap();
@@ -283,9 +273,7 @@ impl<T: EthSpec> BlockProcessingBuilder<T> {
match previous_block_root {
Some(root) => builder.set_parent_root(root),
None => builder.set_parent_root(Hash256::from_slice(
&state.latest_block_header.tree_hash_root(),
)),
None => builder.set_parent_root(state.latest_block_header.tree_hash_root()),
}
let proposer_index = state.get_beacon_proposer_index(state.slot, spec).unwrap();

View File

@@ -62,13 +62,13 @@ pub fn block_proposal_signature_set<'a, T: EthSpec>(
}
.tree_hash_root()
} else {
block.signing_root(domain).as_bytes().to_vec()
block.signing_root(domain)
};
Ok(SignatureSet::single(
&signed_block.signature,
validator_pubkey(state, proposer_index)?,
message,
message.as_bytes().to_vec(),
))
}

View File

@@ -57,7 +57,7 @@ pub fn verify_deposit_merkle_proof<T: EthSpec>(
verify!(
verify_merkle_proof(
Hash256::from_slice(&leaf),
leaf,
&deposit.proof[..],
spec.deposit_contract_tree_depth as usize + 1,
deposit_index as usize,

View File

@@ -172,7 +172,7 @@ pub fn process_final_updates<T: EthSpec>(
let historical_batch = state.historical_batch();
state
.historical_roots
.push(Hash256::from_slice(&historical_batch.tree_hash_root()))?;
.push(historical_batch.tree_hash_root())?;
}
// Rotate current/previous epoch attestations