mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-08-06 22:25:49 +00:00
49b6dfd2e5
* Cargo.lock after merge * Restore scale-info feature * Fully qualify TypeInfo derive * Skip PendingSwap T * Add missing skip_type_params attr * metadata docs features * Reduce pallet event attribute to struct * Cargo.lock * Update frame/balances/src/tests_composite.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Line widths check * Cargo.lock * Add scale-info/std * Update frame/system/src/lib.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Use `skip_type_params` to remove `TypeInfo` requirements on checks * Revert "Remove unused Call metadata stuff" This reverts commit 41311f85 * Skip BalanceSwapAction type parameter * Remove unused event metadata macro * Update frame-metadata * Update primitives/npos-elections/compact/src/codec.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Manual TypeInfo for Header * Remove TypeInfo requirement for consts in BoundedVec etc. * Another TypeInfo bound removed * review: fix indentation * TypeInfo impls for Identity types * Add some todos to add custom TypeInfo impls * Update frame/support/procedural/src/pallet/expand/pallet_struct.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Add some todos to add custom TypeInfo impls * Add a test for manual Data TypeInfo impl * Add custom TypeInfo impl for Vote * Era custom TypeInfo crimes * Revert finality-grandpa version to 0.14.z * review: renamed module to pallet_constants_metadata * New line at end of file * Add missing scale-info/std * Update frame/support/src/storage/types/mod.rs Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> * Remove StorageEntryType::Map unused flag * Add missing scale-info dependency after merge * SignedExtension::AdditionalSigned metadata * Update frame-metadata, use abbreviated docs and args fields * Update frame/example/Cargo.toml Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Add scale_info/std and remove unused scale-info dependency * Remove scale-info dependency * Remove treasury pallet::metadata * Remove redundant Event test * Add back scale-info as dev dependency * fix error metadata when no error defined in decl_module * Add Module3 to tests * Fix metadata test * Add docs feature to frame-support test * WIP fixing pallet metadata test * Remove redundant FunctionMetadata, FunctionArgumentMetadata as per https://github.com/paritytech/frame-metadata/pull/20 * Use main branch of frame-metadata * Use patch of scale-info for latest changes * Use latest patched scale-info * Manual TypeInfo for DigestItem * Manual TypeInfo for DigestItem * Update scale-info * Skip __Ignore variants for Error, depends on https://github.com/paritytech/scale-info/pull/117 * Named fields for FRAME v2 pallet Call variants * Named fields for FRAME v1 pallet Call variants * Add missing scale-info dependency * WIP expand benchmark call variant * fix benchmark with new function create a new function for each variant of a pallet call. This function is called by benchmarking macro in order not to break call creation with unnamed argument * fix tests * more fix * Fix staking tests * Fix offchain workers calls * Cherry pick rustfmt.toml from master * cargo +nightly-2021-06-22 fmt --all * Update to new call variant structs * More call variant struct updates * Remove unused import * More call variant structs * More call variant structs * Even more call variant structs * Mooar variant structs * Evermore variant structs * Call variant structs ad infinitum * Fmt * More call variants * Last call variant * Call variants all done? * Fix SS58Prefix type * Potential workaround for BitFlags<IdentityFields> TypeInfo * Enable docs capturing for Call, Event, and Error types * Fix IdentityFields TypeInfo * Remove metadata-docs feature * Add capture_docs = true for legacy Call, Event and Error types * Fmt * Fix metadata test type * Update benchmarks with call struct variants * Fmt * More test fixes * Fmt * Fix benches * Use latest capture_docs attr * Latest scale_info * Fmt * review: change &Vec to &[] * Remove pallet metadata attr * review: remove commented out test code * review: skip_type_params trailing comma suggestion * Update to scale-info 0.10.0 * Update construct_runtime ui tests, different because of metadata TypeInfo impls * Add some TypeInfo derives for UI tests * Update storage ensure span ui stderrs * Update call argument bound ui tests Possibly changed because change from tuple to struct variants? * Add scale-info dev dependency * Update to latest finality-grandpa release * review: missing newline * review: missing scale-info/std * review: remove duplicate scale-info/std * review: remove fully qualified TypeInfo * review: add missing scale-info/std * review: remove unnecessary imports. * Fmt * Use crates.io RC version of frame-metadata * Remove scale-info/std because it is a dev dependency * Add missing scale_info dev-dependency for test * Delete empty metadata folder * Fix sp_std import * review: improve manual UncheckedExtrinsic TypeInfo impl * review: use full scale-info for dev-dependency * Remove DefaultByteGetter impl * review: derive TypeInfo for generic header * Fmt * Update primitives/runtime/src/generic/unchecked_extrinsic.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Update primitives/runtime/src/generic/unchecked_extrinsic.rs Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> * Update bin/node/executor/Cargo.toml Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Update frame/identity/src/types.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Update frame/support/src/dispatch.rs Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com> * Remove redundant derive * Simplify scale-info dependency * Strip underscore prefix from call variant struct names * Another underscore field * More underscore fields * Another underscore field * Update to frame-metadata 14.0.0-rc.2 with combined StorageEntryType::Map * Fmt * Revert weights formatting * Fix up some tests * Fix up some tests for StorageEntryTypeMetadata * scale-info dev dependency * Fix test error * Add missing TypeInfo derives * Add back missing scale-info dependency * Add back missing scale-info dependency * Fix npos compact impls * Cargo.lock * Fmt * Fix errors * Fmt * Fix renamed raw_solution field * Fix error * Fmt * Fix some benchmarks * Fmt * Stray R * Fix * Add missing TypeInfos * ui test fix * Fix line widths * Revert "ui test fix" This reverts commit 2d15ec058a216e3f92d713f1174603a2bb1eac65. * Upgrade to scale-info 0.11.0 * Revert "Upgrade to scale-info 0.11.0" This reverts commit 047bb179085a0059c36cd20ab405f55cf0867e28. * Add Runtime type * Update to scale-info 0.12 * Update to scale-info 1.0 * Update frame-metadata to version 14.0.0 * Patch finality-grandpa until release available * Fix metadata tests * Fix metadata tests * Fmt * Remove patched finality-grandpa * Fix tests, use scale_info imports * Fix pallet tests * Add BlockNumber TypeInfo bound * ui test fix * Cargo.lock * Remove pallet metadata * Cargo.lock * Add missing scale-info dependency * Remove pallet event metadata * Fix error * Fix collective errors * Semicolol * Fmt * Remove another metadata attribute * Add new variant to custom digest TypeInfo * Fmt * Cargo.lock from master * Remove comma lol * Fix example call error * Fix example call error properly Co-authored-by: Guillaume Thiolliere <gui.thiolliere@gmail.com> Co-authored-by: Keith Yeung <kungfukeith11@gmail.com> Co-authored-by: Shawn Tabrizi <shawntabrizi@gmail.com> Co-authored-by: Bastian Köcher <bkchr@users.noreply.github.com>
247 lines
7.4 KiB
Rust
247 lines
7.4 KiB
Rust
// This file is part of Substrate.
|
|
|
|
// Copyright (C) 2019-2021 Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
//! Storage proof primitives. Constains types and basic code to extract storage
|
|
//! proofs for indexed transactions.
|
|
|
|
#![cfg_attr(not(feature = "std"), no_std)]
|
|
|
|
use sp_std::{prelude::*, result::Result};
|
|
|
|
use codec::{Decode, Encode};
|
|
use sp_inherents::{InherentData, InherentIdentifier, IsFatalError};
|
|
use sp_runtime::traits::{Block as BlockT, NumberFor};
|
|
|
|
pub use sp_inherents::Error;
|
|
|
|
/// The identifier for the proof inherent.
|
|
pub const INHERENT_IDENTIFIER: InherentIdentifier = *b"tx_proof";
|
|
/// Storage period for data.
|
|
pub const DEFAULT_STORAGE_PERIOD: u32 = 100800;
|
|
/// Proof trie value size.
|
|
pub const CHUNK_SIZE: usize = 256;
|
|
|
|
/// Errors that can occur while checking the storage proof.
|
|
#[derive(Encode, sp_runtime::RuntimeDebug)]
|
|
#[cfg_attr(feature = "std", derive(Decode))]
|
|
pub enum InherentError {
|
|
InvalidProof,
|
|
TrieError,
|
|
}
|
|
|
|
impl IsFatalError for InherentError {
|
|
fn is_fatal_error(&self) -> bool {
|
|
true
|
|
}
|
|
}
|
|
|
|
/// Holds a chunk of data retrieved from storage along with
|
|
/// a proof that the data was stored at that location in the trie.
|
|
#[derive(Encode, Decode, Clone, PartialEq, Debug, scale_info::TypeInfo)]
|
|
pub struct TransactionStorageProof {
|
|
/// Data chunk that is proved to exist.
|
|
pub chunk: Vec<u8>,
|
|
/// Trie nodes that compose the proof.
|
|
pub proof: Vec<Vec<u8>>,
|
|
}
|
|
|
|
/// Auxiliary trait to extract storage proof.
|
|
pub trait TransactionStorageProofInherentData {
|
|
/// Get the proof.
|
|
fn storage_proof(&self) -> Result<Option<TransactionStorageProof>, Error>;
|
|
}
|
|
|
|
impl TransactionStorageProofInherentData for InherentData {
|
|
fn storage_proof(&self) -> Result<Option<TransactionStorageProof>, Error> {
|
|
Ok(self.get_data(&INHERENT_IDENTIFIER)?)
|
|
}
|
|
}
|
|
|
|
/// Provider for inherent data.
|
|
#[cfg(feature = "std")]
|
|
pub struct InherentDataProvider {
|
|
proof: Option<TransactionStorageProof>,
|
|
}
|
|
|
|
#[cfg(feature = "std")]
|
|
impl InherentDataProvider {
|
|
pub fn new(proof: Option<TransactionStorageProof>) -> Self {
|
|
InherentDataProvider { proof }
|
|
}
|
|
}
|
|
|
|
#[cfg(feature = "std")]
|
|
#[async_trait::async_trait]
|
|
impl sp_inherents::InherentDataProvider for InherentDataProvider {
|
|
fn provide_inherent_data(&self, inherent_data: &mut InherentData) -> Result<(), Error> {
|
|
if let Some(proof) = &self.proof {
|
|
inherent_data.put_data(INHERENT_IDENTIFIER, proof)
|
|
} else {
|
|
Ok(())
|
|
}
|
|
}
|
|
|
|
async fn try_handle_error(
|
|
&self,
|
|
identifier: &InherentIdentifier,
|
|
error: &[u8],
|
|
) -> Option<Result<(), Error>> {
|
|
if *identifier != INHERENT_IDENTIFIER {
|
|
return None
|
|
}
|
|
|
|
let error = InherentError::decode(&mut &error[..]).ok()?;
|
|
|
|
Some(Err(Error::Application(Box::from(format!("{:?}", error)))))
|
|
}
|
|
}
|
|
|
|
/// A utility function to extract a chunk index from the source of randomness.
|
|
pub fn random_chunk(random_hash: &[u8], total_chunks: u32) -> u32 {
|
|
let mut buf = [0u8; 8];
|
|
buf.copy_from_slice(&random_hash[0..8]);
|
|
let random_u64 = u64::from_be_bytes(buf);
|
|
(random_u64 % total_chunks as u64) as u32
|
|
}
|
|
|
|
/// A utility function to encode transaction index as trie key.
|
|
pub fn encode_index(input: u32) -> Vec<u8> {
|
|
codec::Encode::encode(&codec::Compact(input))
|
|
}
|
|
|
|
/// An interface to request indexed data from the client.
|
|
pub trait IndexedBody<B: BlockT> {
|
|
/// Get all indexed transactions for a block,
|
|
/// including renewed transactions.
|
|
///
|
|
/// Note that this will only fetch transactions
|
|
/// that are indexed by the runtime with `storage_index_transaction`.
|
|
fn block_indexed_body(&self, number: NumberFor<B>) -> Result<Option<Vec<Vec<u8>>>, Error>;
|
|
|
|
/// Get block number for a block hash.
|
|
fn number(&self, hash: B::Hash) -> Result<Option<NumberFor<B>>, Error>;
|
|
}
|
|
|
|
#[cfg(feature = "std")]
|
|
pub mod registration {
|
|
use super::*;
|
|
use sp_runtime::traits::{Block as BlockT, One, Saturating, Zero};
|
|
use sp_trie::TrieMut;
|
|
|
|
type Hasher = sp_core::Blake2Hasher;
|
|
type TrieLayout = sp_trie::Layout<Hasher>;
|
|
|
|
/// Create a new inherent data provider instance for a given parent block hash.
|
|
pub fn new_data_provider<B, C>(
|
|
client: &C,
|
|
parent: &B::Hash,
|
|
) -> Result<InherentDataProvider, Error>
|
|
where
|
|
B: BlockT,
|
|
C: IndexedBody<B>,
|
|
{
|
|
let parent_number = client.number(parent.clone())?.unwrap_or(Zero::zero());
|
|
let number = parent_number
|
|
.saturating_add(One::one())
|
|
.saturating_sub(DEFAULT_STORAGE_PERIOD.into());
|
|
if number.is_zero() {
|
|
// Too early to collect proofs.
|
|
return Ok(InherentDataProvider::new(None))
|
|
}
|
|
|
|
let proof = match client.block_indexed_body(number)? {
|
|
Some(transactions) if !transactions.is_empty() =>
|
|
Some(build_proof(parent.as_ref(), transactions)?),
|
|
Some(_) | None => {
|
|
// Nothing was indexed in that block.
|
|
None
|
|
},
|
|
};
|
|
Ok(InherentDataProvider::new(proof))
|
|
}
|
|
|
|
/// Build a proof for a given source of randomness and indexed transactions.
|
|
pub fn build_proof(
|
|
random_hash: &[u8],
|
|
transactions: Vec<Vec<u8>>,
|
|
) -> Result<TransactionStorageProof, Error> {
|
|
let mut db = sp_trie::MemoryDB::<Hasher>::default();
|
|
|
|
let mut target_chunk = None;
|
|
let mut target_root = Default::default();
|
|
let mut target_chunk_key = Default::default();
|
|
let mut chunk_proof = Default::default();
|
|
|
|
let total_chunks: u64 = transactions
|
|
.iter()
|
|
.map(|t| ((t.len() + CHUNK_SIZE - 1) / CHUNK_SIZE) as u64)
|
|
.sum();
|
|
let mut buf = [0u8; 8];
|
|
buf.copy_from_slice(&random_hash[0..8]);
|
|
let random_u64 = u64::from_be_bytes(buf);
|
|
let target_chunk_index = random_u64 % total_chunks;
|
|
// Generate tries for each transaction.
|
|
let mut chunk_index = 0;
|
|
for transaction in transactions {
|
|
let mut transaction_root = sp_trie::empty_trie_root::<TrieLayout>();
|
|
{
|
|
let mut trie =
|
|
sp_trie::TrieDBMut::<TrieLayout>::new(&mut db, &mut transaction_root);
|
|
let chunks = transaction.chunks(CHUNK_SIZE).map(|c| c.to_vec());
|
|
for (index, chunk) in chunks.enumerate() {
|
|
let index = encode_index(index as u32);
|
|
trie.insert(&index, &chunk).map_err(|e| Error::Application(Box::new(e)))?;
|
|
if chunk_index == target_chunk_index {
|
|
target_chunk = Some(chunk);
|
|
target_chunk_key = index;
|
|
}
|
|
chunk_index += 1;
|
|
}
|
|
trie.commit();
|
|
}
|
|
if target_chunk.is_some() && target_root == Default::default() {
|
|
target_root = transaction_root.clone();
|
|
chunk_proof = sp_trie::generate_trie_proof::<TrieLayout, _, _, _>(
|
|
&db,
|
|
transaction_root.clone(),
|
|
&[target_chunk_key.clone()],
|
|
)
|
|
.map_err(|e| Error::Application(Box::new(e)))?;
|
|
}
|
|
}
|
|
|
|
Ok(TransactionStorageProof { proof: chunk_proof, chunk: target_chunk.unwrap() })
|
|
}
|
|
|
|
#[test]
|
|
fn build_proof_check() {
|
|
use std::str::FromStr;
|
|
let random = [0u8; 32];
|
|
let proof = build_proof(&random, vec![vec![42]]).unwrap();
|
|
let root = sp_core::H256::from_str(
|
|
"0xff8611a4d212fc161dae19dd57f0f1ba9309f45d6207da13f2d3eab4c6839e91",
|
|
)
|
|
.unwrap();
|
|
sp_trie::verify_trie_proof::<TrieLayout, _, _, _>(
|
|
&root,
|
|
&proof.proof,
|
|
&[(encode_index(0), Some(proof.chunk))],
|
|
)
|
|
.unwrap();
|
|
}
|
|
}
|