Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor transaction storage pallet to use fungible traits #1800

Merged
Merged
3 changes: 2 additions & 1 deletion substrate/bin/node/runtime/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1829,7 +1829,8 @@ impl pallet_nfts::Config for Runtime {

impl pallet_transaction_storage::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type Currency = Balances;
type Fungible = Balances;
type RuntimeHoldReason = RuntimeHoldReason;
type RuntimeCall = RuntimeCall;
type FeeDestination = ();
type WeightInfo = pallet_transaction_storage::weights::SubstrateWeight<Runtime>;
Expand Down
16 changes: 8 additions & 8 deletions substrate/frame/transaction-storage/src/benchmarking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,9 @@

use super::*;
use frame_benchmarking::v1::{benchmarks, whitelisted_caller};
use frame_support::traits::{Currency, Get, OnFinalize, OnInitialize};
use frame_support::traits::{Get, OnFinalize, OnInitialize};
use frame_system::{pallet_prelude::BlockNumberFor, EventRecord, Pallet as System, RawOrigin};
use sp_runtime::traits::{Bounded, One, Zero};
use sp_runtime::traits::{Bounded, CheckedDiv, One, Zero};
use sp_std::*;
use sp_transaction_storage_proof::TransactionStorageProof;

Expand Down Expand Up @@ -103,9 +103,6 @@ fn proof() -> Vec<u8> {
array_bytes::hex2bytes_unchecked(PROOF)
}

type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;

fn assert_last_event<T: Config>(generic_event: <T as Config>::RuntimeEvent) {
let events = System::<T>::events();
let system_event: <T as frame_system::Config>::RuntimeEvent = generic_event.into();
Expand All @@ -129,7 +126,8 @@ benchmarks! {
store {
let l in 1 .. T::MaxTransactionSize::get();
let caller: T::AccountId = whitelisted_caller();
T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
let initial_balance = BalanceOf::<T>::max_value().checked_div(&2u32.into()).unwrap();
acatangiu marked this conversation as resolved.
Show resolved Hide resolved
T::Fungible::set_balance(&caller, initial_balance);
}: _(RawOrigin::Signed(caller.clone()), vec![0u8; l as usize])
verify {
assert!(!BlockTransactions::<T>::get().is_empty());
Expand All @@ -138,7 +136,8 @@ benchmarks! {

renew {
let caller: T::AccountId = whitelisted_caller();
T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
let initial_balance = BalanceOf::<T>::max_value().checked_div(&2u32.into()).unwrap();
acatangiu marked this conversation as resolved.
Show resolved Hide resolved
T::Fungible::set_balance(&caller, initial_balance);
TransactionStorage::<T>::store(
RawOrigin::Signed(caller.clone()).into(),
vec![0u8; T::MaxTransactionSize::get() as usize],
Expand All @@ -152,7 +151,8 @@ benchmarks! {
check_proof_max {
run_to_block::<T>(1u32.into());
let caller: T::AccountId = whitelisted_caller();
T::Currency::make_free_balance_be(&caller, BalanceOf::<T>::max_value());
let initial_balance = BalanceOf::<T>::max_value().checked_div(&2u32.into()).unwrap();
acatangiu marked this conversation as resolved.
Show resolved Hide resolved
T::Fungible::set_balance(&caller, initial_balance);
for _ in 0 .. T::MaxBlockTransactions::get() {
TransactionStorage::<T>::store(
RawOrigin::Signed(caller.clone()).into(),
Expand Down
38 changes: 26 additions & 12 deletions substrate/frame/transaction-storage/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,14 @@ mod tests;
use codec::{Decode, Encode, MaxEncodedLen};
use frame_support::{
dispatch::GetDispatchInfo,
traits::{Currency, OnUnbalanced, ReservableCurrency},
traits::{
fungible::{
hold::Balanced as FnBalanced, Inspect as FnInspect, Mutate as FnMutate,
MutateHold as FnMutateHold,
},
tokens::fungible::Credit,
OnUnbalanced,
},
};
use sp_runtime::traits::{BlakeTwo256, Dispatchable, Hash, One, Saturating, Zero};
use sp_std::{prelude::*, result};
Expand All @@ -42,10 +49,8 @@ use sp_transaction_storage_proof::{

/// A type alias for the balance type from this pallet's point of view.
type BalanceOf<T> =
<<T as Config>::Currency as Currency<<T as frame_system::Config>::AccountId>>::Balance;
type NegativeImbalanceOf<T> = <<T as Config>::Currency as Currency<
<T as frame_system::Config>::AccountId,
>>::NegativeImbalance;
<<T as Config>::Fungible as FnInspect<<T as frame_system::Config>::AccountId>>::Balance;
pub type CreditOf<T> = Credit<<T as frame_system::Config>::AccountId, <T as Config>::Fungible>;

// Re-export pallet items so that they can be accessed from the crate namespace.
pub use pallet::*;
Expand Down Expand Up @@ -89,6 +94,13 @@ pub mod pallet {
use frame_support::pallet_prelude::*;
use frame_system::pallet_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: frame_system::Config {
/// The overarching event type.
Expand All @@ -98,10 +110,14 @@ pub mod pallet {
+ Dispatchable<RuntimeOrigin = Self::RuntimeOrigin>
+ GetDispatchInfo
+ From<frame_system::Call<Self>>;
/// The currency trait.
type Currency: ReservableCurrency<Self::AccountId>;
/// The fungible type for this pallet.
type Fungible: FnMutate<Self::AccountId>
+ FnMutateHold<Self::AccountId, Reason = Self::RuntimeHoldReason>
+ FnBalanced<Self::AccountId>;
acatangiu marked this conversation as resolved.
Show resolved Hide resolved
/// The overarching runtime hold reason.
acatangiu marked this conversation as resolved.
Show resolved Hide resolved
type RuntimeHoldReason: From<HoldReason>;
/// Handler for the unbalanced decrease when fees are burned.
type FeeDestination: OnUnbalanced<NegativeImbalanceOf<Self>>;
type FeeDestination: OnUnbalanced<CreditOf<Self>>;
/// Weight information for extrinsics in this pallet.
type WeightInfo: WeightInfo;
/// Maximum number of indexed transactions in the block.
Expand All @@ -112,8 +128,6 @@ pub mod pallet {

#[pallet::error]
pub enum Error<T> {
/// Insufficient account balance.
InsufficientFunds,
/// Invalid configuration.
NotConfigured,
/// Renewed extrinsic is not found.
Expand Down Expand Up @@ -432,8 +446,8 @@ pub mod pallet {
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);
ensure!(T::Currency::can_slash(&sender, fee), Error::<T>::InsufficientFunds);
let (credit, _) = T::Currency::slash(&sender, fee);
T::Fungible::hold(&HoldReason::StorageFeeHold.into(), &sender, fee)?;
let (credit, _) = T::Fungible::slash(&HoldReason::StorageFeeHold.into(), &sender, fee);
T::FeeDestination::on_unbalanced(credit);
Ok(())
}
Expand Down
25 changes: 11 additions & 14 deletions substrate/frame/transaction-storage/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@
//! Test environment for transaction-storage pallet.

use crate::{
self as pallet_transaction_storage, TransactionStorageProof, DEFAULT_MAX_BLOCK_TRANSACTIONS,
DEFAULT_MAX_TRANSACTION_SIZE,
self as pallet_transaction_storage, HoldReason, TransactionStorageProof,
DEFAULT_MAX_BLOCK_TRANSACTIONS, DEFAULT_MAX_TRANSACTION_SIZE,
};
use frame_support::{
derive_impl,
traits::{ConstU16, ConstU32, ConstU64, OnFinalize, OnInitialize},
};
use frame_support::traits::{ConstU16, ConstU32, ConstU64, OnFinalize, OnInitialize};
use sp_core::H256;
use sp_runtime::{
traits::{BlakeTwo256, IdentityLookup},
Expand Down Expand Up @@ -68,26 +71,20 @@ impl frame_system::Config for Test {
type MaxConsumers = ConstU32<16>;
}

#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)]
acatangiu marked this conversation as resolved.
Show resolved Hide resolved
impl pallet_balances::Config for Test {
type Balance = u64;
type DustRemoval = ();
type RuntimeEvent = RuntimeEvent;
type ExistentialDeposit = ConstU64<1>;
type AccountStore = System;
type WeightInfo = ();
type MaxLocks = ();
type MaxReserves = ();
type ReserveIdentifier = ();
type FreezeIdentifier = ();
type MaxFreezes = ();
type RuntimeHoldReason = ();
type MaxHolds = ();
type RuntimeHoldReason = HoldReason;
type MaxHolds = ConstU32<128>;
}

impl pallet_transaction_storage::Config for Test {
type RuntimeEvent = RuntimeEvent;
type RuntimeCall = RuntimeCall;
type Currency = Balances;
type Fungible = Balances;
type RuntimeHoldReason = HoldReason;
type FeeDestination = ();
type WeightInfo = ();
type MaxBlockTransactions = ConstU32<{ DEFAULT_MAX_BLOCK_TRANSACTIONS }>;
Expand Down
3 changes: 2 additions & 1 deletion substrate/frame/transaction-storage/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ use super::{Pallet as TransactionStorage, *};
use crate::mock::*;
use frame_support::{assert_noop, assert_ok};
use frame_system::RawOrigin;
use sp_runtime::{DispatchError, TokenError::FundsUnavailable};
use sp_transaction_storage_proof::registration::build_proof;

const MAX_DATA_SIZE: u32 = DEFAULT_MAX_TRANSACTION_SIZE;
Expand Down Expand Up @@ -71,7 +72,7 @@ fn burns_fee() {
RawOrigin::Signed(5).into(),
vec![0u8; 2000 as usize]
),
Error::<Test>::InsufficientFunds,
DispatchError::Token(FundsUnavailable),
);
assert_ok!(TransactionStorage::<Test>::store(
RawOrigin::Signed(caller).into(),
Expand Down