mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-05-30 00:01:03 +00:00
Run cargo fmt on the whole code base (#9394)
* Run cargo fmt on the whole code base * Second run * Add CI check * Fix compilation * More unnecessary braces * Handle weights * Use --all * Use correct attributes... * Fix UI tests * AHHHHHHHHH * 🤦 * Docs * Fix compilation * 🤷 * Please stop * 🤦 x 2 * More * make rustfmt.toml consistent with polkadot Co-authored-by: André Silva <andrerfosilva@gmail.com>
This commit is contained in:
@@ -21,7 +21,7 @@
|
||||
#![warn(missing_docs)]
|
||||
|
||||
use frame_support::RuntimeDebug;
|
||||
use sp_runtime::traits::{self, Saturating, One};
|
||||
use sp_runtime::traits::{self, One, Saturating};
|
||||
use sp_std::fmt;
|
||||
#[cfg(not(feature = "std"))]
|
||||
use sp_std::prelude::Vec;
|
||||
@@ -55,16 +55,10 @@ impl LeafDataProvider for () {
|
||||
/// current block hash is not available (since the block is not finished yet),
|
||||
/// we use the `parent_hash` here along with parent block number.
|
||||
impl<T: frame_system::Config> LeafDataProvider for frame_system::Pallet<T> {
|
||||
type LeafData = (
|
||||
<T as frame_system::Config>::BlockNumber,
|
||||
<T as frame_system::Config>::Hash
|
||||
);
|
||||
type LeafData = (<T as frame_system::Config>::BlockNumber, <T as frame_system::Config>::Hash);
|
||||
|
||||
fn leaf_data() -> Self::LeafData {
|
||||
(
|
||||
Self::block_number().saturating_sub(One::one()),
|
||||
Self::parent_hash()
|
||||
)
|
||||
(Self::block_number().saturating_sub(One::one()), Self::parent_hash())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -130,7 +124,8 @@ mod encoding {
|
||||
fn encode_to<T: codec::Output + ?Sized>(&self, dest: &mut T) {
|
||||
match self {
|
||||
Self::Data(l) => l.using_encoded(
|
||||
|data| Either::<&[u8], &H::Output>::Left(data).encode_to(dest), false
|
||||
|data| Either::<&[u8], &H::Output>::Left(data).encode_to(dest),
|
||||
false,
|
||||
),
|
||||
Self::Hash(h) => Either::<&[u8], &H::Output>::Right(h).encode_to(dest),
|
||||
}
|
||||
@@ -258,7 +253,8 @@ macro_rules! impl_leaf_data_for_tuple {
|
||||
|
||||
/// Test functions implementation for `Compact<H, (DataOrHash<H, Tuple>, ...)>`
|
||||
#[cfg(test)]
|
||||
impl<H, A, B> Compact<H, (DataOrHash<H, A>, DataOrHash<H, B>)> where
|
||||
impl<H, A, B> Compact<H, (DataOrHash<H, A>, DataOrHash<H, B>)>
|
||||
where
|
||||
H: traits::Hash,
|
||||
A: FullLeaf,
|
||||
B: FullLeaf,
|
||||
@@ -346,7 +342,7 @@ pub struct OpaqueLeaf(
|
||||
///
|
||||
/// NOTE it DOES NOT include length prefix (like `Vec<u8>` encoding would).
|
||||
#[cfg_attr(feature = "std", serde(with = "sp_core::bytes"))]
|
||||
pub Vec<u8>
|
||||
pub Vec<u8>,
|
||||
);
|
||||
|
||||
impl OpaqueLeaf {
|
||||
@@ -474,25 +470,21 @@ mod tests {
|
||||
];
|
||||
|
||||
// when
|
||||
let encoded = cases
|
||||
.iter()
|
||||
.map(codec::Encode::encode)
|
||||
.collect::<Vec<_>>();
|
||||
let encoded = cases.iter().map(codec::Encode::encode).collect::<Vec<_>>();
|
||||
|
||||
let decoded = encoded
|
||||
.iter()
|
||||
.map(|x| Test::decode(&mut &**x))
|
||||
.collect::<Vec<_>>();
|
||||
let decoded = encoded.iter().map(|x| Test::decode(&mut &**x)).collect::<Vec<_>>();
|
||||
|
||||
// then
|
||||
assert_eq!(decoded, cases.into_iter().map(Result::<_, codec::Error>::Ok).collect::<Vec<_>>());
|
||||
assert_eq!(
|
||||
decoded,
|
||||
cases.into_iter().map(Result::<_, codec::Error>::Ok).collect::<Vec<_>>()
|
||||
);
|
||||
// check encoding correctness
|
||||
assert_eq!(&encoded[0], &hex_literal::hex!("00343048656c6c6f20576f726c6421"));
|
||||
assert_eq!(
|
||||
encoded[1].as_slice(),
|
||||
hex_literal::hex!(
|
||||
"01c3e7ba6b511162fead58f2c8b5764ce869ed1118011ac37392522ed16720bbcd"
|
||||
).as_ref()
|
||||
hex_literal::hex!("01c3e7ba6b511162fead58f2c8b5764ce869ed1118011ac37392522ed16720bbcd")
|
||||
.as_ref()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -519,10 +511,7 @@ mod tests {
|
||||
|
||||
// when
|
||||
let c: TestCompact = Compact::new((a.clone(), b.clone()));
|
||||
let d: TestCompact = Compact::new((
|
||||
Test::Hash(a.hash()),
|
||||
Test::Hash(b.hash()),
|
||||
));
|
||||
let d: TestCompact = Compact::new((Test::Hash(a.hash()), Test::Hash(b.hash())));
|
||||
|
||||
// then
|
||||
assert_eq!(c.hash(), d.hash());
|
||||
@@ -535,35 +524,28 @@ mod tests {
|
||||
let b = Test::Data("".into());
|
||||
|
||||
let c: TestCompact = Compact::new((a.clone(), b.clone()));
|
||||
let d: TestCompact = Compact::new((
|
||||
Test::Hash(a.hash()),
|
||||
Test::Hash(b.hash()),
|
||||
));
|
||||
let d: TestCompact = Compact::new((Test::Hash(a.hash()), Test::Hash(b.hash())));
|
||||
let cases = vec![c, d.clone()];
|
||||
|
||||
// when
|
||||
let encoded_compact = cases
|
||||
.iter()
|
||||
.map(|c| c.using_encoded(|x| x.to_vec(), true))
|
||||
.collect::<Vec<_>>();
|
||||
let encoded_compact =
|
||||
cases.iter().map(|c| c.using_encoded(|x| x.to_vec(), true)).collect::<Vec<_>>();
|
||||
|
||||
let encoded = cases
|
||||
.iter()
|
||||
.map(|c| c.using_encoded(|x| x.to_vec(), false))
|
||||
.collect::<Vec<_>>();
|
||||
let encoded =
|
||||
cases.iter().map(|c| c.using_encoded(|x| x.to_vec(), false)).collect::<Vec<_>>();
|
||||
|
||||
let decoded_compact = encoded_compact
|
||||
.iter()
|
||||
.map(|x| TestCompact::decode(&mut &**x))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let decoded = encoded
|
||||
.iter()
|
||||
.map(|x| TestCompact::decode(&mut &**x))
|
||||
.collect::<Vec<_>>();
|
||||
let decoded = encoded.iter().map(|x| TestCompact::decode(&mut &**x)).collect::<Vec<_>>();
|
||||
|
||||
// then
|
||||
assert_eq!(decoded, cases.into_iter().map(Result::<_, codec::Error>::Ok).collect::<Vec<_>>());
|
||||
assert_eq!(
|
||||
decoded,
|
||||
cases.into_iter().map(Result::<_, codec::Error>::Ok).collect::<Vec<_>>()
|
||||
);
|
||||
|
||||
assert_eq!(decoded_compact, vec![Ok(d.clone()), Ok(d.clone())]);
|
||||
}
|
||||
@@ -575,10 +557,7 @@ mod tests {
|
||||
let b = Test::Data("".into());
|
||||
|
||||
let c: TestCompact = Compact::new((a.clone(), b.clone()));
|
||||
let d: TestCompact = Compact::new((
|
||||
Test::Hash(a.hash()),
|
||||
Test::Hash(b.hash()),
|
||||
));
|
||||
let d: TestCompact = Compact::new((Test::Hash(a.hash()), Test::Hash(b.hash())));
|
||||
let cases = vec![c, d.clone()];
|
||||
|
||||
let encoded_compact = cases
|
||||
@@ -587,16 +566,10 @@ mod tests {
|
||||
.map(OpaqueLeaf::from_encoded_leaf)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
let opaque = cases
|
||||
.iter()
|
||||
.map(OpaqueLeaf::from_leaf)
|
||||
.collect::<Vec<_>>();
|
||||
let opaque = cases.iter().map(OpaqueLeaf::from_leaf).collect::<Vec<_>>();
|
||||
|
||||
// then
|
||||
assert_eq!(
|
||||
encoded_compact,
|
||||
opaque,
|
||||
);
|
||||
assert_eq!(encoded_compact, opaque,);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -610,10 +583,7 @@ mod tests {
|
||||
let case3 = a.encode().encode();
|
||||
|
||||
// when
|
||||
let encoded = vec![&case1, &case2]
|
||||
.into_iter()
|
||||
.map(|x| x.encode())
|
||||
.collect::<Vec<_>>();
|
||||
let encoded = vec![&case1, &case2].into_iter().map(|x| x.encode()).collect::<Vec<_>>();
|
||||
let decoded = vec![&*encoded[0], &*encoded[1], &*case3]
|
||||
.into_iter()
|
||||
.map(|x| EncodableOpaqueLeaf::decode(&mut &*x))
|
||||
|
||||
@@ -26,14 +26,11 @@ use jsonrpc_core::{Error, ErrorCode, Result};
|
||||
use jsonrpc_derive::rpc;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use pallet_mmr_primitives::{Error as MmrError, Proof};
|
||||
use sp_api::ProvideRuntimeApi;
|
||||
use sp_blockchain::HeaderBackend;
|
||||
use sp_core::Bytes;
|
||||
use sp_runtime::{
|
||||
generic::BlockId,
|
||||
traits::{Block as BlockT},
|
||||
};
|
||||
use pallet_mmr_primitives::{Error as MmrError, Proof};
|
||||
use sp_runtime::{generic::BlockId, traits::Block as BlockT};
|
||||
|
||||
pub use pallet_mmr_primitives::MmrApi as MmrRuntimeApi;
|
||||
|
||||
@@ -51,19 +48,12 @@ pub struct LeafProof<BlockHash> {
|
||||
|
||||
impl<BlockHash> LeafProof<BlockHash> {
|
||||
/// Create new `LeafProof` from given concrete `leaf` and `proof`.
|
||||
pub fn new<Leaf, MmrHash>(
|
||||
block_hash: BlockHash,
|
||||
leaf: Leaf,
|
||||
proof: Proof<MmrHash>,
|
||||
) -> Self where
|
||||
pub fn new<Leaf, MmrHash>(block_hash: BlockHash, leaf: Leaf, proof: Proof<MmrHash>) -> Self
|
||||
where
|
||||
Leaf: Encode,
|
||||
MmrHash: Encode,
|
||||
{
|
||||
Self {
|
||||
block_hash,
|
||||
leaf: Bytes(leaf.encode()),
|
||||
proof: Bytes(proof.encode()),
|
||||
}
|
||||
Self { block_hash, leaf: Bytes(leaf.encode()), proof: Bytes(proof.encode()) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -95,21 +85,15 @@ pub struct Mmr<C, B> {
|
||||
impl<C, B> Mmr<C, B> {
|
||||
/// Create new `Mmr` with the given reference to the client.
|
||||
pub fn new(client: Arc<C>) -> Self {
|
||||
Self {
|
||||
client,
|
||||
_marker: Default::default(),
|
||||
}
|
||||
Self { client, _marker: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, Block, MmrHash> MmrApi<<Block as BlockT>::Hash,> for Mmr<C, (Block, MmrHash)>
|
||||
impl<C, Block, MmrHash> MmrApi<<Block as BlockT>::Hash> for Mmr<C, (Block, MmrHash)>
|
||||
where
|
||||
Block: BlockT,
|
||||
C: Send + Sync + 'static + ProvideRuntimeApi<Block> + HeaderBackend<Block>,
|
||||
C::Api: MmrRuntimeApi<
|
||||
Block,
|
||||
MmrHash,
|
||||
>,
|
||||
C::Api: MmrRuntimeApi<Block, MmrHash>,
|
||||
MmrHash: Codec + Send + Sync + 'static,
|
||||
{
|
||||
fn generate_proof(
|
||||
@@ -120,8 +104,7 @@ where
|
||||
let api = self.client.runtime_api();
|
||||
let block_hash = at.unwrap_or_else(||
|
||||
// If the block hash is not supplied assume the best block.
|
||||
self.client.info().best_hash
|
||||
);
|
||||
self.client.info().best_hash);
|
||||
|
||||
let (leaf, proof) = api
|
||||
.generate_proof_with_context(
|
||||
@@ -202,11 +185,14 @@ mod tests {
|
||||
let expected = LeafProof {
|
||||
block_hash: H256::repeat_byte(0),
|
||||
leaf: Bytes(vec![1_u8, 2, 3, 4].encode()),
|
||||
proof: Bytes(Proof {
|
||||
leaf_index: 1,
|
||||
leaf_count: 9,
|
||||
items: vec![H256::repeat_byte(1), H256::repeat_byte(2)],
|
||||
}.encode()),
|
||||
proof: Bytes(
|
||||
Proof {
|
||||
leaf_index: 1,
|
||||
leaf_count: 9,
|
||||
items: vec![H256::repeat_byte(1), H256::repeat_byte(2)],
|
||||
}
|
||||
.encode(),
|
||||
),
|
||||
};
|
||||
|
||||
// when
|
||||
@@ -218,6 +204,5 @@ mod tests {
|
||||
|
||||
// then
|
||||
assert_eq!(actual, expected);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,8 +20,8 @@
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use crate::*;
|
||||
use frame_support::traits::OnInitialize;
|
||||
use frame_benchmarking::{benchmarks_instance_pallet, impl_benchmark_test_suite};
|
||||
use frame_support::traits::OnInitialize;
|
||||
|
||||
benchmarks_instance_pallet! {
|
||||
on_initialize {
|
||||
@@ -37,8 +37,4 @@ benchmarks_instance_pallet! {
|
||||
}
|
||||
}
|
||||
|
||||
impl_benchmark_test_suite!(
|
||||
Pallet,
|
||||
crate::tests::new_test_ext(),
|
||||
crate::mock::Test,
|
||||
);
|
||||
impl_benchmark_test_suite!(Pallet, crate::tests::new_test_ext(), crate::mock::Test,);
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
//! This file was not auto-generated.
|
||||
|
||||
use frame_support::weights::{
|
||||
Weight, constants::{WEIGHT_PER_NANOS, RocksDbWeight as DbWeight},
|
||||
constants::{RocksDbWeight as DbWeight, WEIGHT_PER_NANOS},
|
||||
Weight,
|
||||
};
|
||||
|
||||
impl crate::WeightInfo for () {
|
||||
@@ -34,9 +35,6 @@ impl crate::WeightInfo for () {
|
||||
leaf_weight
|
||||
.saturating_add(hash_weight)
|
||||
.saturating_add(hook_weight)
|
||||
.saturating_add(DbWeight::get().reads_writes(
|
||||
2 + peaks,
|
||||
2 + peaks,
|
||||
))
|
||||
.saturating_add(DbWeight::get().reads_writes(2 + peaks, 2 + peaks))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,38 +40,37 @@
|
||||
//!
|
||||
//! ## What for?
|
||||
//!
|
||||
//! Primary use case for this pallet is to generate MMR root hashes, that can latter on be used by
|
||||
//! BEEFY protocol (see <https://github.com/paritytech/grandpa-bridge-gadget>).
|
||||
//! MMR root hashes along with BEEFY will make it possible to build Super Light Clients (SLC) of
|
||||
//! Substrate-based chains. The SLC will be able to follow finality and can be shown proofs of more
|
||||
//! details that happened on the source chain.
|
||||
//! In that case the chain which contains the pallet generates the Root Hashes and Proofs, which
|
||||
//! are then presented to another chain acting as a light client which can verify them.
|
||||
//! Primary use case for this pallet is to generate MMR root hashes, that can latter on be used by
|
||||
//! BEEFY protocol (see <https://github.com/paritytech/grandpa-bridge-gadget>).
|
||||
//! MMR root hashes along with BEEFY will make it possible to build Super Light Clients (SLC) of
|
||||
//! Substrate-based chains. The SLC will be able to follow finality and can be shown proofs of more
|
||||
//! details that happened on the source chain.
|
||||
//! In that case the chain which contains the pallet generates the Root Hashes and Proofs, which
|
||||
//! are then presented to another chain acting as a light client which can verify them.
|
||||
//!
|
||||
//! Secondary use case is to archive historical data, but still be able to retrieve them on-demand
|
||||
//! if needed. For instance if parent block hashes are stored in the MMR it's possible at any point
|
||||
//! in time to provide a MMR proof about some past block hash, while this data can be safely pruned
|
||||
//! from on-chain storage.
|
||||
//! Secondary use case is to archive historical data, but still be able to retrieve them on-demand
|
||||
//! if needed. For instance if parent block hashes are stored in the MMR it's possible at any point
|
||||
//! in time to provide a MMR proof about some past block hash, while this data can be safely pruned
|
||||
//! from on-chain storage.
|
||||
//!
|
||||
//! NOTE This pallet is experimental and not proven to work in production.
|
||||
//!
|
||||
#![cfg_attr(not(feature = "std"), no_std)]
|
||||
|
||||
use codec::Encode;
|
||||
use frame_support::weights::Weight;
|
||||
use sp_runtime::traits;
|
||||
|
||||
mod default_weights;
|
||||
mod mmr;
|
||||
#[cfg(any(feature = "runtime-benchmarks", test))]
|
||||
mod benchmarking;
|
||||
mod default_weights;
|
||||
mod mmr;
|
||||
#[cfg(test)]
|
||||
mod mock;
|
||||
#[cfg(test)]
|
||||
mod tests;
|
||||
|
||||
pub use pallet_mmr_primitives as primitives;
|
||||
pub use pallet::*;
|
||||
pub use pallet_mmr_primitives as primitives;
|
||||
|
||||
pub trait WeightInfo {
|
||||
fn on_initialize(peaks: u64) -> Weight;
|
||||
@@ -79,9 +78,9 @@ pub trait WeightInfo {
|
||||
|
||||
#[frame_support::pallet]
|
||||
pub mod pallet {
|
||||
use super::*;
|
||||
use frame_support::pallet_prelude::*;
|
||||
use frame_system::pallet_prelude::*;
|
||||
use super::*;
|
||||
|
||||
#[pallet::pallet]
|
||||
#[pallet::generate_store(pub(super) trait Store)]
|
||||
@@ -116,8 +115,15 @@ pub mod pallet {
|
||||
///
|
||||
/// This type is actually going to be stored in the MMR.
|
||||
/// Required to be provided again, to satisfy trait bounds for storage items.
|
||||
type Hash: traits::Member + traits::MaybeSerializeDeserialize + sp_std::fmt::Debug
|
||||
+ sp_std::hash::Hash + AsRef<[u8]> + AsMut<[u8]> + Copy + Default + codec::Codec
|
||||
type Hash: traits::Member
|
||||
+ traits::MaybeSerializeDeserialize
|
||||
+ sp_std::fmt::Debug
|
||||
+ sp_std::hash::Hash
|
||||
+ AsRef<[u8]>
|
||||
+ AsMut<[u8]>
|
||||
+ Copy
|
||||
+ Default
|
||||
+ codec::Codec
|
||||
+ codec::EncodeLike;
|
||||
|
||||
/// Data stored in the leaf nodes.
|
||||
@@ -147,7 +153,8 @@ pub mod pallet {
|
||||
/// Latest MMR Root hash.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn mmr_root_hash)]
|
||||
pub type RootHash<T: Config<I>, I: 'static = ()> = StorageValue<_, <T as Config<I>>::Hash, ValueQuery>;
|
||||
pub type RootHash<T: Config<I>, I: 'static = ()> =
|
||||
StorageValue<_, <T as Config<I>>::Hash, ValueQuery>;
|
||||
|
||||
/// Current size of the MMR (number of leaves).
|
||||
#[pallet::storage]
|
||||
@@ -160,13 +167,8 @@ pub mod pallet {
|
||||
/// are pruned and only stored in the Offchain DB.
|
||||
#[pallet::storage]
|
||||
#[pallet::getter(fn mmr_peak)]
|
||||
pub type Nodes<T: Config<I>, I: 'static = ()> = StorageMap<
|
||||
_,
|
||||
Identity,
|
||||
u64,
|
||||
<T as Config<I>>::Hash,
|
||||
OptionQuery
|
||||
>;
|
||||
pub type Nodes<T: Config<I>, I: 'static = ()> =
|
||||
StorageMap<_, Identity, u64, <T as Config<I>>::Hash, OptionQuery>;
|
||||
|
||||
#[pallet::hooks]
|
||||
impl<T: Config<I>, I: 'static> Hooks<BlockNumberFor<T>> for Pallet<T, I> {
|
||||
@@ -211,7 +213,8 @@ pub fn verify_leaf_proof<H, L>(
|
||||
root: H::Output,
|
||||
leaf: mmr::Node<H, L>,
|
||||
proof: primitives::Proof<H::Output>,
|
||||
) -> Result<(), primitives::Error> where
|
||||
) -> Result<(), primitives::Error>
|
||||
where
|
||||
H: traits::Hash,
|
||||
L: primitives::FullLeaf,
|
||||
{
|
||||
@@ -234,10 +237,9 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
/// (Offchain Worker or Runtime API call), since it requires
|
||||
/// all the leaves to be present.
|
||||
/// It may return an error or panic if used incorrectly.
|
||||
pub fn generate_proof(leaf_index: u64) -> Result<
|
||||
(LeafOf<T, I>, primitives::Proof<<T as Config<I>>::Hash>),
|
||||
primitives::Error,
|
||||
> {
|
||||
pub fn generate_proof(
|
||||
leaf_index: u64,
|
||||
) -> Result<(LeafOf<T, I>, primitives::Proof<<T as Config<I>>::Hash>), primitives::Error> {
|
||||
let mmr: ModuleMmr<mmr::storage::OffchainStorage, T, I> = mmr::Mmr::new(Self::mmr_leaves());
|
||||
mmr.generate_proof(leaf_index)
|
||||
}
|
||||
@@ -252,13 +254,12 @@ impl<T: Config<I>, I: 'static> Pallet<T, I> {
|
||||
leaf: LeafOf<T, I>,
|
||||
proof: primitives::Proof<<T as Config<I>>::Hash>,
|
||||
) -> Result<(), primitives::Error> {
|
||||
if proof.leaf_count > Self::mmr_leaves()
|
||||
|| proof.leaf_count == 0
|
||||
|| proof.items.len() as u32 > mmr::utils::NodesUtils::new(proof.leaf_count).depth()
|
||||
if proof.leaf_count > Self::mmr_leaves() ||
|
||||
proof.leaf_count == 0 ||
|
||||
proof.items.len() as u32 > mmr::utils::NodesUtils::new(proof.leaf_count).depth()
|
||||
{
|
||||
return Err(primitives::Error::Verify.log_debug(
|
||||
"The proof has incorrect number of leaves or proof items."
|
||||
));
|
||||
return Err(primitives::Error::Verify
|
||||
.log_debug("The proof has incorrect number of leaves or proof items."))
|
||||
}
|
||||
|
||||
let mmr: ModuleMmr<mmr::storage::RuntimeStorage, T, I> = mmr::Mmr::new(proof.leaf_count);
|
||||
|
||||
@@ -16,13 +16,13 @@
|
||||
// limitations under the License.
|
||||
|
||||
use crate::{
|
||||
Config, HashingOf,
|
||||
mmr::{
|
||||
Node, NodeOf, Hasher,
|
||||
storage::{Storage, OffchainStorage, RuntimeStorage},
|
||||
storage::{OffchainStorage, RuntimeStorage, Storage},
|
||||
utils::NodesUtils,
|
||||
Hasher, Node, NodeOf,
|
||||
},
|
||||
primitives::{self, Error},
|
||||
Config, HashingOf,
|
||||
};
|
||||
#[cfg(not(feature = "std"))]
|
||||
use sp_std::vec;
|
||||
@@ -32,45 +32,39 @@ pub fn verify_leaf_proof<H, L>(
|
||||
root: H::Output,
|
||||
leaf: Node<H, L>,
|
||||
proof: primitives::Proof<H::Output>,
|
||||
) -> Result<bool, Error> where
|
||||
) -> Result<bool, Error>
|
||||
where
|
||||
H: sp_runtime::traits::Hash,
|
||||
L: primitives::FullLeaf,
|
||||
{
|
||||
let size = NodesUtils::new(proof.leaf_count).size();
|
||||
let leaf_position = mmr_lib::leaf_index_to_pos(proof.leaf_index);
|
||||
|
||||
let p = mmr_lib::MerkleProof::<
|
||||
Node<H, L>,
|
||||
Hasher<H, L>,
|
||||
>::new(
|
||||
let p = mmr_lib::MerkleProof::<Node<H, L>, Hasher<H, L>>::new(
|
||||
size,
|
||||
proof.items.into_iter().map(Node::Hash).collect(),
|
||||
);
|
||||
p.verify(
|
||||
Node::Hash(root),
|
||||
vec![(leaf_position, leaf)],
|
||||
).map_err(|e| Error::Verify.log_debug(e))
|
||||
p.verify(Node::Hash(root), vec![(leaf_position, leaf)])
|
||||
.map_err(|e| Error::Verify.log_debug(e))
|
||||
}
|
||||
|
||||
/// A wrapper around a MMR library to expose limited functionality.
|
||||
///
|
||||
/// Available functions depend on the storage kind ([Runtime](crate::mmr::storage::RuntimeStorage)
|
||||
/// vs [Off-chain](crate::mmr::storage::OffchainStorage)).
|
||||
pub struct Mmr<StorageType, T, I, L> where
|
||||
pub struct Mmr<StorageType, T, I, L>
|
||||
where
|
||||
T: Config<I>,
|
||||
I: 'static,
|
||||
L: primitives::FullLeaf,
|
||||
Storage<StorageType, T, I, L>: mmr_lib::MMRStore<NodeOf<T, I, L>>,
|
||||
{
|
||||
mmr: mmr_lib::MMR<
|
||||
NodeOf<T, I, L>,
|
||||
Hasher<HashingOf<T, I>, L>,
|
||||
Storage<StorageType, T, I, L>
|
||||
>,
|
||||
mmr: mmr_lib::MMR<NodeOf<T, I, L>, Hasher<HashingOf<T, I>, L>, Storage<StorageType, T, I, L>>,
|
||||
leaves: u64,
|
||||
}
|
||||
|
||||
impl<StorageType, T, I, L> Mmr<StorageType, T, I, L> where
|
||||
impl<StorageType, T, I, L> Mmr<StorageType, T, I, L>
|
||||
where
|
||||
T: Config<I>,
|
||||
I: 'static,
|
||||
L: primitives::FullLeaf,
|
||||
@@ -79,10 +73,7 @@ impl<StorageType, T, I, L> Mmr<StorageType, T, I, L> where
|
||||
/// Create a pointer to an existing MMR with given number of leaves.
|
||||
pub fn new(leaves: u64) -> Self {
|
||||
let size = NodesUtils::new(leaves).size();
|
||||
Self {
|
||||
mmr: mmr_lib::MMR::new(size, Default::default()),
|
||||
leaves,
|
||||
}
|
||||
Self { mmr: mmr_lib::MMR::new(size, Default::default()), leaves }
|
||||
}
|
||||
|
||||
/// Verify proof of a single leaf.
|
||||
@@ -91,19 +82,14 @@ impl<StorageType, T, I, L> Mmr<StorageType, T, I, L> where
|
||||
leaf: L,
|
||||
proof: primitives::Proof<<T as Config<I>>::Hash>,
|
||||
) -> Result<bool, Error> {
|
||||
let p = mmr_lib::MerkleProof::<
|
||||
NodeOf<T, I, L>,
|
||||
Hasher<HashingOf<T, I>, L>,
|
||||
>::new(
|
||||
let p = mmr_lib::MerkleProof::<NodeOf<T, I, L>, Hasher<HashingOf<T, I>, L>>::new(
|
||||
self.mmr.mmr_size(),
|
||||
proof.items.into_iter().map(Node::Hash).collect(),
|
||||
);
|
||||
let position = mmr_lib::leaf_index_to_pos(proof.leaf_index);
|
||||
let root = self.mmr.get_root().map_err(|e| Error::GetRoot.log_error(e))?;
|
||||
p.verify(
|
||||
root,
|
||||
vec![(position, Node::Data(leaf))],
|
||||
).map_err(|e| Error::Verify.log_debug(e))
|
||||
p.verify(root, vec![(position, Node::Data(leaf))])
|
||||
.map_err(|e| Error::Verify.log_debug(e))
|
||||
}
|
||||
|
||||
/// Return the internal size of the MMR (number of nodes).
|
||||
@@ -114,19 +100,18 @@ impl<StorageType, T, I, L> Mmr<StorageType, T, I, L> where
|
||||
}
|
||||
|
||||
/// Runtime specific MMR functions.
|
||||
impl<T, I, L> Mmr<RuntimeStorage, T, I, L> where
|
||||
impl<T, I, L> Mmr<RuntimeStorage, T, I, L>
|
||||
where
|
||||
T: Config<I>,
|
||||
I: 'static,
|
||||
L: primitives::FullLeaf,
|
||||
{
|
||||
|
||||
/// Push another item to the MMR.
|
||||
///
|
||||
/// Returns element position (index) in the MMR.
|
||||
pub fn push(&mut self, leaf: L) -> Option<u64> {
|
||||
let position = self.mmr.push(Node::Data(leaf))
|
||||
.map_err(|e| Error::Push.log_error(e))
|
||||
.ok()?;
|
||||
let position =
|
||||
self.mmr.push(Node::Data(leaf)).map_err(|e| Error::Push.log_error(e)).ok()?;
|
||||
|
||||
self.leaves += 1;
|
||||
|
||||
@@ -143,7 +128,8 @@ impl<T, I, L> Mmr<RuntimeStorage, T, I, L> where
|
||||
}
|
||||
|
||||
/// Off-chain specific MMR functions.
|
||||
impl<T, I, L> Mmr<OffchainStorage, T, I, L> where
|
||||
impl<T, I, L> Mmr<OffchainStorage, T, I, L>
|
||||
where
|
||||
T: Config<I>,
|
||||
I: 'static,
|
||||
L: primitives::FullLeaf + codec::Decode,
|
||||
@@ -152,10 +138,10 @@ impl<T, I, L> Mmr<OffchainStorage, T, I, L> where
|
||||
///
|
||||
/// Proof generation requires all the nodes (or their hashes) to be available in the storage.
|
||||
/// (i.e. you can't run the function in the pruned storage).
|
||||
pub fn generate_proof(&self, leaf_index: u64) -> Result<
|
||||
(L, primitives::Proof<<T as Config<I>>::Hash>),
|
||||
Error
|
||||
> {
|
||||
pub fn generate_proof(
|
||||
&self,
|
||||
leaf_index: u64,
|
||||
) -> Result<(L, primitives::Proof<<T as Config<I>>::Hash>), Error> {
|
||||
let position = mmr_lib::leaf_index_to_pos(leaf_index);
|
||||
let store = <Storage<OffchainStorage, T, I, L>>::default();
|
||||
let leaf = match mmr_lib::MMRStore::get_elem(&store, position) {
|
||||
@@ -163,7 +149,8 @@ impl<T, I, L> Mmr<OffchainStorage, T, I, L> where
|
||||
e => return Err(Error::LeafNotFound.log_debug(e)),
|
||||
};
|
||||
let leaf_count = self.leaves;
|
||||
self.mmr.gen_proof(vec![position])
|
||||
self.mmr
|
||||
.gen_proof(vec![position])
|
||||
.map_err(|e| Error::GenerateProof.log_error(e))
|
||||
.map(|p| primitives::Proof {
|
||||
leaf_index,
|
||||
@@ -173,4 +160,3 @@ impl<T, I, L> Mmr<OffchainStorage, T, I, L> where
|
||||
.map(|p| (leaf, p))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,14 +15,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
mod mmr;
|
||||
pub mod storage;
|
||||
pub mod utils;
|
||||
mod mmr;
|
||||
|
||||
use crate::primitives::FullLeaf;
|
||||
use sp_runtime::traits;
|
||||
|
||||
pub use self::mmr::{Mmr, verify_leaf_proof};
|
||||
pub use self::mmr::{verify_leaf_proof, Mmr};
|
||||
|
||||
/// Node type for runtime `T`.
|
||||
pub type NodeOf<T, I, L> = Node<<T as crate::Config<I>>::Hashing, L>;
|
||||
|
||||
@@ -21,8 +21,10 @@ use codec::Encode;
|
||||
#[cfg(not(feature = "std"))]
|
||||
use sp_std::prelude::Vec;
|
||||
|
||||
use crate::mmr::{NodeOf, Node};
|
||||
use crate::{NumberOfLeaves, Nodes, Pallet, Config, primitives};
|
||||
use crate::{
|
||||
mmr::{Node, NodeOf},
|
||||
primitives, Config, Nodes, NumberOfLeaves, Pallet,
|
||||
};
|
||||
|
||||
/// A marker type for runtime-specific storage implementation.
|
||||
///
|
||||
@@ -44,9 +46,7 @@ pub struct OffchainStorage;
|
||||
///
|
||||
/// There are two different implementations depending on the use case.
|
||||
/// See docs for [RuntimeStorage] and [OffchainStorage].
|
||||
pub struct Storage<StorageType, T, I, L>(
|
||||
sp_std::marker::PhantomData<(StorageType, T, I, L)>
|
||||
);
|
||||
pub struct Storage<StorageType, T, I, L>(sp_std::marker::PhantomData<(StorageType, T, I, L)>);
|
||||
|
||||
impl<StorageType, T, I, L> Default for Storage<StorageType, T, I, L> {
|
||||
fn default() -> Self {
|
||||
@@ -54,7 +54,8 @@ impl<StorageType, T, I, L> Default for Storage<StorageType, T, I, L> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I, L> mmr_lib::MMRStore<NodeOf<T, I, L>> for Storage<OffchainStorage, T, I, L> where
|
||||
impl<T, I, L> mmr_lib::MMRStore<NodeOf<T, I, L>> for Storage<OffchainStorage, T, I, L>
|
||||
where
|
||||
T: Config<I>,
|
||||
I: 'static,
|
||||
L: primitives::FullLeaf + codec::Decode,
|
||||
@@ -62,32 +63,30 @@ impl<T, I, L> mmr_lib::MMRStore<NodeOf<T, I, L>> for Storage<OffchainStorage, T,
|
||||
fn get_elem(&self, pos: u64) -> mmr_lib::Result<Option<NodeOf<T, I, L>>> {
|
||||
let key = Pallet::<T, I>::offchain_key(pos);
|
||||
// Retrieve the element from Off-chain DB.
|
||||
Ok(sp_io::offchain
|
||||
::local_storage_get(sp_core::offchain::StorageKind::PERSISTENT, &key)
|
||||
Ok(sp_io::offchain::local_storage_get(sp_core::offchain::StorageKind::PERSISTENT, &key)
|
||||
.and_then(|v| codec::Decode::decode(&mut &*v).ok()))
|
||||
}
|
||||
|
||||
fn append(&mut self, _: u64, _: Vec<NodeOf<T, I, L>>) -> mmr_lib::Result<()> {
|
||||
panic!("MMR must not be altered in the off-chain context.")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T, I, L> mmr_lib::MMRStore<NodeOf<T, I, L>> for Storage<RuntimeStorage, T, I, L> where
|
||||
impl<T, I, L> mmr_lib::MMRStore<NodeOf<T, I, L>> for Storage<RuntimeStorage, T, I, L>
|
||||
where
|
||||
T: Config<I>,
|
||||
I: 'static,
|
||||
L: primitives::FullLeaf,
|
||||
{
|
||||
fn get_elem(&self, pos: u64) -> mmr_lib::Result<Option<NodeOf<T, I, L>>> {
|
||||
Ok(<Nodes<T, I>>::get(pos)
|
||||
.map(Node::Hash)
|
||||
)
|
||||
Ok(<Nodes<T, I>>::get(pos).map(Node::Hash))
|
||||
}
|
||||
|
||||
fn append(&mut self, pos: u64, elems: Vec<NodeOf<T, I, L>>) -> mmr_lib::Result<()> {
|
||||
let mut leaves = crate::NumberOfLeaves::<T, I>::get();
|
||||
let mut size = crate::mmr::utils::NodesUtils::new(leaves).size();
|
||||
if pos != size {
|
||||
return Err(mmr_lib::Error::InconsistentStore);
|
||||
return Err(mmr_lib::Error::InconsistentStore)
|
||||
}
|
||||
|
||||
for elem in elems {
|
||||
|
||||
@@ -49,9 +49,7 @@ impl NodesUtils {
|
||||
return 0
|
||||
}
|
||||
|
||||
64 - self.no_of_leaves
|
||||
.next_power_of_two()
|
||||
.leading_zeros()
|
||||
64 - self.no_of_leaves.next_power_of_two().leading_zeros()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -123,9 +121,6 @@ mod tests {
|
||||
actual_sizes.push(mmr.size());
|
||||
})
|
||||
}
|
||||
assert_eq!(
|
||||
sizes[1..],
|
||||
actual_sizes[..],
|
||||
);
|
||||
assert_eq!(sizes[1..], actual_sizes[..],);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,21 +15,18 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate as pallet_mmr;
|
||||
use crate::*;
|
||||
|
||||
use codec::{Encode, Decode};
|
||||
use codec::{Decode, Encode};
|
||||
use frame_support::parameter_types;
|
||||
use pallet_mmr_primitives::{LeafDataProvider, Compact};
|
||||
use pallet_mmr_primitives::{Compact, LeafDataProvider};
|
||||
use sp_core::H256;
|
||||
use sp_runtime::{
|
||||
testing::Header,
|
||||
traits::{
|
||||
BlakeTwo256, Keccak256, IdentityLookup,
|
||||
},
|
||||
traits::{BlakeTwo256, IdentityLookup, Keccak256},
|
||||
};
|
||||
use sp_std::cell::RefCell;
|
||||
use sp_std::prelude::*;
|
||||
use sp_std::{cell::RefCell, prelude::*};
|
||||
|
||||
type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic<Test>;
|
||||
type Block = frame_system::mocking::MockBlock<Test>;
|
||||
@@ -92,10 +89,7 @@ pub struct LeafData {
|
||||
|
||||
impl LeafData {
|
||||
pub fn new(a: u64) -> Self {
|
||||
Self {
|
||||
a,
|
||||
b: Default::default(),
|
||||
}
|
||||
Self { a, b: Default::default() }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,18 +15,14 @@
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
use crate::*;
|
||||
use crate::mock::*;
|
||||
use crate::{mock::*, *};
|
||||
|
||||
use frame_support::traits::OnInitialize;
|
||||
use pallet_mmr_primitives::{Compact, Proof};
|
||||
use sp_core::{
|
||||
offchain::{testing::TestOffchainExt, OffchainDbExt, OffchainWorkerExt},
|
||||
H256,
|
||||
offchain::{
|
||||
testing::TestOffchainExt,
|
||||
OffchainWorkerExt, OffchainDbExt,
|
||||
},
|
||||
};
|
||||
use pallet_mmr_primitives::{Proof, Compact};
|
||||
|
||||
pub(crate) fn new_test_ext() -> sp_io::TestExternalities {
|
||||
frame_system::GenesisConfig::default().build_storage::<Test>().unwrap().into()
|
||||
@@ -58,13 +54,12 @@ pub(crate) fn hex(s: &str) -> H256 {
|
||||
|
||||
type BlockNumber = <Test as frame_system::Config>::BlockNumber;
|
||||
|
||||
fn decode_node(v: Vec<u8>) -> mmr::Node<
|
||||
<Test as Config>::Hashing,
|
||||
((BlockNumber, H256), LeafData),
|
||||
> {
|
||||
fn decode_node(
|
||||
v: Vec<u8>,
|
||||
) -> mmr::Node<<Test as Config>::Hashing, ((BlockNumber, H256), LeafData)> {
|
||||
use crate::primitives::DataOrHash;
|
||||
type A = DataOrHash::<<Test as Config>::Hashing, (BlockNumber, H256)>;
|
||||
type B = DataOrHash::<<Test as Config>::Hashing, LeafData>;
|
||||
type A = DataOrHash<<Test as Config>::Hashing, (BlockNumber, H256)>;
|
||||
type B = DataOrHash<<Test as Config>::Hashing, LeafData>;
|
||||
type Node = mmr::Node<<Test as Config>::Hashing, (A, B)>;
|
||||
let tuple: Node = codec::Decode::decode(&mut &v[..]).unwrap();
|
||||
|
||||
@@ -89,7 +84,9 @@ fn should_start_empty() {
|
||||
// given
|
||||
assert_eq!(
|
||||
crate::RootHash::<Test>::get(),
|
||||
"0000000000000000000000000000000000000000000000000000000000000000".parse().unwrap()
|
||||
"0000000000000000000000000000000000000000000000000000000000000000"
|
||||
.parse()
|
||||
.unwrap()
|
||||
);
|
||||
assert_eq!(crate::NumberOfLeaves::<Test>::get(), 0);
|
||||
assert_eq!(crate::Nodes::<Test>::get(0), None);
|
||||
@@ -99,8 +96,10 @@ fn should_start_empty() {
|
||||
|
||||
// then
|
||||
assert_eq!(crate::NumberOfLeaves::<Test>::get(), 1);
|
||||
assert_eq!(crate::Nodes::<Test>::get(0),
|
||||
Some(hex("4320435e8c3318562dba60116bdbcc0b82ffcecb9bb39aae3300cfda3ad0b8b0")));
|
||||
assert_eq!(
|
||||
crate::Nodes::<Test>::get(0),
|
||||
Some(hex("4320435e8c3318562dba60116bdbcc0b82ffcecb9bb39aae3300cfda3ad0b8b0"))
|
||||
);
|
||||
assert_eq!(
|
||||
crate::RootHash::<Test>::get(),
|
||||
hex("4320435e8c3318562dba60116bdbcc0b82ffcecb9bb39aae3300cfda3ad0b8b0")
|
||||
@@ -120,35 +119,41 @@ fn should_append_to_mmr_when_on_initialize_is_called() {
|
||||
|
||||
// then
|
||||
assert_eq!(crate::NumberOfLeaves::<Test>::get(), 2);
|
||||
assert_eq!((
|
||||
crate::Nodes::<Test>::get(0),
|
||||
crate::Nodes::<Test>::get(1),
|
||||
crate::Nodes::<Test>::get(2),
|
||||
crate::Nodes::<Test>::get(3),
|
||||
crate::RootHash::<Test>::get(),
|
||||
), (
|
||||
Some(hex("4320435e8c3318562dba60116bdbcc0b82ffcecb9bb39aae3300cfda3ad0b8b0")),
|
||||
Some(hex("ad4cbc033833612ccd4626d5f023b9dfc50a35e838514dd1f3c86f8506728705")),
|
||||
Some(hex("672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854")),
|
||||
None,
|
||||
hex("672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854"),
|
||||
));
|
||||
assert_eq!(
|
||||
(
|
||||
crate::Nodes::<Test>::get(0),
|
||||
crate::Nodes::<Test>::get(1),
|
||||
crate::Nodes::<Test>::get(2),
|
||||
crate::Nodes::<Test>::get(3),
|
||||
crate::RootHash::<Test>::get(),
|
||||
),
|
||||
(
|
||||
Some(hex("4320435e8c3318562dba60116bdbcc0b82ffcecb9bb39aae3300cfda3ad0b8b0")),
|
||||
Some(hex("ad4cbc033833612ccd4626d5f023b9dfc50a35e838514dd1f3c86f8506728705")),
|
||||
Some(hex("672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854")),
|
||||
None,
|
||||
hex("672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854"),
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
// make sure the leaves end up in the offchain DB
|
||||
ext.persist_offchain_overlay();
|
||||
let offchain_db = ext.offchain_db();
|
||||
assert_eq!(offchain_db.get(&MMR::offchain_key(0)).map(decode_node), Some(mmr::Node::Data((
|
||||
(0, H256::repeat_byte(1)),
|
||||
LeafData::new(1),
|
||||
))));
|
||||
assert_eq!(offchain_db.get(&MMR::offchain_key(1)).map(decode_node), Some(mmr::Node::Data((
|
||||
(1, H256::repeat_byte(2)),
|
||||
LeafData::new(2),
|
||||
))));
|
||||
assert_eq!(offchain_db.get(&MMR::offchain_key(2)).map(decode_node), Some(mmr::Node::Hash(
|
||||
hex("672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854")
|
||||
)));
|
||||
assert_eq!(
|
||||
offchain_db.get(&MMR::offchain_key(0)).map(decode_node),
|
||||
Some(mmr::Node::Data(((0, H256::repeat_byte(1)), LeafData::new(1),)))
|
||||
);
|
||||
assert_eq!(
|
||||
offchain_db.get(&MMR::offchain_key(1)).map(decode_node),
|
||||
Some(mmr::Node::Data(((1, H256::repeat_byte(2)), LeafData::new(2),)))
|
||||
);
|
||||
assert_eq!(
|
||||
offchain_db.get(&MMR::offchain_key(2)).map(decode_node),
|
||||
Some(mmr::Node::Hash(hex(
|
||||
"672c04a9cd05a644789d769daa552d35d8de7c33129f8a7cbf49e595234c4854"
|
||||
)))
|
||||
);
|
||||
assert_eq!(offchain_db.get(&MMR::offchain_key(3)), None);
|
||||
}
|
||||
|
||||
@@ -161,15 +166,18 @@ fn should_construct_larger_mmr_correctly() {
|
||||
|
||||
// then
|
||||
assert_eq!(crate::NumberOfLeaves::<Test>::get(), 7);
|
||||
assert_eq!((
|
||||
crate::Nodes::<Test>::get(0),
|
||||
crate::Nodes::<Test>::get(10),
|
||||
crate::RootHash::<Test>::get(),
|
||||
), (
|
||||
Some(hex("4320435e8c3318562dba60116bdbcc0b82ffcecb9bb39aae3300cfda3ad0b8b0")),
|
||||
Some(hex("611c2174c6164952a66d985cfe1ec1a623794393e3acff96b136d198f37a648c")),
|
||||
hex("e45e25259f7930626431347fa4dd9aae7ac83b4966126d425ca70ab343709d2c"),
|
||||
));
|
||||
assert_eq!(
|
||||
(
|
||||
crate::Nodes::<Test>::get(0),
|
||||
crate::Nodes::<Test>::get(10),
|
||||
crate::RootHash::<Test>::get(),
|
||||
),
|
||||
(
|
||||
Some(hex("4320435e8c3318562dba60116bdbcc0b82ffcecb9bb39aae3300cfda3ad0b8b0")),
|
||||
Some(hex("611c2174c6164952a66d985cfe1ec1a623794393e3acff96b136d198f37a648c")),
|
||||
hex("e45e25259f7930626431347fa4dd9aae7ac83b4966126d425ca70ab343709d2c"),
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -192,41 +200,50 @@ fn should_generate_proofs_correctly() {
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// then
|
||||
assert_eq!(proofs[0], (Compact::new((
|
||||
(0, H256::repeat_byte(1)).into(),
|
||||
LeafData::new(1).into(),
|
||||
)), Proof {
|
||||
leaf_index: 0,
|
||||
leaf_count: 7,
|
||||
items: vec![
|
||||
hex("ad4cbc033833612ccd4626d5f023b9dfc50a35e838514dd1f3c86f8506728705"),
|
||||
hex("cb24f4614ad5b2a5430344c99545b421d9af83c46fd632d70a332200884b4d46"),
|
||||
hex("dca421199bdcc55bb773c6b6967e8d16675de69062b52285ca63685241fdf626"),
|
||||
],
|
||||
}));
|
||||
assert_eq!(proofs[4], (Compact::new((
|
||||
(4, H256::repeat_byte(5)).into(),
|
||||
LeafData::new(5).into(),
|
||||
)), Proof {
|
||||
leaf_index: 4,
|
||||
leaf_count: 7,
|
||||
items: vec![
|
||||
hex("ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252"),
|
||||
hex("8ed25570209d8f753d02df07c1884ddb36a3d9d4770e4608b188322151c657fe"),
|
||||
hex("611c2174c6164952a66d985cfe1ec1a623794393e3acff96b136d198f37a648c"),
|
||||
],
|
||||
}));
|
||||
assert_eq!(proofs[6], (Compact::new((
|
||||
(6, H256::repeat_byte(7)).into(),
|
||||
LeafData::new(7).into(),
|
||||
)), Proof {
|
||||
leaf_index: 6,
|
||||
leaf_count: 7,
|
||||
items: vec![
|
||||
hex("ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252"),
|
||||
hex("7e4316ae2ebf7c3b6821cb3a46ca8b7a4f9351a9b40fcf014bb0a4fd8e8f29da"),
|
||||
],
|
||||
}));
|
||||
assert_eq!(
|
||||
proofs[0],
|
||||
(
|
||||
Compact::new(((0, H256::repeat_byte(1)).into(), LeafData::new(1).into(),)),
|
||||
Proof {
|
||||
leaf_index: 0,
|
||||
leaf_count: 7,
|
||||
items: vec![
|
||||
hex("ad4cbc033833612ccd4626d5f023b9dfc50a35e838514dd1f3c86f8506728705"),
|
||||
hex("cb24f4614ad5b2a5430344c99545b421d9af83c46fd632d70a332200884b4d46"),
|
||||
hex("dca421199bdcc55bb773c6b6967e8d16675de69062b52285ca63685241fdf626"),
|
||||
],
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
proofs[4],
|
||||
(
|
||||
Compact::new(((4, H256::repeat_byte(5)).into(), LeafData::new(5).into(),)),
|
||||
Proof {
|
||||
leaf_index: 4,
|
||||
leaf_count: 7,
|
||||
items: vec![
|
||||
hex("ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252"),
|
||||
hex("8ed25570209d8f753d02df07c1884ddb36a3d9d4770e4608b188322151c657fe"),
|
||||
hex("611c2174c6164952a66d985cfe1ec1a623794393e3acff96b136d198f37a648c"),
|
||||
],
|
||||
}
|
||||
)
|
||||
);
|
||||
assert_eq!(
|
||||
proofs[6],
|
||||
(
|
||||
Compact::new(((6, H256::repeat_byte(7)).into(), LeafData::new(7).into(),)),
|
||||
Proof {
|
||||
leaf_index: 6,
|
||||
leaf_count: 7,
|
||||
items: vec![
|
||||
hex("ae88a0825da50e953e7a359c55fe13c8015e48d03d301b8bdfc9193874da9252"),
|
||||
hex("7e4316ae2ebf7c3b6821cb3a46ca8b7a4f9351a9b40fcf014bb0a4fd8e8f29da"),
|
||||
],
|
||||
}
|
||||
)
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -280,7 +297,10 @@ fn verification_should_be_stateless() {
|
||||
|
||||
// Verify proof without relying on any on-chain data.
|
||||
let leaf = crate::primitives::DataOrHash::Data(leaf);
|
||||
assert_eq!(crate::verify_leaf_proof::<<Test as Config>::Hashing, _>(root, leaf, proof5), Ok(()));
|
||||
assert_eq!(
|
||||
crate::verify_leaf_proof::<<Test as Config>::Hashing, _>(root, leaf, proof5),
|
||||
Ok(())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
|
||||
Reference in New Issue
Block a user