feat: Rebrand Polkadot/Substrate references to PezkuwiChain

This commit systematically rebrands various references from Parity Technologies'
Polkadot/Substrate ecosystem to PezkuwiChain within the kurdistan-sdk.

Key changes include:
- Updated external repository URLs (zombienet-sdk, parity-db, parity-scale-codec, wasm-instrument) to point to pezkuwichain forks.
- Modified internal documentation and code comments to reflect PezkuwiChain naming and structure.
- Replaced direct references to  with  or specific paths within the  for XCM, Pezkuwi, and other modules.
- Cleaned up deprecated  issue and PR references in various  and  files, particularly in  and  modules.
- Adjusted image and logo URLs in documentation to point to PezkuwiChain assets.
- Removed or rephrased comments related to external Polkadot/Substrate PRs and issues.

This is a significant step towards fully customizing the SDK for the PezkuwiChain ecosystem.
This commit is contained in:
2025-12-14 00:04:10 +03:00
parent 286de54384
commit 1c0e57d984
9084 changed files with 997839 additions and 997557 deletions
@@ -0,0 +1,184 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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.
//! Benchmarks for transaction-storage Pallet
#![cfg(feature = "runtime-benchmarks")]
use crate::*;
use alloc::{vec, vec::Vec};
use pezframe_benchmarking::v2::*;
use pezframe_support::traits::{Get, OnFinalize, OnInitialize};
use pezframe_system::{pezpallet_prelude::BlockNumberFor, EventRecord, Pallet as System, RawOrigin};
use pezsp_runtime::traits::{Bounded, CheckedDiv, One, Zero};
use pezsp_transaction_storage_proof::TransactionStorageProof;
// Proof generated from max size storage:
// ```
// let mut transactions = Vec::new();
// let tx_size = DEFAULT_MAX_TRANSACTION_SIZE;
// for _ in 0..DEFAULT_MAX_BLOCK_TRANSACTIONS {
// transactions.push(vec![0; tx_size]);
// }
// let hash = vec![0; 32];
// build_proof(hash.as_slice(), transactions).unwrap().encode()
// ```
// while hardforcing target chunk key in `build_proof` to [22, 21, 1, 0].
const PROOF: &str = "\
0104000000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000000000\
0000000000000000000000000000000000000000000000000000000000000000000000000000\
00000000000000000000000000000000000000000000000000000000000014cd0780ffff8030\
2eb0a6d2f63b834d15f1e729d1c1004657e3048cf206d697eeb153f61a30ba0080302eb0a6d2\
f63b834d15f1e729d1c1004657e3048cf206d697eeb153f61a30ba80302eb0a6d2f63b834d15\
f1e729d1c1004657e3048cf206d697eeb153f61a30ba80302eb0a6d2f63b834d15f1e729d1c1\
004657e3048cf206d697eeb153f61a30ba80302eb0a6d2f63b834d15f1e729d1c1004657e304\
8cf206d697eeb153f61a30ba80302eb0a6d2f63b834d15f1e729d1c1004657e3048cf206d697\
eeb153f61a30ba80302eb0a6d2f63b834d15f1e729d1c1004657e3048cf206d697eeb153f61a\
30ba80302eb0a6d2f63b834d15f1e729d1c1004657e3048cf206d697eeb153f61a30ba80302e\
b0a6d2f63b834d15f1e729d1c1004657e3048cf206d697eeb153f61a30ba80302eb0a6d2f63b\
834d15f1e729d1c1004657e3048cf206d697eeb153f61a30ba80302eb0a6d2f63b834d15f1e7\
29d1c1004657e3048cf206d697eeb153f61a30ba80302eb0a6d2f63b834d15f1e729d1c10046\
57e3048cf206d697eeb153f61a30ba80302eb0a6d2f63b834d15f1e729d1c1004657e3048cf2\
06d697eeb153f61a30ba80302eb0a6d2f63b834d15f1e729d1c1004657e3048cf206d697eeb1\
53f61a30ba80302eb0a6d2f63b834d15f1e729d1c1004657e3048cf206d697eeb153f61a30ba\
bd058077778010fd81bc1359802f0b871aeb95e4410a8ec92b93af10ea767a2027cf4734e8de\
808da338e6b722f7bf2051901bd5bccee5e71d5cf6b1faff338ad7120b0256c28380221ce17f\
19117affa96e077905fe48a99723a065969c638593b7d9ab57b538438010fd81bc1359802f0b\
871aeb95e4410a8ec92b93af10ea767a2027cf4734e8de808da338e6b722f7bf2051901bd5bc\
cee5e71d5cf6b1faff338ad7120b0256c283008010fd81bc1359802f0b871aeb95e4410a8ec9\
2b93af10ea767a2027cf4734e8de808da338e6b722f7bf2051901bd5bccee5e71d5cf6b1faff\
338ad7120b0256c28380221ce17f19117affa96e077905fe48a99723a065969c638593b7d9ab\
57b538438010fd81bc1359802f0b871aeb95e4410a8ec92b93af10ea767a2027cf4734e8de80\
8da338e6b722f7bf2051901bd5bccee5e71d5cf6b1faff338ad7120b0256c28380221ce17f19\
117affa96e077905fe48a99723a065969c638593b7d9ab57b53843cd0780ffff804509f59593\
fd47b1a97189127ba65a5649cfb0346637f9836e155eaf891a939c00804509f59593fd47b1a9\
7189127ba65a5649cfb0346637f9836e155eaf891a939c804509f59593fd47b1a97189127ba6\
5a5649cfb0346637f9836e155eaf891a939c804509f59593fd47b1a97189127ba65a5649cfb0\
346637f9836e155eaf891a939c804509f59593fd47b1a97189127ba65a5649cfb0346637f983\
6e155eaf891a939c804509f59593fd47b1a97189127ba65a5649cfb0346637f9836e155eaf89\
1a939c804509f59593fd47b1a97189127ba65a5649cfb0346637f9836e155eaf891a939c8045\
09f59593fd47b1a97189127ba65a5649cfb0346637f9836e155eaf891a939c804509f59593fd\
47b1a97189127ba65a5649cfb0346637f9836e155eaf891a939c804509f59593fd47b1a97189\
127ba65a5649cfb0346637f9836e155eaf891a939c804509f59593fd47b1a97189127ba65a56\
49cfb0346637f9836e155eaf891a939c804509f59593fd47b1a97189127ba65a5649cfb03466\
37f9836e155eaf891a939c804509f59593fd47b1a97189127ba65a5649cfb0346637f9836e15\
5eaf891a939c804509f59593fd47b1a97189127ba65a5649cfb0346637f9836e155eaf891a93\
9c804509f59593fd47b1a97189127ba65a5649cfb0346637f9836e155eaf891a939ccd0780ff\
ff8078916e776c64ccea05e958559f015c082d9d06feafa3610fc44a5b2ef543cb818078916e\
776c64ccea05e958559f015c082d9d06feafa3610fc44a5b2ef543cb818078916e776c64ccea\
05e958559f015c082d9d06feafa3610fc44a5b2ef543cb818078916e776c64ccea05e958559f\
015c082d9d06feafa3610fc44a5b2ef543cb818078916e776c64ccea05e958559f015c082d9d\
06feafa3610fc44a5b2ef543cb81008078916e776c64ccea05e958559f015c082d9d06feafa3\
610fc44a5b2ef543cb818078916e776c64ccea05e958559f015c082d9d06feafa3610fc44a5b\
2ef543cb818078916e776c64ccea05e958559f015c082d9d06feafa3610fc44a5b2ef543cb81\
8078916e776c64ccea05e958559f015c082d9d06feafa3610fc44a5b2ef543cb818078916e77\
6c64ccea05e958559f015c082d9d06feafa3610fc44a5b2ef543cb818078916e776c64ccea05\
e958559f015c082d9d06feafa3610fc44a5b2ef543cb818078916e776c64ccea05e958559f01\
5c082d9d06feafa3610fc44a5b2ef543cb818078916e776c64ccea05e958559f015c082d9d06\
feafa3610fc44a5b2ef543cb818078916e776c64ccea05e958559f015c082d9d06feafa3610f\
c44a5b2ef543cb818078916e776c64ccea05e958559f015c082d9d06feafa3610fc44a5b2ef5\
43cb811044010000\
";
fn proof() -> Vec<u8> {
array_bytes::hex2bytes_unchecked(PROOF)
}
fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
let events = System::<T>::events();
let system_event: <T as pezframe_system::Config>::RuntimeEvent = generic_event.into();
let EventRecord { event, .. } = &events[events.len() - 1];
assert_eq!(event, &system_event);
}
pub fn run_to_block<T: Config>(n: pezframe_system::pezpallet_prelude::BlockNumberFor<T>) {
while pezframe_system::Pallet::<T>::block_number() < n {
crate::Pallet::<T>::on_finalize(pezframe_system::Pallet::<T>::block_number());
pezframe_system::Pallet::<T>::on_finalize(pezframe_system::Pallet::<T>::block_number());
pezframe_system::Pallet::<T>::set_block_number(
pezframe_system::Pallet::<T>::block_number() + One::one(),
);
pezframe_system::Pallet::<T>::on_initialize(pezframe_system::Pallet::<T>::block_number());
crate::Pallet::<T>::on_initialize(pezframe_system::Pallet::<T>::block_number());
}
}
#[benchmarks]
mod benchmarks {
use super::*;
#[benchmark]
fn store(l: Linear<1, { T::MaxTransactionSize::get() }>) {
let caller: T::AccountId = whitelisted_caller();
let initial_balance = BalanceOf::<T>::max_value().checked_div(&2u32.into()).unwrap();
T::Currency::set_balance(&caller, initial_balance);
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()), vec![0u8; l as usize]);
assert!(!BlockTransactions::<T>::get().is_empty());
assert_last_event::<T>(Event::Stored { index: 0 }.into());
}
#[benchmark]
fn renew() -> Result<(), BenchmarkError> {
let caller: T::AccountId = whitelisted_caller();
let initial_balance = BalanceOf::<T>::max_value().checked_div(&2u32.into()).unwrap();
T::Currency::set_balance(&caller, initial_balance);
Pallet::<T>::store(
RawOrigin::Signed(caller.clone()).into(),
vec![0u8; T::MaxTransactionSize::get() as usize],
)?;
run_to_block::<T>(1u32.into());
#[extrinsic_call]
_(RawOrigin::Signed(caller.clone()), BlockNumberFor::<T>::zero(), 0);
assert_last_event::<T>(Event::Renewed { index: 0 }.into());
Ok(())
}
#[benchmark]
fn check_proof_max() -> Result<(), BenchmarkError> {
run_to_block::<T>(1u32.into());
let caller: T::AccountId = whitelisted_caller();
let initial_balance = BalanceOf::<T>::max_value().checked_div(&2u32.into()).unwrap();
T::Currency::set_balance(&caller, initial_balance);
for _ in 0..T::MaxBlockTransactions::get() {
Pallet::<T>::store(
RawOrigin::Signed(caller.clone()).into(),
vec![0u8; T::MaxTransactionSize::get() as usize],
)?;
}
run_to_block::<T>(StoragePeriod::<T>::get() + BlockNumberFor::<T>::one());
let encoded_proof = proof();
let proof = TransactionStorageProof::decode(&mut &*encoded_proof).unwrap();
#[extrinsic_call]
check_proof(RawOrigin::None, proof);
assert_last_event::<T>(Event::ProofChecked.into());
Ok(())
}
impl_benchmark_test_suite!(Pallet, mock::new_test_ext(), mock::Test);
}
@@ -0,0 +1,519 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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.
//! Transaction storage pallet. Indexes transactions and manages storage proofs.
// Ensure we're `no_std` when compiling for Wasm.
#![cfg_attr(not(feature = "std"), no_std)]
mod benchmarking;
pub mod weights;
#[cfg(test)]
mod mock;
#[cfg(test)]
mod tests;
extern crate alloc;
use alloc::vec::Vec;
use codec::{Decode, Encode, MaxEncodedLen};
use core::result;
use pezframe_support::{
dispatch::GetDispatchInfo,
traits::{
fungible::{hold::Balanced, Inspect, Mutate, MutateHold},
tokens::fungible::Credit,
OnUnbalanced,
},
};
use pezsp_runtime::traits::{BlakeTwo256, Dispatchable, Hash, One, Saturating, Zero};
use pezsp_transaction_storage_proof::{
encode_index, num_chunks, random_chunk, ChunkIndex, InherentError, TransactionStorageProof,
CHUNK_SIZE, INHERENT_IDENTIFIER,
};
/// A type alias for the balance type from this pallet's point of view.
type BalanceOf<T> =
<<T as Config>::Currency as Inspect<<T as pezframe_system::Config>::AccountId>>::Balance;
pub type CreditOf<T> = Credit<<T as pezframe_system::Config>::AccountId, <T as Config>::Currency>;
// Re-export pallet items so that they can be accessed from the crate namespace.
pub use pallet::*;
pub use weights::WeightInfo;
/// Maximum bytes that can be stored in one transaction.
// Setting higher limit also requires raising the allocator limit.
pub const DEFAULT_MAX_TRANSACTION_SIZE: u32 = 8 * 1024 * 1024;
pub const DEFAULT_MAX_BLOCK_TRANSACTIONS: u32 = 512;
/// State data for a stored transaction.
#[derive(
Encode,
Decode,
Clone,
pezsp_runtime::RuntimeDebug,
PartialEq,
Eq,
scale_info::TypeInfo,
MaxEncodedLen,
)]
pub struct TransactionInfo {
/// Chunk trie root.
chunk_root: <BlakeTwo256 as Hash>::Output,
/// Plain hash of indexed data.
content_hash: <BlakeTwo256 as Hash>::Output,
/// Size of indexed data in bytes.
size: u32,
/// Total number of chunks added in the block with this transaction. This
/// is used to find transaction info by block chunk index using binary search.
///
/// Cumulative value of all previous transactions in the block; the last transaction holds the
/// total chunks value.
block_chunks: ChunkIndex,
}
impl TransactionInfo {
/// Get the number of total chunks.
///
/// See the `block_chunks` field of [`TransactionInfo`] for details.
pub fn total_chunks(txs: &[TransactionInfo]) -> ChunkIndex {
txs.last().map_or(0, |t| t.block_chunks)
}
}
#[pezframe_support::pallet]
pub mod pallet {
use super::*;
use pezframe_support::pezpallet_prelude::*;
use pezframe_system::pezpallet_prelude::*;
/// A reason for this pallet placing a hold on funds.
#[pallet::composite_enum]
pub enum HoldReason {
/// The funds are held as deposit for the used storage.
StorageFeeHold,
}
#[pallet::config]
pub trait Config: pezframe_system::Config {
/// The overarching event type.
#[allow(deprecated)]
type RuntimeEvent: From<Event<Self>> + IsType<<Self as pezframe_system::Config>::RuntimeEvent>;
/// A dispatchable call.
type RuntimeCall: Parameter
+ Dispatchable<RuntimeOrigin = Self::RuntimeOrigin>
+ GetDispatchInfo
+ From<pezframe_system::Call<Self>>;
/// The fungible type for this pallet.
type Currency: Mutate<Self::AccountId>
+ MutateHold<Self::AccountId, Reason = Self::RuntimeHoldReason>
+ Balanced<Self::AccountId>;
/// The overarching runtime hold reason.
type RuntimeHoldReason: From<HoldReason>;
/// Handler for the unbalanced decrease when fees are burned.
type FeeDestination: OnUnbalanced<CreditOf<Self>>;
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
/// Maximum number of indexed transactions in the block.
type MaxBlockTransactions: Get<u32>;
/// Maximum data set in a single transaction in bytes.
type MaxTransactionSize: Get<u32>;
}
#[pallet::error]
pub enum Error<T> {
/// Invalid configuration.
NotConfigured,
/// Renewed extrinsic is not found.
RenewedNotFound,
/// Attempting to store an empty transaction
EmptyTransaction,
/// Proof was not expected in this block.
UnexpectedProof,
/// Proof failed verification.
InvalidProof,
/// Missing storage proof.
MissingProof,
/// Unable to verify proof because state data is missing.
MissingStateData,
/// Double proof check in the block.
DoubleCheck,
/// Storage proof was not checked in the block.
ProofNotChecked,
/// Transaction is too large.
TransactionTooLarge,
/// Too many transactions in the block.
TooManyTransactions,
/// Attempted to call `store` outside of block execution.
BadContext,
}
#[pallet::pallet]
pub struct Pallet<T>(_);
#[pallet::hooks]
impl<T: Config> Hooks<BlockNumberFor<T>> for Pallet<T> {
fn on_initialize(n: BlockNumberFor<T>) -> Weight {
// TODO: https://github.com/pezkuwichain/pezkuwi-sdk/issues/160 - Replace this with benchmarked weights.
let mut weight = Weight::zero();
let db_weight = T::DbWeight::get();
// Drop obsolete roots. The proof for `obsolete` will be checked later
// in this block, so we drop `obsolete` - 1.
weight.saturating_accrue(db_weight.reads(1));
let period = StoragePeriod::<T>::get();
let obsolete = n.saturating_sub(period.saturating_add(One::one()));
if obsolete > Zero::zero() {
weight.saturating_accrue(db_weight.writes(1));
Transactions::<T>::remove(obsolete);
}
// For `on_finalize`
weight.saturating_accrue(db_weight.reads_writes(3, 1));
weight
}
fn on_finalize(n: BlockNumberFor<T>) {
assert!(
ProofChecked::<T>::take() || {
// Proof is not required for early or empty blocks.
let number = pezframe_system::Pallet::<T>::block_number();
let period = StoragePeriod::<T>::get();
let target_number = number.saturating_sub(period);
target_number.is_zero() || {
// An empty block means no transactions were stored, relying on the fact
// below that we store transactions only if they contain chunks.
!Transactions::<T>::contains_key(target_number)
}
},
"Storage proof must be checked once in the block"
);
// Insert new transactions, iff they have chunks.
let transactions = BlockTransactions::<T>::take();
let total_chunks = TransactionInfo::total_chunks(&transactions);
if total_chunks != 0 {
Transactions::<T>::insert(n, transactions);
}
}
}
#[pallet::call]
impl<T: Config> Pallet<T> {
/// Index and store data off chain. Minimum data size is 1 bytes, maximum is
/// `MaxTransactionSize`. Data will be removed after `STORAGE_PERIOD` blocks, unless `renew`
/// is called.
/// ## Complexity
/// - O(n*log(n)) of data size, as all data is pushed to an in-memory trie.
#[pallet::call_index(0)]
#[pallet::weight(T::WeightInfo::store(data.len() as u32))]
pub fn store(origin: OriginFor<T>, data: Vec<u8>) -> DispatchResult {
ensure!(data.len() > 0, Error::<T>::EmptyTransaction);
ensure!(
data.len() <= T::MaxTransactionSize::get() as usize,
Error::<T>::TransactionTooLarge
);
let sender = ensure_signed(origin)?;
Self::apply_fee(sender, data.len() as u32)?;
// Chunk data and compute storage root
let chunk_count = num_chunks(data.len() as u32);
let chunks = data.chunks(CHUNK_SIZE).map(|c| c.to_vec()).collect();
let root = pezsp_io::trie::blake2_256_ordered_root(chunks, pezsp_runtime::StateVersion::V1);
let content_hash = pezsp_io::hashing::blake2_256(&data);
let extrinsic_index =
pezframe_system::Pallet::<T>::extrinsic_index().ok_or(Error::<T>::BadContext)?;
pezsp_io::transaction_index::index(extrinsic_index, data.len() as u32, content_hash);
let mut index = 0;
BlockTransactions::<T>::mutate(|transactions| {
if transactions.len() + 1 > T::MaxBlockTransactions::get() as usize {
return Err(Error::<T>::TooManyTransactions);
}
let total_chunks = TransactionInfo::total_chunks(&transactions) + chunk_count;
index = transactions.len() as u32;
transactions
.try_push(TransactionInfo {
chunk_root: root,
size: data.len() as u32,
content_hash: content_hash.into(),
block_chunks: total_chunks,
})
.map_err(|_| Error::<T>::TooManyTransactions)?;
Ok(())
})?;
Self::deposit_event(Event::Stored { index });
Ok(())
}
/// Renew previously stored data. Parameters are the block number that contains
/// previous `store` or `renew` call and transaction index within that block.
/// Transaction index is emitted in the `Stored` or `Renewed` event.
/// Applies same fees as `store`.
/// ## Complexity
/// - O(1).
#[pallet::call_index(1)]
#[pallet::weight(T::WeightInfo::renew())]
pub fn renew(
origin: OriginFor<T>,
block: BlockNumberFor<T>,
index: u32,
) -> DispatchResultWithPostInfo {
let sender = ensure_signed(origin)?;
let transactions = Transactions::<T>::get(block).ok_or(Error::<T>::RenewedNotFound)?;
let info = transactions.get(index as usize).ok_or(Error::<T>::RenewedNotFound)?;
let extrinsic_index =
pezframe_system::Pallet::<T>::extrinsic_index().ok_or(Error::<T>::BadContext)?;
Self::apply_fee(sender, info.size)?;
pezsp_io::transaction_index::renew(extrinsic_index, info.content_hash.into());
let mut index = 0;
BlockTransactions::<T>::mutate(|transactions| {
if transactions.len() + 1 > T::MaxBlockTransactions::get() as usize {
return Err(Error::<T>::TooManyTransactions);
}
let chunks = num_chunks(info.size);
let total_chunks = TransactionInfo::total_chunks(&transactions) + chunks;
index = transactions.len() as u32;
transactions
.try_push(TransactionInfo {
chunk_root: info.chunk_root,
size: info.size,
content_hash: info.content_hash,
block_chunks: total_chunks,
})
.map_err(|_| Error::<T>::TooManyTransactions)
})?;
Self::deposit_event(Event::Renewed { index });
Ok(().into())
}
/// Check storage proof for block number `block_number() - StoragePeriod`.
/// If such a block does not exist, the proof is expected to be `None`.
///
/// ## Complexity
/// - Linear w.r.t the number of indexed transactions in the proved block for random
/// probing.
/// There's a DB read for each transaction.
#[pallet::call_index(2)]
#[pallet::weight((T::WeightInfo::check_proof_max(), DispatchClass::Mandatory))]
pub fn check_proof(
origin: OriginFor<T>,
proof: TransactionStorageProof,
) -> DispatchResultWithPostInfo {
ensure_none(origin)?;
ensure!(!ProofChecked::<T>::get(), Error::<T>::DoubleCheck);
// Get the target block metadata.
let number = pezframe_system::Pallet::<T>::block_number();
let period = StoragePeriod::<T>::get();
let target_number = number.saturating_sub(period);
ensure!(!target_number.is_zero(), Error::<T>::UnexpectedProof);
let transactions =
Transactions::<T>::get(target_number).ok_or(Error::<T>::MissingStateData)?;
// Verify the proof with a "random" chunk (randomness is based on the parent hash).
let parent_hash = pezframe_system::Pallet::<T>::parent_hash();
Self::verify_chunk_proof(proof, parent_hash.as_ref(), transactions.to_vec())?;
ProofChecked::<T>::put(true);
Self::deposit_event(Event::ProofChecked);
Ok(().into())
}
}
#[pallet::event]
#[pallet::generate_deposit(pub(super) fn deposit_event)]
pub enum Event<T: Config> {
/// Stored data under specified index.
Stored { index: u32 },
/// Renewed data under specified index.
Renewed { index: u32 },
/// Storage proof was successfully checked.
ProofChecked,
}
/// Collection of transaction metadata by block number.
#[pallet::storage]
pub type Transactions<T: Config> = StorageMap<
_,
Blake2_128Concat,
BlockNumberFor<T>,
BoundedVec<TransactionInfo, T::MaxBlockTransactions>,
OptionQuery,
>;
#[pallet::storage]
/// Storage fee per byte.
pub type ByteFee<T: Config> = StorageValue<_, BalanceOf<T>>;
#[pallet::storage]
/// Storage fee per transaction.
pub type EntryFee<T: Config> = StorageValue<_, BalanceOf<T>>;
/// Storage period for data in blocks. Should match `pezsp_storage_proof::DEFAULT_STORAGE_PERIOD`
/// for block authoring.
#[pallet::storage]
pub type StoragePeriod<T: Config> = StorageValue<_, BlockNumberFor<T>, ValueQuery>;
// Intermediates
#[pallet::storage]
pub type BlockTransactions<T: Config> =
StorageValue<_, BoundedVec<TransactionInfo, T::MaxBlockTransactions>, ValueQuery>;
/// Was the proof checked in this block?
#[pallet::storage]
pub type ProofChecked<T: Config> = StorageValue<_, bool, ValueQuery>;
#[pallet::genesis_config]
pub struct GenesisConfig<T: Config> {
pub byte_fee: BalanceOf<T>,
pub entry_fee: BalanceOf<T>,
pub storage_period: BlockNumberFor<T>,
}
impl<T: Config> Default for GenesisConfig<T> {
fn default() -> Self {
Self {
byte_fee: 10u32.into(),
entry_fee: 1000u32.into(),
storage_period: pezsp_transaction_storage_proof::DEFAULT_STORAGE_PERIOD.into(),
}
}
}
#[pallet::genesis_build]
impl<T: Config> BuildGenesisConfig for GenesisConfig<T> {
fn build(&self) {
ByteFee::<T>::put(&self.byte_fee);
EntryFee::<T>::put(&self.entry_fee);
StoragePeriod::<T>::put(&self.storage_period);
}
}
#[pallet::inherent]
impl<T: Config> ProvideInherent for Pallet<T> {
type Call = Call<T>;
type Error = InherentError;
const INHERENT_IDENTIFIER: InherentIdentifier = INHERENT_IDENTIFIER;
fn create_inherent(data: &InherentData) -> Option<Self::Call> {
let proof = data
.get_data::<TransactionStorageProof>(&Self::INHERENT_IDENTIFIER)
.unwrap_or(None);
proof.map(|proof| Call::check_proof { proof })
}
fn check_inherent(
_call: &Self::Call,
_data: &InherentData,
) -> result::Result<(), Self::Error> {
Ok(())
}
fn is_inherent(call: &Self::Call) -> bool {
matches!(call, Call::check_proof { .. })
}
}
impl<T: Config> Pallet<T> {
/// Get transaction storage information from outside of this pallet.
pub fn transaction_roots(
block: BlockNumberFor<T>,
) -> Option<BoundedVec<TransactionInfo, T::MaxBlockTransactions>> {
Transactions::<T>::get(block)
}
/// Get ByteFee storage information from outside of this pallet.
pub fn byte_fee() -> Option<BalanceOf<T>> {
ByteFee::<T>::get()
}
/// Get EntryFee storage information from outside of this pallet.
pub fn entry_fee() -> Option<BalanceOf<T>> {
EntryFee::<T>::get()
}
fn apply_fee(sender: T::AccountId, size: u32) -> DispatchResult {
let byte_fee = ByteFee::<T>::get().ok_or(Error::<T>::NotConfigured)?;
let entry_fee = EntryFee::<T>::get().ok_or(Error::<T>::NotConfigured)?;
let fee = byte_fee.saturating_mul(size.into()).saturating_add(entry_fee);
T::Currency::hold(&HoldReason::StorageFeeHold.into(), &sender, fee)?;
let (credit, _remainder) =
T::Currency::slash(&HoldReason::StorageFeeHold.into(), &sender, fee);
debug_assert!(_remainder.is_zero());
T::FeeDestination::on_unbalanced(credit);
Ok(())
}
/// Verifies that the provided proof corresponds to a randomly selected chunk from a list of
/// transactions.
pub(crate) fn verify_chunk_proof(
proof: TransactionStorageProof,
random_hash: &[u8],
infos: Vec<TransactionInfo>,
) -> Result<(), Error<T>> {
// Get the random chunk index - from all transactions in the block = [0..total_chunks).
let total_chunks: ChunkIndex = TransactionInfo::total_chunks(&infos);
ensure!(total_chunks != 0, Error::<T>::UnexpectedProof);
let selected_block_chunk_index = random_chunk(random_hash, total_chunks as _);
// Let's find the corresponding transaction and its "local" chunk index for "global"
// `selected_block_chunk_index`.
let (tx_info, tx_chunk_index) = {
// Binary search for the transaction that owns this `selected_block_chunk_index`
// chunk.
let tx_index = infos
.binary_search_by_key(&selected_block_chunk_index, |info| {
// Each `info.block_chunks` is cumulative count,
// so last chunk index = count - 1.
info.block_chunks.saturating_sub(1)
})
.unwrap_or_else(|tx_index| tx_index);
// Get the transaction and its local chunk index.
let tx_info = infos.get(tx_index).ok_or(Error::<T>::MissingStateData)?;
// We shouldn't reach this point; we rely on the fact that `fn store` does not allow
// empty transactions. Without this check, it would fail anyway below with
// `InvalidProof`.
ensure!(!tx_info.block_chunks.is_zero(), Error::<T>::EmptyTransaction);
// Convert a global chunk index into a transaction-local one.
let tx_chunks = num_chunks(tx_info.size);
let prev_chunks = tx_info.block_chunks - tx_chunks;
let tx_chunk_index = selected_block_chunk_index - prev_chunks;
(tx_info, tx_chunk_index)
};
// Verify the tx chunk proof.
ensure!(
pezsp_io::trie::blake2_256_verify_proof(
tx_info.chunk_root,
&proof.proof,
&encode_index(tx_chunk_index),
&proof.chunk,
pezsp_runtime::StateVersion::V1,
),
Error::<T>::InvalidProof
);
Ok(())
}
}
}
@@ -0,0 +1,90 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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.
//! Test environment for transaction-storage pallet.
use crate::{
self as pezpallet_transaction_storage, TransactionStorageProof, DEFAULT_MAX_BLOCK_TRANSACTIONS,
DEFAULT_MAX_TRANSACTION_SIZE,
};
use pezframe_support::{derive_impl, traits::ConstU32};
use pezsp_runtime::{traits::IdentityLookup, BuildStorage};
pub type Block = pezframe_system::mocking::MockBlock<Test>;
// Configure a mock runtime to test the pallet.
pezframe_support::construct_runtime!(
pub enum Test
{
System: pezframe_system,
Balances: pezpallet_balances,
TransactionStorage: pezpallet_transaction_storage,
}
);
#[derive_impl(pezframe_system::config_preludes::TestDefaultConfig)]
impl pezframe_system::Config for Test {
type Block = Block;
type AccountData = pezpallet_balances::AccountData<u64>;
type AccountId = u64;
type Lookup = IdentityLookup<Self::AccountId>;
}
#[derive_impl(pezpallet_balances::config_preludes::TestDefaultConfig)]
impl pezpallet_balances::Config for Test {
type AccountStore = System;
}
impl pezpallet_transaction_storage::Config for Test {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type Currency = Balances;
type RuntimeHoldReason = RuntimeHoldReason;
type FeeDestination = ();
type WeightInfo = ();
type MaxBlockTransactions = ConstU32<{ DEFAULT_MAX_BLOCK_TRANSACTIONS }>;
type MaxTransactionSize = ConstU32<{ DEFAULT_MAX_TRANSACTION_SIZE }>;
}
pub fn new_test_ext() -> pezsp_io::TestExternalities {
let t = RuntimeGenesisConfig {
system: Default::default(),
balances: pezpallet_balances::GenesisConfig::<Test> {
balances: vec![(1, 1000000000), (2, 100), (3, 100), (4, 100)],
..Default::default()
},
transaction_storage: pezpallet_transaction_storage::GenesisConfig::<Test> {
storage_period: 10,
byte_fee: 2,
entry_fee: 200,
},
}
.build_storage()
.unwrap();
t.into()
}
pub fn run_to_block(n: u64, f: impl Fn() -> Option<TransactionStorageProof> + 'static) {
System::run_to_block_with::<AllPalletsWithSystem>(
n,
pezframe_system::RunToBlockHooks::default().before_finalize(|_| {
if let Some(proof) = f() {
TransactionStorage::check_proof(RuntimeOrigin::none(), proof).unwrap();
}
}),
);
}
@@ -0,0 +1,208 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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.
//! Tests for transaction-storage pallet.
use super::{Pallet as TransactionStorage, *};
use crate::mock::*;
use pezframe_support::{assert_noop, assert_ok};
use pezframe_system::RawOrigin;
use pezsp_runtime::{DispatchError, TokenError::FundsUnavailable};
use pezsp_transaction_storage_proof::{registration::build_proof, CHUNK_SIZE};
const MAX_DATA_SIZE: u32 = DEFAULT_MAX_TRANSACTION_SIZE;
#[test]
fn discards_data() {
new_test_ext().execute_with(|| {
run_to_block(1, || None);
let caller = 1;
assert_ok!(TransactionStorage::<Test>::store(
RawOrigin::Signed(caller).into(),
vec![0u8; 2000 as usize]
));
assert_ok!(TransactionStorage::<Test>::store(
RawOrigin::Signed(caller).into(),
vec![0u8; 2000 as usize]
));
let proof_provider = || {
let block_num = pezframe_system::Pallet::<Test>::block_number();
if block_num == 11 {
let parent_hash = pezframe_system::Pallet::<Test>::parent_hash();
build_proof(parent_hash.as_ref(), vec![vec![0u8; 2000], vec![0u8; 2000]]).unwrap()
} else {
None
}
};
run_to_block(11, proof_provider);
assert!(Transactions::<Test>::get(1).is_some());
let transactions = Transactions::<Test>::get(1).unwrap();
assert_eq!(transactions.len(), 2);
assert_eq!(TransactionInfo::total_chunks(&transactions), 16);
run_to_block(12, proof_provider);
assert!(Transactions::<Test>::get(1).is_none());
});
}
#[test]
fn burns_fee() {
new_test_ext().execute_with(|| {
run_to_block(1, || None);
let caller = 1;
assert_noop!(
TransactionStorage::<Test>::store(
RawOrigin::Signed(5).into(),
vec![0u8; 2000 as usize]
),
DispatchError::Token(FundsUnavailable),
);
assert_ok!(TransactionStorage::<Test>::store(
RawOrigin::Signed(caller).into(),
vec![0u8; 2000 as usize]
));
assert_eq!(Balances::free_balance(1), 1_000_000_000 - 2000 * 2 - 200);
});
}
#[test]
fn checks_proof() {
new_test_ext().execute_with(|| {
run_to_block(1, || None);
let caller = 1;
assert_ok!(TransactionStorage::<Test>::store(
RawOrigin::Signed(caller).into(),
vec![0u8; MAX_DATA_SIZE as usize]
));
run_to_block(10, || None);
let parent_hash = pezframe_system::Pallet::<Test>::parent_hash();
let proof = build_proof(parent_hash.as_ref(), vec![vec![0u8; MAX_DATA_SIZE as usize]])
.unwrap()
.unwrap();
assert_noop!(
TransactionStorage::<Test>::check_proof(RuntimeOrigin::none(), proof,),
Error::<Test>::UnexpectedProof,
);
run_to_block(11, || None);
let parent_hash = pezframe_system::Pallet::<Test>::parent_hash();
let invalid_proof =
build_proof(parent_hash.as_ref(), vec![vec![0u8; 1000]]).unwrap().unwrap();
assert_noop!(
TransactionStorage::<Test>::check_proof(RuntimeOrigin::none(), invalid_proof,),
Error::<Test>::InvalidProof,
);
let proof = build_proof(parent_hash.as_ref(), vec![vec![0u8; MAX_DATA_SIZE as usize]])
.unwrap()
.unwrap();
assert_ok!(TransactionStorage::<Test>::check_proof(RuntimeOrigin::none(), proof));
});
}
#[test]
fn verify_chunk_proof_works() {
new_test_ext().execute_with(|| {
// Prepare a bunch of transactions with variable chunk sizes.
let transactions = vec![
vec![0u8; CHUNK_SIZE - 1],
vec![1u8; CHUNK_SIZE],
vec![2u8; CHUNK_SIZE + 1],
vec![3u8; 2 * CHUNK_SIZE - 1],
vec![3u8; 2 * CHUNK_SIZE],
vec![3u8; 2 * CHUNK_SIZE + 1],
vec![4u8; 7 * CHUNK_SIZE - 1],
vec![4u8; 7 * CHUNK_SIZE],
vec![4u8; 7 * CHUNK_SIZE + 1],
];
let expected_total_chunks =
transactions.iter().map(|t| t.len().div_ceil(CHUNK_SIZE) as u32).sum::<u32>();
// Store a couple of transactions in one block.
run_to_block(1, || None);
let caller = 1;
for transaction in transactions.clone() {
assert_ok!(TransactionStorage::<Test>::store(
RawOrigin::Signed(caller).into(),
transaction
));
}
run_to_block(2, || None);
// Read all the block transactions metadata.
let tx_infos = Transactions::<Test>::get(1).unwrap();
let total_chunks = TransactionInfo::total_chunks(&tx_infos);
assert_eq!(expected_total_chunks, total_chunks);
assert_eq!(9, tx_infos.len());
// Verify proofs for all possible chunk indexes.
for chunk_index in 0..total_chunks {
// chunk index randomness
let mut random_hash = [0u8; 32];
random_hash[..8].copy_from_slice(&(chunk_index as u64).to_be_bytes());
let selected_chunk_index = random_chunk(random_hash.as_ref(), total_chunks);
assert_eq!(selected_chunk_index, chunk_index);
// build/check chunk proof roundtrip
let proof = build_proof(random_hash.as_ref(), transactions.clone())
.expect("valid proof")
.unwrap();
assert_ok!(TransactionStorage::<Test>::verify_chunk_proof(
proof,
random_hash.as_ref(),
tx_infos.to_vec()
));
}
});
}
#[test]
fn renews_data() {
new_test_ext().execute_with(|| {
run_to_block(1, || None);
let caller = 1;
assert_noop!(
TransactionStorage::<Test>::store(RawOrigin::Signed(caller).into(), vec![]),
Error::<Test>::EmptyTransaction
);
assert_ok!(TransactionStorage::<Test>::store(
RawOrigin::Signed(caller).into(),
vec![0u8; 2000]
));
let info = BlockTransactions::<Test>::get().last().unwrap().clone();
run_to_block(6, || None);
assert_ok!(TransactionStorage::<Test>::renew(
RawOrigin::Signed(caller).into(),
1, // block
0, // transaction
));
assert_eq!(Balances::free_balance(1), 1_000_000_000 - 4000 * 2 - 200 * 2);
let proof_provider = || {
let block_num = pezframe_system::Pallet::<Test>::block_number();
if block_num == 11 || block_num == 16 {
let parent_hash = pezframe_system::Pallet::<Test>::parent_hash();
build_proof(parent_hash.as_ref(), vec![vec![0u8; 2000]]).unwrap()
} else {
None
}
};
run_to_block(16, proof_provider);
assert!(Transactions::<Test>::get(1).is_none());
assert_eq!(Transactions::<Test>::get(6).unwrap().get(0), Some(info).as_ref());
run_to_block(17, proof_provider);
assert!(Transactions::<Test>::get(6).is_none());
});
}
@@ -0,0 +1,182 @@
// This file is part of Bizinikiwi.
// Copyright (C) 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.
//! Autogenerated weights for `pezpallet_transaction_storage`
//!
//! THIS FILE WAS AUTO-GENERATED USING THE BIZINIKIWI BENCHMARK CLI VERSION 32.0.0
//! DATE: 2024-11-08, STEPS: `50`, REPEAT: `20`, LOW RANGE: `[]`, HIGH RANGE: `[]`
//! WORST CASE MAP SIZE: `1000000`
//! HOSTNAME: `runner-wiukf8gn-project-674-concurrent-0`, CPU: `Intel(R) Xeon(R) CPU @ 2.60GHz`
//! WASM-EXECUTION: `Compiled`, CHAIN: `Some("dev")`, DB CACHE: `1024`
// Executed Command:
// ./target/production/bizinikiwi-node
// benchmark
// pallet
// --chain=dev
// --steps=50
// --repeat=20
// --pallet=pezpallet_transaction_storage
// --no-storage-info
// --no-median-slopes
// --no-min-squares
// --extrinsic=*
// --wasm-execution=compiled
// --heap-pages=4096
// --output=./bizinikiwi/pezframe/transaction-storage/src/weights.rs
// --header=./bizinikiwi/HEADER-APACHE2
// --template=./bizinikiwi/.maintain/frame-weight-template.hbs
#![cfg_attr(rustfmt, rustfmt_skip)]
#![allow(unused_parens)]
#![allow(unused_imports)]
#![allow(missing_docs)]
use pezframe_support::{traits::Get, weights::{Weight, constants::RocksDbWeight}};
use core::marker::PhantomData;
/// Weight functions needed for `pezpallet_transaction_storage`.
pub trait WeightInfo {
fn store(l: u32, ) -> Weight;
fn renew() -> Weight;
fn check_proof_max() -> Weight;
}
/// Weights for `pezpallet_transaction_storage` using the Bizinikiwi node and recommended hardware.
pub struct BizinikiwiWeight<T>(PhantomData<T>);
impl<T: pezframe_system::Config> WeightInfo for BizinikiwiWeight<T> {
/// Storage: `TransactionStorage::ByteFee` (r:1 w:0)
/// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::EntryFee` (r:1 w:0)
/// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1)
/// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`)
/// The range of component `l` is `[1, 8388608]`.
fn store(l: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `242`
// Estimated: `38351`
// Minimum execution time: 65_899_000 picoseconds.
Weight::from_parts(66_814_000, 38351)
// Standard Error: 7
.saturating_add(Weight::from_parts(7_678, 0).saturating_mul(l.into()))
.saturating_add(T::DbWeight::get().reads(4_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
/// Storage: `TransactionStorage::Transactions` (r:1 w:0)
/// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::ByteFee` (r:1 w:0)
/// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::EntryFee` (r:1 w:0)
/// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1)
/// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`)
fn renew() -> Weight {
// Proof Size summary in bytes:
// Measured: `430`
// Estimated: `40351`
// Minimum execution time: 87_876_000 picoseconds.
Weight::from_parts(91_976_000, 40351)
.saturating_add(T::DbWeight::get().reads(5_u64))
.saturating_add(T::DbWeight::get().writes(2_u64))
}
/// Storage: `TransactionStorage::ProofChecked` (r:1 w:1)
/// Proof: `TransactionStorage::ProofChecked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::StoragePeriod` (r:1 w:0)
/// Proof: `TransactionStorage::StoragePeriod` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::ChunkCount` (r:1 w:0)
/// Proof: `TransactionStorage::ChunkCount` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`)
/// Storage: `System::ParentHash` (r:1 w:0)
/// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::Transactions` (r:1 w:0)
/// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`)
fn check_proof_max() -> Weight {
// Proof Size summary in bytes:
// Measured: `37211`
// Estimated: `40351`
// Minimum execution time: 78_423_000 picoseconds.
Weight::from_parts(82_423_000, 40351)
.saturating_add(T::DbWeight::get().reads(5_u64))
.saturating_add(T::DbWeight::get().writes(1_u64))
}
}
// For backwards compatibility and tests.
impl WeightInfo for () {
/// Storage: `TransactionStorage::ByteFee` (r:1 w:0)
/// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::EntryFee` (r:1 w:0)
/// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1)
/// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`)
/// The range of component `l` is `[1, 8388608]`.
fn store(l: u32, ) -> Weight {
// Proof Size summary in bytes:
// Measured: `242`
// Estimated: `38351`
// Minimum execution time: 65_899_000 picoseconds.
Weight::from_parts(66_814_000, 38351)
// Standard Error: 7
.saturating_add(Weight::from_parts(7_678, 0).saturating_mul(l.into()))
.saturating_add(RocksDbWeight::get().reads(4_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
/// Storage: `TransactionStorage::Transactions` (r:1 w:0)
/// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::ByteFee` (r:1 w:0)
/// Proof: `TransactionStorage::ByteFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::EntryFee` (r:1 w:0)
/// Proof: `TransactionStorage::EntryFee` (`max_values`: Some(1), `max_size`: Some(16), added: 511, mode: `MaxEncodedLen`)
/// Storage: `Balances::Holds` (r:1 w:1)
/// Proof: `Balances::Holds` (`max_values`: None, `max_size`: Some(355), added: 2830, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::BlockTransactions` (r:1 w:1)
/// Proof: `TransactionStorage::BlockTransactions` (`max_values`: Some(1), `max_size`: Some(36866), added: 37361, mode: `MaxEncodedLen`)
fn renew() -> Weight {
// Proof Size summary in bytes:
// Measured: `430`
// Estimated: `40351`
// Minimum execution time: 87_876_000 picoseconds.
Weight::from_parts(91_976_000, 40351)
.saturating_add(RocksDbWeight::get().reads(5_u64))
.saturating_add(RocksDbWeight::get().writes(2_u64))
}
/// Storage: `TransactionStorage::ProofChecked` (r:1 w:1)
/// Proof: `TransactionStorage::ProofChecked` (`max_values`: Some(1), `max_size`: Some(1), added: 496, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::StoragePeriod` (r:1 w:0)
/// Proof: `TransactionStorage::StoragePeriod` (`max_values`: Some(1), `max_size`: Some(4), added: 499, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::ChunkCount` (r:1 w:0)
/// Proof: `TransactionStorage::ChunkCount` (`max_values`: None, `max_size`: Some(24), added: 2499, mode: `MaxEncodedLen`)
/// Storage: `System::ParentHash` (r:1 w:0)
/// Proof: `System::ParentHash` (`max_values`: Some(1), `max_size`: Some(32), added: 527, mode: `MaxEncodedLen`)
/// Storage: `TransactionStorage::Transactions` (r:1 w:0)
/// Proof: `TransactionStorage::Transactions` (`max_values`: None, `max_size`: Some(36886), added: 39361, mode: `MaxEncodedLen`)
fn check_proof_max() -> Weight {
// Proof Size summary in bytes:
// Measured: `37211`
// Estimated: `40351`
// Minimum execution time: 78_423_000 picoseconds.
Weight::from_parts(82_423_000, 40351)
.saturating_add(RocksDbWeight::get().reads(5_u64))
.saturating_add(RocksDbWeight::get().writes(1_u64))
}
}