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

Use parity-common to make substrate generic over hasher and trie encoding codec #297

Merged
merged 95 commits into from
Aug 9, 2018

Conversation

dvdplm
Copy link
Contributor

@dvdplm dvdplm commented Jul 11, 2018

As part of the effort to extract and use common code between parity-ethereum and polkadot, this PR introduces the crates in parity-common which in turn means switch to using generics for the hash type and node encoder and add concrete impls (BlakeHasher and BlakeRlpCodec).
Part of the code is completely generic, e.g. state-machine, whereas other parts use BlakeHasher and BlakeRlpCodec to build concrete types. The exact layering of which parts are generic and which aren't is not very well thought out and feedback on how to improve that is most welcome.

@dvdplm dvdplm changed the title Make generic over Hasher/NodeCodec Make substrate/state-machine generic over Hasher/NodeCodec Jul 11, 2018
@dvdplm dvdplm added A3-in_progress Pull request is in progress. No review needed at this stage. I7-refactor Code needs refactoring. M4-core A0-please_review Pull request needs code review. and removed A3-in_progress Pull request is in progress. No review needed at this stage. labels Jul 11, 2018
gnunicorn
gnunicorn previously approved these changes Jul 12, 2018
Copy link
Contributor

@gnunicorn gnunicorn left a comment

Choose a reason for hiding this comment

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

Minor changes and questions. Aside from that LGTM.

inner: Arc<HashMap<Vec<u8>, Vec<u8>>>,
_hasher: PhantomData<H>,
Copy link
Contributor

Choose a reason for hiding this comment

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

Curious: why did you opt for an underscore here?

Copy link
Contributor Author

@dvdplm dvdplm Jul 12, 2018

Choose a reason for hiding this comment

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

No real good reason. I keep going back and forth on how to name my phantoms, so I end up being inconsistent. Sometimes I like marker, sometimes I name it for what it contains, sometimes with a _ prefix to signal to the reader "never mind this, it's there to make the code compile and is not relevant".

I'd like to have a rule to follow here. What do you use?

Copy link
Contributor

Choose a reason for hiding this comment

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

Clippy states that underscore-prefixed names are expected to be in there for compile-passing-purposes only and aren't actually used. Which is the case here, and combined with a proper descriptive name, I think this is totally the appropriate way to do it, @dvdplm :) .

Copy link
Contributor Author

Choose a reason for hiding this comment

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

"compile-passing-purposes" – rofl

@@ -123,7 +136,7 @@ impl<'a, B: 'a> Externalities for Ext<'a, B>
42
}

