Skip to content
This repository has been archived by the owner on Nov 6, 2020. It is now read-only.

Make HashDB generic #8739

Merged
merged 185 commits into from
Jul 2, 2018
Merged

Make HashDB generic #8739

merged 185 commits into from
Jul 2, 2018

Conversation

dvdplm
Copy link
Collaborator

@dvdplm dvdplm commented May 30, 2018

The aim of this PR is to make patricia-trie usable from Polkadot by making it generic over both the hashing algorithm and the encoding scheme (currently Keccak-256 and RLP).

Part of #7019 and #8620

The HashDB trait – the basis of the various Trie DB types – is made generic over the hashing algorithm and output format by introducing a new Hasher trait and threading it throughout the crates using it.
With the NodeCodec trait we encapsulate the information needed to encode/decode a trie node. The NodeCodec trait is generic over the Hasher as well.

The concrete implementations we need in Parity for Keccak-256 and RLP, are provided in two new mini-crates: keccak-hasher and patricia-trie-ethereum. Here we also provide type aliases for Result and TrieError.

Benchmark compared to master:

 name                        master ns/iter  PR ns/iter        diff ns/iter  diff %  speedup
 trie_insertions_32_mir_1k   2,230,153        2,217,779            -12,374  -0.55%   x 1.01
 trie_insertions_32_ran_1k   2,216,102        2,231,613             15,511   0.70%   x 0.99
 trie_insertions_random_mid  1,556,671        1,578,555             21,884   1.41%   x 0.99
 trie_insertions_six_high    1,604,928        1,643,805             38,877   2.42%   x 0.98
 trie_insertions_six_low     3,049,674        3,090,029             40,355   1.32%   x 0.99
 trie_insertions_six_mid     2,048,429        2,059,450             11,021   0.54%   x 0.99
 trie_iter                   1,581,328        1,549,457            -31,871  -2.02%   x 1.02

dvdplm added 23 commits May 26, 2018 22:23
Add associated const to Hasher for the fast-path
Make HashDB impl for MemoryDB generic
Make H256FastMap generic (eew)
Bump version to 0.2.0

**NOTE** Hard coded to use `KeccakHasher`
…eric

* origin/master:
  Fix local transactions policy. (#8691)
  Shutdown the Snapshot Service early (#8658)
  network-devp2p: handle UselessPeer disconnect (#8686)
  Fix compilation error on nightly rust (#8707)
  Add a test for decoding corrupt data (#8713)
  Update dev chain (#8717)
  Remove unused imports (#8722)
@dvdplm dvdplm self-assigned this May 30, 2018
@dvdplm dvdplm added the A0-pleasereview 🤓 Pull request needs code review. label May 30, 2018

/// `HashDB` value type.
pub type DBValue = ElasticArray128<u8>;

/// Trait modelling datastore keyed by a 32-byte Keccak hash.
pub trait HashDB: AsHashDB + Send + Sync {
pub trait HashDB: Send + Sync {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How do I best fit in AsHashDB in this? It takes a Hasher now (see below), but not sure how to make pass the type argument.

},
IterStep::Descend(Err(e)) => {
return Some(Err(e))
IterStep::Descend::<H::Out>(Err(e)) => {
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Help needed here.

@@ -154,6 +156,7 @@ impl<'a> NibbleSlice<'a> {
}

/// Encode while nibble slice in prefixed hex notation, noting whether it `is_leaf`.
#[inline(always)]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is non-trivial and so I'd probably annotate it #[inline] so LLVM can make the choice to inline or not itself. #[inline(always)] is only for really trivial functions that are really hot but you have profiled to see are not being inlined automatically (like len below) and should be used with care. Although if you've benchmarked this and found that the (always) is necessary then ignore this comment, of course!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It did show up in the traces and looked suspicious, but now that I try again it doesn't seem to make any difference at all so dialing back to just #[inline] makes sense. :)

use trie::recorder::Recorder;

// pub fn prove_storage(&self, db: &HashDB<KeccakHasher>, storage_key: H256) -> Result<(Vec<Bytes>, H256), Box<TrieError<<KeccakHasher as Hasher>::Out>>> {
// pub fn prove_storage(&self, db: &HashDB<KeccakHasher>, storage_key: H256) -> Result<(Vec<Bytes>, H256), Box<TrieError>> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

obsolete?

AccountDB {
db: db,
address_hash: address_hash,
}
}
}

impl<'db> HashDB for AccountDB<'db>{
impl<'db> AsHashDB<KeccakHasher> for AccountDB<'db> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure whether it is possible to eliminate this boilerplate, due to super-trait upcasting still being an unresolved issue in rust (https://github.com/rust-lang/rust/issues/5665). But maybe we can ease that pain by using a macro?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can file a refactor issue but I wouldn't call this a blocker for this PR

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added here: #9022

@@ -309,13 +311,15 @@ impl StateDB {
}
}

// TODO: needed?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used in ethcore/src/client/client.rs:1688:52.

self.db.as_hashdb()
}

// TODO: needed?
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Used in ethcore/src/client/client.rs:613:62.

let node = Node::from_rlp(&node_rlp, &*self.db, &mut self.storage);
fn cache(&mut self, hash: H::Out) -> Result<StorageHandle, H::Out, C::Error> {
let node_encoded = self.db.get(&hash).ok_or_else(|| TrieError::IncompleteDatabase(hash))?;
// let node_encoded = self.db.get(&hash).ok_or_else(|| Box::new(TrieError::IncompleteDatabase(hash)))?;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

obsolete?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this one's actually wrong, good catch.

* master:
  Minimal effective gas price in the queue (#8934)
  parity: fix db path when migrating to blooms db (#8975)
  Preserve the current abort behavior (#8995)
  Improve should_replace on NonceAndGasPrice (#8980)
  Tentative fix for missing dependency error (#8973)
@rphmeier
Copy link
Contributor

rphmeier commented Jul 2, 2018

LGTM after a merge and some extra whitespace cleanup.

Copy link
Collaborator

@ordian ordian left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo unresolved conflicts

@5chdn 5chdn added A7-looksgoodcantmerge 🙄 Pull request is reviewed well, but cannot be merged due to conflicts. and removed A0-pleasereview 🤓 Pull request needs code review. labels Jul 2, 2018
@5chdn
Copy link
Contributor

5chdn commented Jul 2, 2018

@dvdplm please resolve conflicts 💪

* master:
  Attempt to graceful shutdown in case of panics (#8999)
  simplify kvdb error types (#8924)
  Add option for user to set max size limit for RPC requests (#9010)
  bump ntp to 0.5.0 (#9009)
  Removed duplicate dependency (#9021)
* master:
  Only return error log for rustls (#9025)
  Update Changelogs for 1.10.8 and 1.11.5 (#9012)
@dvdplm dvdplm merged commit 9caa868 into master Jul 2, 2018
@debris debris deleted the refactor/hashdb-generic branch July 2, 2018 17:00
ordian added a commit to ordian/parity that referenced this pull request Jul 9, 2018
…rp_sync_on_light_client

* 'master' of https://github.com/paritytech/parity:
  Never drop local transactions from different senders. (openethereum#9002)
  Precise HTTP or WebSockets for JSON-RPC options (openethereum#9027)
  Recently rejected cache for transaction queue (openethereum#9005)
  Make HashDB generic (openethereum#8739)
  Only return error log for rustls (openethereum#9025)
  Update Changelogs for 1.10.8 and 1.11.5 (openethereum#9012)
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
A7-looksgoodcantmerge 🙄 Pull request is reviewed well, but cannot be merged due to conflicts. M4-core ⛓ Core client code / Rust.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants