Skip to content

Commit

Permalink
Create a Basic Proving Trie for the Runtime (#3881)
Browse files Browse the repository at this point in the history
This PR will introduce a `BasicProvingTrie` type, which makes it easy to
construct and prove data in a base-16 merkle trie within the runtime.

Data into the merkle trie only require that they implement `Encode` /
`Decode`.

A FRAME compatible `TrieError` was created and added to `DispatchError`.

Expected usage is to construct the merkle trie with all data offline,
and then place only the merkle root of that trie on-chain.

Also offchain, a user is given a compact merkle proof of some data they
want to prove exists on the blockchain.

Then in the runtime, you can call `verify_single_value_proof` or
`verify_proof` with the root, proof, and the keys and values you want to
verify exists in the merkle trie.

Closes #3880

Contributes to #5400

---------

Co-authored-by: Ankan <[email protected]>
Co-authored-by: Oliver Tale-Yazdi <[email protected]>
  • Loading branch information
3 people authored Sep 4, 2024
1 parent 778a9e4 commit 1cff666
Show file tree
Hide file tree
Showing 5 changed files with 422 additions and 0 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

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

15 changes: 15 additions & 0 deletions prdoc/pr_3881.prdoc
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Schema: Polkadot SDK PRDoc Schema (prdoc) v1.0.0
# See doc at https://raw.githubusercontent.com/paritytech/polkadot-sdk/master/prdoc/schema_user.json

title: Introduce a Generic Proving Trie

doc:
- audience: Runtime Dev
description: |
This PR introduces a Proving Trie object which can be used inside the runtime. This can allow
for things like airdrops where a single hash is stored on chain representing the whole airdrop
and individuals present a proof of their inclusion in the airdrop.

crates:
- name: sp-runtime
bump: major
2 changes: 2 additions & 0 deletions substrate/primitives/runtime/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ sp-arithmetic = { workspace = true }
sp-core = { workspace = true }
sp-io = { workspace = true }
sp-std = { workspace = true }
sp-trie = { workspace = true }
sp-weights = { workspace = true }
docify = { workspace = true }
tracing = { workspace = true, features = ["log"], default-features = false }
Expand Down Expand Up @@ -69,6 +70,7 @@ std = [
"sp-state-machine/std",
"sp-std/std",
"sp-tracing/std",
"sp-trie/std",
"sp-weights/std",
"tracing/std",
]
Expand Down
16 changes: 16 additions & 0 deletions substrate/primitives/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ pub mod generic;
pub mod legacy;
mod multiaddress;
pub mod offchain;
pub mod proving_trie;
pub mod runtime_logger;
mod runtime_string;
#[cfg(feature = "std")]
Expand All @@ -103,6 +104,8 @@ pub use crate::runtime_string::*;
// Re-export Multiaddress
pub use multiaddress::MultiAddress;

use proving_trie::TrieError;

/// Re-export these since they're only "kind of" generic.
pub use generic::{Digest, DigestItem};

Expand Down Expand Up @@ -592,6 +595,8 @@ pub enum DispatchError {
Unavailable,
/// Root origin is not allowed.
RootNotAllowed,
/// An error with tries.
Trie(TrieError),
}

/// Result of a `Dispatchable` which contains the `DispatchResult` and additional information about
Expand Down Expand Up @@ -697,6 +702,12 @@ impl From<ArithmeticError> for DispatchError {
}
}

impl From<TrieError> for DispatchError {
fn from(e: TrieError) -> DispatchError {
Self::Trie(e)
}
}

impl From<&'static str> for DispatchError {
fn from(err: &'static str) -> DispatchError {
Self::Other(err)
Expand All @@ -721,6 +732,7 @@ impl From<DispatchError> for &'static str {
Corruption => "State corrupt",
Unavailable => "Resource unavailable",
RootNotAllowed => "Root not allowed",
Trie(e) => e.into(),
}
}
}
Expand Down Expand Up @@ -768,6 +780,10 @@ impl traits::Printable for DispatchError {
Corruption => "State corrupt".print(),
Unavailable => "Resource unavailable".print(),
RootNotAllowed => "Root not allowed".print(),
Trie(e) => {
"Trie error: ".print();
<&'static str>::from(*e).print();
},
}
}
}
Expand Down
Loading

0 comments on commit 1cff666

Please sign in to comment.