fn storage_root(&mut self) -> [u8; 32] {
fn storage_root(&mut self) -> H::Out where H::Out: Ord + Encodable {
Copy link
Contributor

Choose a reason for hiding this comment

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

I know this line isn't super long, however I think it reduces readability complexity if we had the where in the second line

}

impl<H: Hasher> TestExternalities<H> {
#[cfg(test)]
Copy link
Contributor

Choose a reason for hiding this comment

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

is this #[cfg] necessary?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it's wrong. TestExternalities is exported (and re-exported again in runtime-io) so I think it needs to be pub. Good catch.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

…and this change will break things in other crates. I don't think this PR can be merged as-is.

.get_with(key, &mut *proof_recorder).map(|x| x.map(|val| val.to_vec())).map_err(map_e)
}

// TODO: "error[E0283]: type annotations required: cannot resolve `_: patricia_trie::NodeCodec<H>`"/"note: required because of the requirements on the impl of `backend::Backend<H, _>` for `trie_backend::TrieBackend<H>`")
Copy link
Contributor

Choose a reason for hiding this comment

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

Also comments shouldn't be longer than 100chars, please wrap :) .

@@ -4,7 +4,7 @@ version = "0.1.0"
authors = ["Parity Technologies <[email protected]>"]

[dependencies]
ethcore-crypto = { git = "https://github.com/paritytech/parity.git", default_features = false }
parity-crypto = { git = "https://github.com/paritytech/parity-common.git", default_features = false }
Copy link
Contributor

Choose a reason for hiding this comment

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

You missed renaming an import, see travis test.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed, thanks!

dvdplm added 3 commits July 12, 2018 17:07
…bstrate-state-machine-generic

* refactor/environmental-generic-traits:
  whitespace
  Teach environmental! about generics
  Validator side of the collation protocol. (#295)
  Improve Wasm extern errors and increase heap (#299)
  Issue 212 - refactor Checkable trait to be more generic (#287)
  Fix for nightly 2018-07-10 (#296)
  PoC-2 tweaks (#293)
@gnunicorn gnunicorn changed the title Make substrate/state-machine generic over Hasher/NodeCodec [WIP] Make substrate/state-machine generic over Hasher/NodeCodec Jul 12, 2018
@gnunicorn gnunicorn added A3-in_progress Pull request is in progress. No review needed at this stage. and removed A0-please_review Pull request needs code review. labels Jul 12, 2018
@arkpar
Copy link
Member

arkpar commented Jul 13, 2018

Closes #292

@gavofyork gavofyork added A1-onice and removed A3-in_progress Pull request is in progress. No review needed at this stage. labels Jul 15, 2018
@dvdplm dvdplm added A0-please_review Pull request needs code review. and removed A3-in_progress Pull request is in progress. No review needed at this stage. labels Aug 9, 2018
dvdplm added 3 commits August 9, 2018 12:19
* master:
  README: fixed typo in docker run command (#518)
  Merge *_at methods. (#515)
  New flags to listen to all interfaces (#495)
  If contract reaches max depth, return Err (#503)
  Some networking cleanups (#504)
  Derivable Encode & Decode (#509)
  substrate: return Option in all storage related RPC methods (#510)
  Build with locked Cargo.lock on CI (#514)
  Place call data into a newly allocated pages (#502)
@dvdplm dvdplm requested review from svyatonik and rphmeier August 9, 2018 12:02
@svyatonik
Copy link
Contributor

Haven't followed this PR from the beginning, but I wonder - why there are still direct requirements for BlakeHasher/BlakeRlpCodec in substrate (like this one). I thought that the point of the PR is to avoid requirements for concrete implementations in substrate. Probably I'm missing something, but could you please elaborate?

Block: BlockT,
H: Hasher,
Copy link
Member

Choose a reason for hiding this comment

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

reason for not integrating H and C into BlockT?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not sure I understand what you mean here. You mean something like this?

pub trait Block: Clone + Send + Sync + Codec + Eq + MaybeSerializeDebug + 'static {
	type Extrinsic: Member + Codec;
	type Header: Header<Hash=Self::Hash>;
	type Hash: Member + ::rstd::hash::Hash + Copy + MaybeDisplay + Default + SimpleBitOps + Codec + AsRef<[u8]>;
	type Hasher: Hasher<Out=<Self::Hash>::Output>;
	type NodeCodec: NodeCodec<Self::Hasher>;
…

There is some significant overlap between the hashdb::Hasher and substrate own Hash trait and when talking this over with @rphmeier his idea was to get this in first and refine/unify further down the line. Not sure if Block is the proper unification point but might very well be?

fn is_empty_node(data: &[u8]) -> bool {
Rlp::new(data).is_empty()
}
fn empty_node() -> ElasticArray1024<u8> {
Copy link
Member

Choose a reason for hiding this comment

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

get them spaces out of here!!!!


fn branch_node<I>(children: I, value: Option<ElasticArray128<u8>>) -> ElasticArray1024<u8>
where I: IntoIterator<Item=Option<ChildReference<<BlakeHasher as Hasher>::Out>>>
{
Copy link
Member

Choose a reason for hiding this comment

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

gah the indenting is borked. spaces!

@gavofyork
Copy link
Member

gavofyork commented Aug 9, 2018

two concerns:

  1. same as @svyatonik - why do I see BlakeHasher so frequently in substrate - isn't the point to keep it generic? it looks very much like most of the runtime and much of the backend can only be used with BlakeHasher, drastically reducing this PR's benefit.
  2. there's a lot of extra code noise with these changes. i'm thinking of (quite numerous) instances of:
- ) -> Result<(Vec<u8>, B::Transaction), Box<Error>> {
+ ) -> Result<(Vec<u8>, B::Transaction), Box<Error>>
+ where
+ 	H: Hasher,
+ 	C: NodeCodec<H>,
+ 	Exec: CodeExecutor<H>,
+ 	B: Backend<H, C>,
+ 	H::Out: Ord + Encodable,
+ 	Handler: FnOnce(Result<Vec<u8>, Exec::Error>, Result<Vec<u8>, Exec::Error>) -> Result<Vec<u8>, Exec::Error>
+ {

this makes previously quite readable and concise code bloated and boilerplatey.

@dvdplm
Copy link
Contributor Author

dvdplm commented Aug 9, 2018

I thought that the point of the PR is to avoid requirements for concrete implementations in substrate.

Up to a point yes, the goal is to make things generic but the main motivating force was to share code with parity-ethereum. There is something of a "hard limit" as to how generic substrate can be, though. I found it quite tricky to make things generic beyond this here:

environmental!(ext: trait Externalities<BlakeHasher>);

That line can not not use concrete types, and this somewhat limits the extent to which the rest can be generic. I am sure I've missed places that could be generic and instead went for concrete types (do holler if you spot some!).

The result is "a lot of BlakeHasher" all over. I think this can be alleviated in many places with some convenience types but I'd like to address that in a separate PR. I think it is easier to get good review feedback with all the nastiness laid bare and then sweep stuff under the rug in a a phase 2. If you disagree I'm happy to do it right away.

dvdplm added 2 commits August 9, 2018 16:51
…:paritytech/polkadot into refactor/substrate-state-machine-generic

* 'refactor/substrate-state-machine-generic' of github.com:paritytech/polkadot:
  Update Cargo.lock
  Remove safe-mix (#521)
@gavofyork
Copy link
Member

gavofyork commented Aug 9, 2018

ok - make an issue for it and i guess we can revisit.

@gavofyork gavofyork added A6-mustntgrumble and removed A0-please_review Pull request needs code review. labels Aug 9, 2018
@gavofyork gavofyork merged commit d5de4bc into master Aug 9, 2018
@gavofyork gavofyork deleted the refactor/substrate-state-machine-generic branch August 9, 2018 15:37
@gavofyork gavofyork restored the refactor/substrate-state-machine-generic branch August 12, 2018 09:19
lamafab pushed a commit to lamafab/substrate that referenced this pull request Jun 16, 2020
…paritytech#297)

* Make `polkadot-parachain` call `validate_block` instead of `validate`

Also switch to rust 2018 in the crate

* Use `rstd`

* Make `load_params` a pointer
JoshOrndorff pushed a commit to moonbeam-foundation/substrate that referenced this pull request Apr 21, 2021
* from 8 to 25

* bump spec version

* Update runtime/src/lib.rs
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
I7-refactor Code needs refactoring.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants