Skip to content

Commit

Permalink
pallet-mmr: move offchain logic to client-side gadget (paritytech#12753)
Browse files Browse the repository at this point in the history
* Move MMR utils methods from pallet to primitives

Signed-off-by: Serban Iorga <[email protected]>

* Add method to MmrApi

* Move forks expanding logic from babe to primitives

* Implement MMR gadget

* Remove prunning logic from the MMR pallet

* Code review changes: 1st iteration

* Replace MaybeCanonEngine with CanonEngineBuilder

* fix mmr_leaves_count() for kitchen sink demo

* Update client/merkle-mountain-range/src/canon_engine.rs

Co-authored-by: Adrian Catangiu <[email protected]>

* Code review changes: 2nd iteration

* fix INDEXING_PREFIX

* impl review comments

* add documentation and minor rename

Signed-off-by: Serban Iorga <[email protected]>
Co-authored-by: Adrian Catangiu <[email protected]>
  • Loading branch information
2 people authored and ltfschoen committed Feb 22, 2023
1 parent 15b4dd1 commit 1447962
Show file tree
Hide file tree
Showing 21 changed files with 1,162 additions and 562 deletions.
25 changes: 24 additions & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ members = [
"client/finality-grandpa",
"client/informant",
"client/keystore",
"client/merkle-mountain-range",
"client/network",
"client/network-gossip",
"client/network/bitswap",
Expand Down
4 changes: 4 additions & 0 deletions bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2066,6 +2066,10 @@ impl_runtime_apis! {
Ok(Mmr::mmr_root())
}

fn mmr_leaf_count() -> Result<mmr::LeafIndex, mmr::Error> {
Ok(Mmr::mmr_leaves())
}

fn generate_proof(
block_numbers: Vec<BlockNumber>,
best_known_block_number: Option<BlockNumber>,
Expand Down
63 changes: 20 additions & 43 deletions client/consensus/babe/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,8 @@ use sp_api::{ApiExt, ProvideRuntimeApi};
use sp_application_crypto::AppKey;
use sp_block_builder::BlockBuilder as BlockBuilderApi;
use sp_blockchain::{
Backend as _, Error as ClientError, HeaderBackend, HeaderMetadata, Result as ClientResult,
Backend as _, Error as ClientError, ForkBackend, HeaderBackend, HeaderMetadata,
Result as ClientResult,
};
use sp_consensus::{
BlockOrigin, CacheKeyId, Environment, Error as ConsensusError, Proposer, SelectChain,
Expand All @@ -123,7 +124,7 @@ use sp_inherents::{CreateInherentDataProviders, InherentData, InherentDataProvid
use sp_keystore::{SyncCryptoStore, SyncCryptoStorePtr};
use sp_runtime::{
generic::{BlockId, OpaqueDigestItemId},
traits::{Block as BlockT, Header, NumberFor, SaturatedConversion, Saturating, Zero},
traits::{Block as BlockT, Header, NumberFor, SaturatedConversion, Zero},
DigestItem,
};

Expand Down Expand Up @@ -515,12 +516,12 @@ fn aux_storage_cleanup<C: HeaderMetadata<Block> + HeaderBackend<Block>, Block: B
client: &C,
notification: &FinalityNotification<Block>,
) -> AuxDataOperations {
let mut aux_keys = HashSet::new();
let mut hashes = HashSet::new();

let first = notification.tree_route.first().unwrap_or(&notification.hash);
match client.header_metadata(*first) {
Ok(meta) => {
aux_keys.insert(aux_schema::block_weight_key(meta.parent));
hashes.insert(meta.parent);
},
Err(err) => warn!(
target: "babe",
Expand All @@ -531,53 +532,29 @@ fn aux_storage_cleanup<C: HeaderMetadata<Block> + HeaderBackend<Block>, Block: B
}

// Cleans data for finalized block's ancestors
aux_keys.extend(
hashes.extend(
notification
.tree_route
.iter()
// Ensure we don't prune latest finalized block.
// This should not happen, but better be safe than sorry!
.filter(|h| **h != notification.hash)
.map(aux_schema::block_weight_key),
.filter(|h| **h != notification.hash),
);

// Cleans data for stale branches.

for head in notification.stale_heads.iter() {
let mut hash = *head;
// Insert stale blocks hashes until canonical chain is reached.
// If we reach a block that is already part of the `aux_keys` we can stop the processing the
// head.
while aux_keys.insert(aux_schema::block_weight_key(hash)) {
match client.header_metadata(hash) {
Ok(meta) => {
hash = meta.parent;

// If the parent is part of the canonical chain or there doesn't exist a block
// hash for the parent number (bug?!), we can abort adding blocks.
if client
.hash(meta.number.saturating_sub(1u32.into()))
.ok()
.flatten()
.map_or(true, |h| h == hash)
{
break
}
},
Err(err) => {
warn!(
target: "babe",
"Header lookup fail while cleaning data for block {:?}: {}",
hash,
err,
);
break
},
}
}
}
// Cleans data for stale forks.
let stale_forks = match client.expand_forks(&notification.stale_heads) {
Ok(stale_forks) => stale_forks,
Err((stale_forks, e)) => {
warn!(target: "babe", "{:?}", e,);
stale_forks
},
};
hashes.extend(stale_forks.iter());

aux_keys.into_iter().map(|val| (val, None)).collect()
hashes
.into_iter()
.map(|val| (aux_schema::block_weight_key(val), None))
.collect()
}

async fn answer_requests<B: BlockT, C>(
Expand Down
32 changes: 32 additions & 0 deletions client/merkle-mountain-range/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
[package]
name = "mmr-gadget"
version = "4.0.0-dev"
authors = ["Parity Technologies <[email protected]>"]
edition = "2021"
license = "GPL-3.0-or-later WITH Classpath-exception-2.0"
repository = "https://github.com/paritytech/substrate"
description = "MMR Client gadget for substrate"
homepage = "https://substrate.io"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
codec = { package = "parity-scale-codec", version = "3.0.0" }
futures = "0.3"
log = "0.4"
beefy-primitives = { version = "4.0.0-dev", path = "../../primitives/beefy" }
sc-client-api = { version = "4.0.0-dev", path = "../api" }
sp-api = { version = "4.0.0-dev", path = "../../primitives/api" }
sp-blockchain = { version = "4.0.0-dev", path = "../../primitives/blockchain" }
sp-consensus = { version = "0.10.0-dev", path = "../../primitives/consensus/common" }
sp-core = { version = "7.0.0", path = "../../primitives/core" }
sp-io = { version = "7.0.0", path = "../../primitives/io" }
sp-mmr-primitives = { version = "4.0.0-dev", path = "../../primitives/merkle-mountain-range" }
sc-offchain = { version = "4.0.0-dev", path = "../offchain" }
sp-runtime = { version = "7.0.0", path = "../../primitives/runtime" }

[dev-dependencies]
tokio = "1.17.0"
sc-block-builder = { version = "0.10.0-dev", path = "../block-builder" }
substrate-test-runtime-client = { version = "2.0.0", path = "../../test-utils/runtime/client" }
async-std = { version = "1.11.0", default-features = false }
Loading

0 comments on commit 1447962

Please sign in to comment.