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

best_containing operations (issue 603)#740

Merged
rphmeier merged 82 commits intomasterfrom
snd-issue-603
Sep 26, 2018
Merged

best_containing operations (issue 603)#740
rphmeier merged 82 commits intomasterfrom
snd-issue-603

Conversation

@snd
Copy link
Copy Markdown
Contributor

@snd snd commented Sep 14, 2018

#603

This pull request implements the operation for finding the best chain containing a specific block (potentially number-limited to a given block). This is usually the best chain.

This also adds a number of cross-backend tests in the test-client crate used to ensure that behavior is consistent across them.

@snd snd added the A3-in_progress Pull request is in progress. No review needed at this stage. label Sep 14, 2018
Comment thread core/client/src/in_mem.rs Outdated
if maybe_insertion_position.is_none() {
return;
}
let insertion_position = maybe_insertion_position.expect("early return right above. q.e.d.");
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

refactor as a let x = match { None => return, Some(x) => x }

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

done

Comment thread core/client/src/client.rs Outdated
/// the operation is performed as if there are no blocks greater `max_block_number`
/// ignoring all blocks with numbers greater
/// TODO [snd] possibly implement this on blockchain::Backend and just redirect here
pub fn best_containing(&self, target_hash: Block::Hash, maybe_max_number: Option<<<Block as BlockT>::Header as HeaderT>::Number>) -> error::Result<Option<Block::Hash>> {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I think there's a NumberFor<Block> type definition in the runtime_primitives that might be useful.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

simplified

Comment thread core/client/src/client.rs Outdated
}

