Expose proof generation and verifying api. (#4646)

* Expose proof generation and verifying api.

* tabs to spaces

* bring back license comment

* Revert "tabs to spaces"

This reverts commit 4c3f72f9ef76b6a9f8988ed15b1bab17a9e51d2f.

* Formatting and docs nits

* Bump deps versions

* Upadte Cargo.lock

* into -> in
This commit is contained in:
Fedor Sakharov
2020-01-17 17:47:21 +03:00
committed by Bastian Köcher
parent d5ecec3775
commit ad60af5f13
5 changed files with 158 additions and 29 deletions
+25 -24
View File
@@ -1250,7 +1250,7 @@ dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -2857,7 +2857,7 @@ dependencies = [
[[package]]
name = "memory-db"
version = "0.18.0"
version = "0.18.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ahash 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3194,7 +3194,7 @@ dependencies = [
"pallet-treasury 2.0.0",
"pallet-utility 2.0.0",
"parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
"sp-api 2.0.0",
"sp-authority-discovery 2.0.0",
@@ -4895,7 +4895,7 @@ name = "rlp"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -4933,7 +4933,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "rustc-hex"
version = "2.0.1"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -5530,7 +5530,7 @@ dependencies = [
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"quickcheck 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sc-block-builder 0.8.0",
"sc-client 0.8.0",
"sc-client-api 2.0.0",
@@ -5654,7 +5654,7 @@ dependencies = [
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"parking_lot 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sc-client 0.8.0",
"sc-client-api 2.0.0",
"sc-executor 0.8.0",
@@ -6378,7 +6378,7 @@ dependencies = [
"primitive-types 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"schnorrkel 0.8.5 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 1.0.103 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_json 1.0.44 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -6636,7 +6636,7 @@ dependencies = [
"sp-externalities 0.8.0",
"sp-panic-handler 2.0.0",
"sp-trie 2.0.0",
"trie-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -6697,12 +6697,12 @@ dependencies = [
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hex-literal 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"sp-core 2.0.0",
"sp-std 2.0.0",
"trie-bench 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-bench 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -6830,7 +6830,7 @@ dependencies = [
"parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rpassword 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"sc-rpc 2.0.0",
"sp-core 2.0.0",
"sp-runtime 2.0.0",
@@ -6921,7 +6921,7 @@ dependencies = [
"frame-system 2.0.0",
"frame-system-rpc-runtime-api 2.0.0",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
"pallet-babe 2.0.0",
"pallet-timestamp 2.0.0",
"parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -6948,7 +6948,7 @@ dependencies = [
"sp-version 2.0.0",
"substrate-test-runtime-client 2.0.0",
"substrate-wasm-builder-runner 1.0.4",
"trie-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -7497,28 +7497,29 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "trie-bench"
version = "0.18.0"
version = "0.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"criterion 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"keccak-hasher 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)",
"memory-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
"parity-scale-codec 1.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-db 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "trie-db"
version = "0.18.1"
version = "0.19.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"hash-db 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)",
"hashbrown 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rand 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -7592,7 +7593,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"crunchy 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"static_assertions 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -8512,7 +8513,7 @@ dependencies = [
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
"checksum memchr 2.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "88579771288728879b57485cc7d6b07d648c9f0141eb955f8ab7f9d45394468e"
"checksum memoffset 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)" = "75189eb85871ea5c2e2c15abbdd541185f63b408415e5051f5cac122d8c774b9"
"checksum memory-db 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "828bdf600636e90c56652689f7c3823ae2072104e4b0b5e83ea984f592f12ab9"
"checksum memory-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "881736a0f68a6fae1b596bb066c5bd16d7b3ed645a4dd8ffaefd02f585abaf71"
"checksum memory_units 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "71d96e3f3c0b6325d8ccd83c33b28acb183edcb6c67938ba104ec546854b0882"
"checksum merlin 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "2b0942b357c1b4d0dc43ba724674ec89c3218e6ca2b3e8269e7cb53bcecd2f6e"
"checksum mime 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ba626b8a6de5da682e1caa06bdb42a335aee5a84db8e5046a3e8ab17ba0a3ae0"
@@ -8636,7 +8637,7 @@ dependencies = [
"checksum rpassword 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d59f0e97173c514b9036cd450c195a6483ba81055c6fa0f1bff3ab563f47d44a"
"checksum rust-argon2 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4ca4eaef519b494d1f2848fc602d18816fed808a981aedf4f1f00ceb7c9d32cf"
"checksum rustc-demangle 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "4c691c0e608126e00913e33f0ccf3727d5fc84573623b8d65b2df340b5201783"
"checksum rustc-hex 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "403bb3a286107a04825a5f82e1270acc1e14028d3d554d7a1e08914549575ab8"
"checksum rustc-hex 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3e75f6a532d0fd9f7f13144f392b6ad56a32696bfcd9c78f797f16bbb6f072d6"
"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
"checksum rustls 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b25a18b1bf7387f0145e7f8324e700805aade3842dd3db2e74e4cdeb4677c09e"
"checksum rustversion 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c48f91977f4ef3be5358c15d131d3f663f6b4d7a112555bf3bf52ad23b6659e5"
@@ -8740,8 +8741,8 @@ dependencies = [
"checksum tracing-attributes 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "a4263b12c3d3c403274493eb805966093b53214124796552d674ca1dd5d27c2b"
"checksum tracing-core 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)" = "bc913647c520c959b6d21e35ed8fa6984971deca9f0a2fcb8c51207e0c56af1d"
"checksum traitobject 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "efd1f82c56340fdf16f2a953d7bda4f8fdffba13d93b00844c25572110b26079"
"checksum trie-bench 0.18.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4d276e600d06806a4ac61e5d6b145a620001e6147151e60a4f1f46a784ec4baa"
"checksum trie-db 0.18.1 (registry+https://github.com/rust-lang/crates.io-index)" = "191fda5d0106f3ed35a8c6875428b213e15c516e48129cc263dd7ad16e9a665f"
"checksum trie-bench 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)" = "26fd042d57ee9c987c562811162a78db78b5340ab674ac76056c85dca49b26bc"
"checksum trie-db 0.19.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a0d747ae5b6f078df7e46477fcc7df66df9eb4f27a031cf4a7c890a8dd03d8e6"
"checksum trie-root 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0b779f7c1c8fe9276365d9d5be5c4b5adeacf545117bb3f64c974305789c5c0b"
"checksum trie-standardmap 0.15.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c3161ba520ab28cd8e6b68e1126f1009f6e335339d1a73b978139011703264c8"
"checksum try-lock 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e604eb7b43c06650e854be16a2a03155743d3752dd1c943f6829e26b7a36e382"
@@ -9,7 +9,7 @@ edition = "2018"
log = "0.4.8"
parking_lot = "0.9.0"
hash-db = "0.15.2"
trie-db = "0.18.1"
trie-db = "0.19.2"
trie-root = "0.15.2"
sp-trie = { version = "2.0.0", path = "../trie" }
sp-core = { version = "2.0.0", path = "../core" }
+3 -3
View File
@@ -15,13 +15,13 @@ harness = false
codec = { package = "parity-scale-codec", version = "1.0.0", default-features = false }
sp-std = { version = "2.0.0", default-features = false, path = "../std" }
hash-db = { version = "0.15.2", default-features = false }
trie-db = { version = "0.18.1", default-features = false }
trie-db = { version = "0.19.2", default-features = false }
trie-root = { version = "0.15.2", default-features = false }
memory-db = { version = "0.18.0", default-features = false }
memory-db = { version = "0.18.1", default-features = false }
sp-core = { version = "2.0.0", default-features = false, path = "../core" }
[dev-dependencies]
trie-bench = "0.18.0"
trie-bench = "0.19.0"
trie-standardmap = "0.15.2"
criterion = "0.2.11"
hex-literal = "0.2.1"
+128
View File
@@ -27,6 +27,8 @@ use sp_std::boxed::Box;
use sp_std::marker::PhantomData;
use sp_std::vec::Vec;
use hash_db::{Hasher, Prefix};
use trie_db::proof::{generate_proof, verify_proof};
pub use trie_db::proof::VerifyError;
/// Our `NodeCodec`-specific error.
pub use error::Error;
/// The Substrate format implementation of `TrieStream`.
@@ -119,6 +121,47 @@ pub mod trie_types {
pub type TrieError<H> = trie_db::TrieError<H, super::Error>;
}
/// Create a proof for a subset of keys in a trie.
///
/// The `keys` may contain any set of keys regardless of each one of them is included
/// in the `db`.
///
/// For a key `K` that is included in the `db` a proof of inclusion is generated.
/// For a key `K` that is not included in the `db` a proof of non-inclusion is generated.
/// These can be later checked in `verify_trie_proof`.
pub fn generate_trie_proof<'a, L: TrieConfiguration, I, K, DB>(
db: &DB,
root: TrieHash<L>,
keys: I,
) -> Result<Vec<Vec<u8>>, Box<TrieError<L>>> where
I: IntoIterator<Item=&'a K>,
K: 'a + AsRef<[u8]>,
DB: hash_db::HashDBRef<L::Hash, trie_db::DBValue>,
{
let trie = TrieDB::<L>::new(db, &root)?;
generate_proof(&trie, keys)
}
/// Verify a set of key-value pairs against a trie root and a proof.
///
/// Checks a set of keys with optional values for inclusion in the proof that was generated by
/// `generate_trie_proof`.
/// If the value in the pair is supplied (`(key, Some(value))`), this key-value pair will be
/// checked for inclusion in the proof.
/// If the value is omitted (`(key, None)`), this key will be checked for non-inclusion in the
/// proof.
pub fn verify_trie_proof<'a, L: TrieConfiguration, I, K, V>(
root: &TrieHash<L>,
proof: &[Vec<u8>],
items: I,
) -> Result<(), VerifyError<TrieHash<L>, error::Error>> where
I: IntoIterator<Item=&'a (K, Option<V>)>,
K: 'a + AsRef<[u8]>,
V: 'a + AsRef<[u8]>,
{
verify_proof::<Layout<L::Hash>, _, _, _>(root, proof, items)
}
/// Determine a trie root given a hash DB and delta values.
pub fn delta_trie_root<L: TrieConfiguration, I, A, B, DB>(
db: &mut DB,
@@ -727,4 +770,89 @@ mod tests {
assert_eq!(pairs, iter_pairs);
}
#[test]
fn proof_non_inclusion_works() {
let pairs = vec![
(hex!("0102").to_vec(), hex!("01").to_vec()),
(hex!("0203").to_vec(), hex!("0405").to_vec()),
];
let mut memdb = MemoryDB::default();
let mut root = Default::default();
populate_trie::<Layout>(&mut memdb, &mut root, &pairs);
let non_included_key: Vec<u8> = hex!("0909").to_vec();
let proof = generate_trie_proof::<Layout, _, _, _>(
&memdb,
root,
&[non_included_key.clone()]
).unwrap();
// Verifying that the K was not included into the trie should work.
assert!(verify_trie_proof::<Layout, _, _, Vec<u8>>(
&root,
&proof,
&[(non_included_key.clone(), None)],
).is_ok()
);
// Verifying that the K was included into the trie should fail.
assert!(verify_trie_proof::<Layout, _, _, Vec<u8>>(
&root,
&proof,
&[(non_included_key, Some(hex!("1010").to_vec()))],
).is_err()
);
}
#[test]
fn proof_inclusion_works() {
let pairs = vec![
(hex!("0102").to_vec(), hex!("01").to_vec()),
(hex!("0203").to_vec(), hex!("0405").to_vec()),
];
let mut memdb = MemoryDB::default();
let mut root = Default::default();
populate_trie::<Layout>(&mut memdb, &mut root, &pairs);
let proof = generate_trie_proof::<Layout, _, _, _>(
&memdb,
root,
&[pairs[0].0.clone()]
).unwrap();
// Check that a K, V included into the proof are verified.
assert!(verify_trie_proof::<Layout, _, _, _>(
&root,
&proof,
&[(pairs[0].0.clone(), Some(pairs[0].1.clone()))]
).is_ok()
);
// Absence of the V is not verified with the proof that has K, V included.
assert!(verify_trie_proof::<Layout, _, _, Vec<u8>>(
&root,
&proof,
&[(pairs[0].0.clone(), None)]
).is_err()
);
// K not included into the trie is not verified.
assert!(verify_trie_proof::<Layout, _, _, _>(
&root,
&proof,
&[(hex!("4242").to_vec(), Some(pairs[0].1.clone()))]
).is_err()
);
// K included into the trie but not included into the proof is not verified.
assert!(verify_trie_proof::<Layout, _, _, _>(
&root,
&proof,
&[(pairs[1].0.clone(), Some(pairs[1].1.clone()))]
).is_err()
);
}
}
+1 -1
View File
@@ -35,7 +35,7 @@ pallet-timestamp = { version = "2.0.0", default-features = false, path = "../../
sc-client = { version = "0.8", optional = true, path = "../../client" }
sp-trie = { version = "2.0.0", default-features = false, path = "../../primitives/trie" }
sp-transaction-pool = { version = "2.0.0", default-features = false, path = "../../primitives/transaction-pool" }
trie-db = { version = "0.18.1", default-features = false }
trie-db = { version = "0.19.2", default-features = false }
[dev-dependencies]
sc-executor = { version = "0.8", path = "../../client/executor" }