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

Conversation

@marcio-diaz
Copy link
Contributor

PR for issue #1448

@marcio-diaz marcio-diaz added the A3-in_progress Pull request is in progress. No review needed at this stage. label Jan 29, 2019
bkchr
bkchr previously requested changes Jan 29, 2019
fn commit_operation(&self, mut operation: Self::BlockImportOperation)
-> Result<(), client::error::Error>
{
println!("db inside commit_operation ----------------------------");
Copy link
Member

Choose a reason for hiding this comment

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

Debug output.

{
let mut leaves = self.blockchain.leaves.write();
let displaced_leaf = leaves.import(hash, number, parent_hash);
println!("db prepare_transaction --------------- {:?}->{:?}", parent_hash, hash);
Copy link
Member

Choose a reason for hiding this comment

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

Debug output.

@@ -0,0 +1,161 @@
// Copyright 2018 Parity Technologies (UK) Ltd.
Copy link
Member

Choose a reason for hiding this comment

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

K: Ord + Eq + Hash + Clone + Encode + Decode + Debug,
V: Ord + Eq + Hash + Clone + Encode + Decode + Debug,
{
storage: BTreeMap<K, Vec<V>>,
Copy link
Member

Choose a reason for hiding this comment

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

Spaces all over the file.

for (parent, child) in self.pending_added.drain(..) {
parent.using_encoded(|s| buf.extend(s));
tx.put_vec(column, &buf[..], child.encode());
buf.truncate(prefix.len()); // reuse allocation.
Copy link
Member

Choose a reason for hiding this comment

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

Why do you truncate here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because prefix is the same but parent and child change.

Copy link
Contributor

Choose a reason for hiding this comment

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

also it looks like some spaces got into the indentation for L98 -- please make sure that indentation is done with tabs

}
}

pub fn hashes(&self, parent_hash: K) -> Vec<V> {
Copy link
Member

Choose a reason for hiding this comment

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

Why do we not return &[V]?

pub fn lock_import_and_run<R, F: FnOnce(&mut ClientImportOperation<Block, Blake2Hasher, B>) -> error::Result<R>>(
&self, f: F
) -> error::Result<R> {
println!("in lock_import_and_run ------------------------------------------------");
Copy link
Member

Choose a reason for hiding this comment

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

Debug.


fn get_descendants(&self, target: Block::Hash) -> Vec<Block::Hash> {
let children = self.backend.blockchain().children(target);
let mut descendants = vec![];
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
let mut descendants = vec![];
let mut descendants = Vec::new();

if ancestors.contains(&uncles[i]) {
uncles.remove(i);
} else {
i += 1;
Copy link
Member

Choose a reason for hiding this comment

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

Why is it only increased in the else branch?

@marcio-diaz marcio-diaz force-pushed the mar-client-provide-uncles branch from 388f553 to bdcde73 Compare February 1, 2019 14:25
@marcio-diaz marcio-diaz 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 Feb 1, 2019
K: Ord + Eq + Hash + Clone + Encode + Decode + Debug,
V: Ord + Eq + Hash + Clone + Encode + Decode + Debug,
{
storage: BTreeMap<K, Vec<V>>,
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 storing all children in memory? that doesn't seem like it will scale very well.
This mapping should be on-disk only -- I don't think emulating the LeavesSet is a good idea for this instance.

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 removed the part where it reads all children from db :). I'm adding children everywhere where leaves are being added. Are there other parts of the code where I should add them?

@gavofyork gavofyork added A5-grumble and removed A0-please_review Pull request needs code review. labels Feb 3, 2019
@marcio-diaz marcio-diaz added A0-please_review Pull request needs code review. and removed A5-grumble labels Feb 5, 2019

/// Gets the uncles of the block with `target_hash` going back `max_generation` ancestors.
pub fn uncles(&self, target_hash: Block::Hash, max_generation: NumberFor<Block>)
-> error::Result<Option<Vec<Block::Hash>>>
Copy link
Member

Choose a reason for hiding this comment

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

We do not return any Ok(None), so we probably can remove the Option here.

-> error::Result<Option<Vec<Block::Hash>>>
{
let load_header = |id: Block::Hash| {
match self.backend.blockchain().header(BlockId::Hash(id)) {
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
match self.backend.blockchain().header(BlockId::Hash(id)) {
match self.backend.blockchain().header(BlockId::Hash(id))? {

And the you just need to match for Some(_) and None.

let genesis_hash = self.backend.blockchain().info().unwrap().genesis_hash;
let genesis = load_header(genesis_hash)?;
let mut current = load_header(target_hash)?;
let mut uncles = vec![];
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
let mut uncles = vec![];
let mut uncles = Vec::new();

@gavofyork
Copy link
Member

@rphmeier @bkchr further thoughts?

match self.storage.get_mut(&parent_hash) {
Some(children) => children.push(child_hash),
None => {
self.storage.insert(parent_hash, vec![child_hash]);
Copy link
Contributor

Choose a reason for hiding this comment

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

use entry API. self.storage.entry(parent_hash).or_insert_with(Vec::new).push(child_hash)

/// Returns the hashes of the children blocks of the block with `parent_hash`.
/// It doesn't read the database.
pub fn hashes_from_mem(&self, parent_hash: K) -> Vec<V> {
match self.storage.get(&parent_hash) {
Copy link
Contributor

Choose a reason for hiding this comment

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

use unwrap_or_else

Copy link
Member

Choose a reason for hiding this comment

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

*cloned().unwrap_or_default()

Copy link
Contributor

Choose a reason for hiding this comment

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

🤷‍♂️ mine is shorter :)


let mut buf = prefix.to_vec();
parent_hash.using_encoded(|s| buf.extend(s));
let raw_val = match db.get(column, &buf[..]).unwrap() {
Copy link
Contributor

@rphmeier rphmeier Feb 12, 2019

Choose a reason for hiding this comment

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

prove or remove unwrap.


/// Abstraction around hashing
pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq { // Stupid bug in the Rust compiler believes derived
pub trait Hash: 'static + MaybeSerializeDebug + Clone + Eq + PartialEq + PartialOrd + Ord { // Stupid bug in the Rust compiler believes derived
Copy link
Contributor

Choose a reason for hiding this comment

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

that's a bit too strong IMO.

Copy link
Contributor

Choose a reason for hiding this comment

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

why should hash types always be orderable?

}
};

let genesis_hash = self.backend.blockchain().info().unwrap().genesis_hash;
Copy link
Contributor

Choose a reason for hiding this comment

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

prove or remove unwrap

let mut descendants = Vec::new();
for child in children {
descendants.push(child);
let d = self.get_descendants(child, None)?;
Copy link
Contributor

Choose a reason for hiding this comment

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

won't this recurse all the way to the head of all descendant chains? could be expensive.

for _generation in 0..max_generation.as_() {
uncles.extend(self.get_descendants(ancestor.hash(), Some(current.hash()))?);
current = ancestor;
if genesis == current { break; }
Copy link
Contributor

Choose a reason for hiding this comment

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

just check if current hash == genesis hash and don't load the genesis header. and you can avoid doing the hash calculations in all cases but the first by book-keeping the last parent_hash.

Copy link
Contributor

@rphmeier rphmeier left a comment

Choose a reason for hiding this comment

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

Note that uncles are a direct descendant of an ancestor, not any descendant of an ancestor.

@rphmeier rphmeier added A4-gotissues and removed A0-please_review Pull request needs code review. labels Feb 12, 2019
}

/// Returns the hashes of the children blocks of the block with `parent_hash`.
pub fn hashes(&self, db: &KeyValueDB, column: Option<u32>, prefix: &[u8],
Copy link
Member

Choose a reason for hiding this comment

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

Either all parameters on one line or one parameter per line, please.

let mut buf = prefix.to_vec();
parent_hash.using_encoded(|s| buf.extend(s));

if let Ok(raw_val_opt) = db.get(column, &buf[..]) {
Copy link
Member

Choose a reason for hiding this comment

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

That is way to complicated. Either split it up across multiple lines with ? or use match.

/// Returns the hashes of the children blocks of the block with `parent_hash`.
/// It doesn't read the database.
pub fn hashes_from_mem(&self, parent_hash: K) -> Vec<V> {
match self.storage.get(&parent_hash) {
Copy link
Member

Choose a reason for hiding this comment

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

*cloned().unwrap_or_default()

@marcio-diaz marcio-diaz force-pushed the mar-client-provide-uncles branch from ad07fbf to f29f611 Compare February 13, 2019 14:55

for _generation in 0..max_generation.as_() {
let children = self.get_children(ancestor_hash, Some(current_hash))?;
uncles.extend(children);
Copy link
Contributor

Choose a reason for hiding this comment

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

i think the get_children function could be elided in favor of

let children = self.backend.blockchain().children(ancestor_hash)?;
uncles.extend(children.into_iter().filter(|h| h != &current_hash));

this saves a sweep and some potential memmoves.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice.

@marcio-diaz marcio-diaz force-pushed the mar-client-provide-uncles branch from b4c0d72 to f587d69 Compare February 15, 2019 14:16
@marcio-diaz marcio-diaz added A0-please_review Pull request needs code review. and removed A3-needsresolving labels Feb 18, 2019
@gavofyork
Copy link
Member

Ready for review again?

@marcio-diaz marcio-diaz dismissed stale reviews from bkchr and rphmeier February 21, 2019 14:17

fixed

@marcio-diaz
Copy link
Contributor Author

marcio-diaz commented Feb 21, 2019

Ready for review again?

Yes, I think I handled all the issues in the reviews.

@gavofyork
Copy link
Member

cool. @bkchr / @rphmeier happy to sign off?

@rphmeier
Copy link
Contributor

what has changed since the last review?

@marcio-diaz
Copy link
Contributor Author

what has changed since the last review?

Mainly, I removed the hashmap from the implementation of children as you asked.

I was thinking to create a new issue for this (I took a look to the ethereum repo).
Should I create a meta issue about refactoring db related code?

\cc @rphmeier


impl ChildrenMap {
/// Returns the hashes of the children blocks of the block with `parent_hash`.
pub fn children_hashes<
Copy link
Contributor

Choose a reason for hiding this comment

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

We could kill the ChildrenMap struct and make these free functions.

@rphmeier rphmeier added A6-mustntgrumble and removed A0-please_review Pull request needs code review. labels Feb 22, 2019
Copy link
Member

@bkchr bkchr left a comment

Choose a reason for hiding this comment

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

Looks good, some last minor issues and then we are good to go :)

vec![a5.hash(), b4.hash(), c3.hash(), d2.hash()]);
}

/// helper to test the `leaves` implementation for various backends
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// helper to test the `leaves` implementation for various backends
/// helper to test the `children` implementation for various backends

authoring_version: 10,
spec_version: 30,
impl_version: 30,
spec_version: 31,
Copy link
Member

Choose a reason for hiding this comment

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

You don't touch the runtime, so you don't need to change the spec_version and impl_version.

@marcio-diaz marcio-diaz force-pushed the mar-client-provide-uncles branch from cc5b1d0 to b6fc5bf Compare February 25, 2019 10:05
@marcio-diaz marcio-diaz merged commit 7999743 into master Feb 25, 2019
@marcio-diaz marcio-diaz deleted the mar-client-provide-uncles branch February 25, 2019 10:21
MTDK1 pushed a commit to bdevux/substrate that referenced this pull request Apr 12, 2019
* feat: add children function to backend

* feat: add test for children hashes

* feat: add uncles function to client

* fix: improve uncles function adds few more tests

* fix: remove children when reverting

* fix: typo and spec version
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

8 participants