// for each chain. longest chain first. shortest last
for leaf_hash in self.backend.blockchain().leaves()? {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

this loop could be pre-empted by checking if the block with number target_header.number() in the "canonical" chain is target_header. Could return the "best block" in that case, or its ancestor with max_number. Although the import lock probably has to be held for safety with that approach, to ensure that a block import doesn't race against this thread and trigger a reorganization.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

i believe i tried this before by checking whether the hash of the block at target_header.number() matches target_hash:

// let is_target_in_best_chain = self.backend.blockchain().hash(*target_header.number())?.ok_or_else(|| error::Error::from(format!("failed to get hash for block number {}", target_header.number())))? == target_hash;

however self.backend.blockchain().hash(*target_header.number()) returned None
for those numbers that were not uniquely mappable to a hash i.e. there were forks and multiple hashes for that number. i'll investigate again. maybe there's a better method.

Copy link
Copy Markdown
Contributor

@rphmeier rphmeier Sep 17, 2018

Choose a reason for hiding this comment

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

The current blockchain backend doesn't handle forks at all, so I've been rewriting it to do so in a local branch.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

this loop could be pre-empted by checking if the block with number target_header.number() in the "canonical" chain is target_header

how do i get the header/hash that's in the canonical chain at position number?

i assumed i could do this through ...blockchain().header(BlockId::Number(number)) / ...blockchain().hash(number).

both do not seem to return the header/hash in the canonical chain but rather the header/hash that was last imported at that position.

i've added a test exposing that problem here 57e758b. note that it only tests the in-memory backend.

is this indeed a bug that should be fixed? is there another method to retrieve a block given a number in the canonical chain? should i leave out the pre-emption for now?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

both do not seem to return the header/hash in the canonical chain but rather the header/hash that was last imported at that position.

This is exactly what #760 is meant to fix; the underlying blockchain DB literally could not accommodate forks before.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

perfect! this should work out then

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

pre-emption is in. the tests should pass once #760 is merged and this is rebased on it

snd added a commit that referenced this pull request Sep 17, 2018
address grumble #740 (comment)
snd added a commit that referenced this pull request Sep 17, 2018
@snd
Copy link
Copy Markdown
Contributor Author

snd commented Sep 18, 2018

when i comment in this code here https://github.com/paritytech/substrate/pull/740/files#diff-5a5b3c7041f582d3b3c912d4bf55aea8R609 which adds block C3 which is here in the block tree https://github.com/paritytech/substrate/pull/740/files#diff-5a5b3c7041f582d3b3c912d4bf55aea8R529 i get

thread 'client::tests::best_containing_with_multiple_forks' panicked at 'called `Result::unwrap()` on an `Err` value: Error(ApplyExtinsicFailed(Stale), State { next_error: None, backtrace: InternalBacktrace { backtrace: None } })', libcore/result.rs:945:5

relevant part: Error(ApplyExtinsicFailed(Stale)

any ideas as to why?

@snd
Copy link
Copy Markdown
Contributor Author

snd commented Sep 19, 2018

it's not trivial to Backend.revert the leaves list. should i bother at this time?

it requires removing the reverted block hash, then adding the parent again if the parent has no other children. checking the latter is expensive. we could make it faster by keeping a child counter for each block. that requires additional storage for each block however.

@rphmeier
Copy link
Copy Markdown
Contributor

Correct reversion should definitely prune out forks that branch off of blocks we've discarded. That's also an issue with the current implementation. @arkpar might have some ideas; I'm pretty ambivalent as long as not reverting the leaves list can't break stuff too badly.

@snd
Copy link
Copy Markdown
Contributor Author

snd commented Sep 20, 2018

Correct reversion should definitely prune out forks that branch off of blocks we've discarded. That's also an issue with the current implementation. @arkpar might have some ideas; I'm pretty ambivalent as long as not reverting the leaves list can't break stuff too badly.

ok. i'll tackle this last

i found a simpler and faster approach to storing the leaves in the kev-value-db. this shouldn't take much longer

Comment thread core/sr-primitives/src/traits.rs Outdated
use substrate_primitives;
use substrate_primitives::Blake2Hasher;
use codec::{Codec, Encode};
pub use codec::{Codec, Encode, Decode};
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

i'm not convinced we should re-export these. client already has a parity_codec dependency, perhaps it can import from there?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

agreed and fixed

Comment thread core/test-client/src/trait_tests.rs Outdated
// from: Keyring::Alice.to_raw_public().into(),
// to: Keyring::Ferdie.to_raw_public().into(),
// amount: 1,
// nonce: 0,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

nonce: 1 should fix it AFAICT

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thanks. that fixed the Error(ApplyExtinsicFailed(Stale) issue

@rphmeier rphmeier 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 Sep 25, 2018
Copy link
Copy Markdown
Contributor Author

@snd snd left a comment

Choose a reason for hiding this comment

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

looks great! thanks for fixing the backends to make the tests pass and finishing up the leaf list db read/write. i'd say we merge it and do further work on this in other PRs

Comment thread core/client/db/src/lib.rs Outdated
Ok(BlockchainDb {
db,
leaves: RwLock::new(leaves),
meta: RwLock::new(meta)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we tend to prefer to keep the last , on multiline lists

Comment thread core/client/db/src/lib.rs Outdated
db: Arc<KeyValueDB>,
meta: RwLock<Meta<<Block::Header as HeaderT>::Number, Block::Hash>>,
meta: RwLock<Meta<NumberFor<Block>, Block::Hash>>,
leaves: RwLock<LeafSet<Block::Hash, NumberFor<Block>>>
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we tend to prefer to keep the last , on multiline lists

Comment thread core/client/src/in_mem.rs Outdated
let route = ::blockchain::tree_route(
self,
BlockId::Hash(best_hash),
BlockId::Hash(*header.parent_hash())
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

we tend to prefer to keep the last , on multiline lists

Comment thread core/test-client/src/lib.rs Outdated
}

fn genesis_storage() -> StorageMap {
let mut storage = genesis_config().genesis_map();
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

superfluous indent level

Copy link
Copy Markdown
Member

@gavofyork gavofyork left a comment

Choose a reason for hiding this comment

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

Minor style nits. Code quality good and test coverage seems reasonable.

@gavofyork gavofyork added A6-seemsok and removed A0-please_review Pull request needs code review. labels Sep 26, 2018
@rphmeier rphmeier merged commit 6c7b45e into master Sep 26, 2018
@rphmeier rphmeier deleted the snd-issue-603 branch September 26, 2018 11:34
lamafab pushed a commit to lamafab/substrate that referenced this pull request Jun 16, 2020
* rough draft of parachains roadmap

* flesh out first 2 phases

* Fix typo

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* Fix typos and add clarifications

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* remove extra space

Co-Authored-By: Bastian Köcher <bkchr@users.noreply.github.com>

* add XCMP work items

Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
liuchengxu pushed a commit to chainx-org/substrate that referenced this pull request Aug 23, 2021
* add log in parse_addr_from_script

* refactor for deposit input_addr

* refactor for deposit handle
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.

3 participants