Skip to content

Commit

Permalink
Added tests
Browse files Browse the repository at this point in the history
  • Loading branch information
markopoloparadox committed Mar 24, 2024
1 parent 8494797 commit 58d171f
Show file tree
Hide file tree
Showing 10 changed files with 237 additions and 41 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions pallets/dactr/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ rayon = "1.5.2"

[dev-dependencies]
pallet-balances = { workspace = true, default-features = false, features = ["std"] }
pallet-timestamp = { workspace = true, default-features = false, features = ["std"] }
test-case.workspace = true

[features]
Expand Down
83 changes: 56 additions & 27 deletions pallets/dactr/src/extensions/check_batch_transactions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ where
) -> TransactionValidity {
use InvalidTransactionCustomId::*;

if iteration > MAX_ITERATIONS {
if iteration >= MAX_ITERATIONS {
return Err(InvalidTransaction::Custom(MaxRecursionExceeded as u8).into());
}
for call in calls {
Expand Down Expand Up @@ -193,22 +193,24 @@ where
}
}

/* #[cfg(test)]
#[cfg(test)]
mod tests {
use avail_core::{
asdr::AppUncheckedExtrinsic,
InvalidTransactionCustomId::{ForbiddenAppId, InvalidAppId},
data_proof::Message,
InvalidTransactionCustomId::{
MaxRecursionExceeded, UnexpectedSendMessageCall, UnexpectedSubmitDataCall,
},
};
use frame_system::pallet::Call as SysCall;
use pallet_utility::pallet::Call as UtilityCall;
use sp_core::H256;
use sp_runtime::transaction_validity::InvalidTransaction;
use test_case::test_case;

use super::*;
use crate::{
mock::{new_test_ext, RuntimeCall, Test},
pallet::Call as DACall,
};
use crate::extensions::check_batch_transactions_mock::{new_test_ext, RuntimeCall, Test};
use crate::pallet::Call as DACall;

fn remark_call() -> RuntimeCall {
RuntimeCall::System(SysCall::remark { remark: vec![] })
Expand All @@ -220,19 +222,24 @@ mod tests {
})
}

fn batch_submit_call() -> RuntimeCall {
let call = submit_data_call();
RuntimeCall::Utility(UtilityCall::batch {
calls: vec![call.clone(), call.clone(), call],
fn send_message_call() -> RuntimeCall {
let message = Message::FungibleToken {
asset_id: H256::default(),
amount: 0,
};
RuntimeCall::Vector(VectorCall::send_message {
message,
to: H256::default(),
domain: 0,
})
}

fn batch_mixed_call() -> RuntimeCall {
let call = submit_data_call();
let remark = remark_call();
RuntimeCall::Utility(UtilityCall::batch {
calls: vec![remark, call.clone(), call],
})
fn batch_call(calls: Vec<RuntimeCall>) -> RuntimeCall {
RuntimeCall::Utility(UtilityCall::batch { calls })
}

fn batch_all_call(calls: Vec<RuntimeCall>) -> RuntimeCall {
RuntimeCall::Utility(UtilityCall::batch_all { calls })
}

fn to_invalid_tx(custom_id: InvalidTransactionCustomId) -> TransactionValidity {
Expand All @@ -241,18 +248,40 @@ mod tests {
))
}

#[test_case(100, submit_data_call() => to_invalid_tx(InvalidAppId); "100 AppId is invalid" )]
#[test_case(0, remark_call() => Ok(ValidTransaction::default()); "System::remark can be called if AppId == 0" )]
#[test_case(1, remark_call() => to_invalid_tx(ForbiddenAppId); "System::remark cannot be called if AppId != 0" )]
#[test_case(1, submit_data_call() => Ok(ValidTransaction::default()); "submit_data can be called with any valid AppId" )]
#[test_case(1, batch_submit_call() => Ok(ValidTransaction::default()); "utility batch filled with submit_data can be called with any valid AppId" )]
#[test_case(1, batch_mixed_call() => to_invalid_tx(ForbiddenAppId); "utility batch filled with submit_data and remark cannot be called if AppId != 0" )]
#[test_case(0, batch_mixed_call() => Ok(ValidTransaction::default()); "utility batch filled with submit_data and remark can be called if AppId == 0" )]
fn do_validate_test(id: u32, call: RuntimeCall) -> TransactionValidity {
fn validate(call: RuntimeCall) -> TransactionValidity {
let extrinsic =
AppUncheckedExtrinsic::<u32, RuntimeCall, (), ()>::new_unsigned(call.clone());
let len = extrinsic.encoded_size();
new_test_ext().execute_with(|| CheckAppId::<Test>::from(AppId(id)).do_validate(&call, len))
new_test_ext()
.execute_with(|| CheckBatchTransactions::<Test>::new().do_validate(&call, len))
}

#[test]
fn test_batch_iterations() {
let mut call = batch_call(vec![remark_call()]);
for _ in 0..MAX_ITERATIONS {
call = batch_call(vec![call])
}

assert_eq!(
validate(call),
to_invalid_tx(MaxRecursionExceeded),
"Stacking too many Batch calls should be blocked"
);
}

#[test_case(submit_data_call() => Ok(ValidTransaction::default()); "Single Submit Data call should be allowed" )]
#[test_case(send_message_call() => Ok(ValidTransaction::default()); "Single Send Message call should be allowed" )]
#[test_case(send_message_call() => Ok(ValidTransaction::default()); "Single Non-Submit-Data and Non-Send-Message call should be allowed" )]
fn test_single_call(call: RuntimeCall) -> TransactionValidity {
validate(call)
}

#[test_case(vec![remark_call(), submit_data_call()] => to_invalid_tx(UnexpectedSubmitDataCall); "Submit Data call inside a Batch call should be blocked" )]
#[test_case(vec![remark_call(), send_message_call()] => to_invalid_tx(UnexpectedSendMessageCall); "Send Message call inside a Batch call should be blocked" )]
#[test_case(vec![remark_call()] => Ok(ValidTransaction::default()); "Non-Submit-Data and Non-Send-Message call inside a Batch call should be allowed" )]
fn test_batch_call(calls: Vec<RuntimeCall>) -> TransactionValidity {
validate(batch_call(calls.clone()))?;
validate(batch_all_call(calls))
}
}
*/
104 changes: 104 additions & 0 deletions pallets/dactr/src/extensions/check_batch_transactions_mock.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
#![cfg(test)]

use frame_support::{derive_impl, weights::IdentityFee};
use frame_system::{
header_builder::da::HeaderExtensionBuilder, mocking::MockUncheckedExtrinsic,
test_utils::TestRandomness,
};
use pallet_transaction_payment::CurrencyAdapter;
use sp_runtime::{AccountId32, BuildStorage};

use crate::{self as da_control, *};

/// An unchecked extrinsic type to be used in tests.
type Extrinsic = MockUncheckedExtrinsic<Test>;
/// An implementation of `sp_runtime::traits::Block` to be used in tests.
type Block = frame_system::mocking::MockDaBlock<Test>;
type Balance = u64;

frame_support::construct_runtime!(
pub struct Test {
Timestamp: pallet_timestamp,
System: frame_system,
Utility: pallet_utility,
Balances: pallet_balances,
TransactionPayment: pallet_transaction_payment,
DataAvailability: da_control,
Vector: pallet_vector,
}
);

#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig)]
impl frame_system::Config for Test {
type AccountData = pallet_balances::AccountData<Balance>;
type Block = Block;
type HeaderExtensionBuilder = HeaderExtensionBuilder<Test>;
type PalletInfo = PalletInfo;
type Randomness = TestRandomness<Test>;
type Extrinsic = Extrinsic;
type AccountId = AccountId32;
type Lookup = sp_runtime::traits::IdentityLookup<AccountId32>;
}

#[derive_impl(pallet_transaction_payment::config_preludes::TestDefaultConfig as pallet_transaction_payment::DefaultConfig)]
impl pallet_transaction_payment::Config for Test {
type LengthToFee = pallet_transaction_payment::TestLengthToFeeU64;
type OnChargeTransaction = CurrencyAdapter<Balances, ()>;
type WeightToFee = IdentityFee<Balance>;
}

#[derive_impl(pallet_balances::config_preludes::TestDefaultConfig as pallet_balances::DefaultConfig)]
impl pallet_balances::Config for Test {
type AccountStore = System;
}

impl pallet_utility::Config for Test {
type PalletsOrigin = OriginCaller;
type RuntimeCall = RuntimeCall;
type RuntimeEvent = RuntimeEvent;
type WeightInfo = ();
}

#[derive_impl(da_control::config_preludes::TestDefaultConfig)]
impl da_control::Config for Test {}

#[derive_impl(pallet_vector::config_preludes::TestDefaultConfig as pallet_vector::DefaultConfig)]
impl pallet_vector::Config for Test {
type TimeProvider = Timestamp;
type Currency = Balances;
}

#[derive_impl(pallet_timestamp::config_preludes::TestDefaultConfig as pallet_timestamp::DefaultConfig)]
impl pallet_timestamp::Config for Test {}

fn u8_to_account_id(value: u8) -> AccountId32 {
let mut account = [0u8; 32];
account[0] = value;

AccountId32::new(account)
}

/// Create new externalities for `System` module tests.
pub fn new_test_ext() -> sp_io::TestExternalities {
let mut storage = frame_system::GenesisConfig::<Test>::default()
.build_storage()
.unwrap();

let alice = u8_to_account_id(1);

pallet_balances::GenesisConfig::<Test> {
balances: vec![(alice.clone(), 1_000_000u64)],
}
.assimilate_storage(&mut storage)
.unwrap();

da_control::GenesisConfig::<Test> {
app_keys: vec![(b"Avail".to_vec(), (alice, 0))],
}
.assimilate_storage(&mut storage)
.unwrap();

let mut ext = sp_io::TestExternalities::new(storage);
ext.execute_with(|| System::set_block_number(1));
ext
}
1 change: 1 addition & 0 deletions pallets/dactr/src/extensions/mod.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
pub mod check_app_id;
pub mod check_batch_transactions;
pub mod check_batch_transactions_mock;

const MAX_ITERATIONS: usize = 2;
22 changes: 16 additions & 6 deletions pallets/dactr/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ pub mod pallet {
pub mod config_preludes {
use super::*;
use frame_support::derive_impl;
use frame_support::parameter_types;

/// Provides a viable default config that can be used with
/// [`derive_impl`](`frame_support::derive_impl`) to derive a testing pallet config
Expand All @@ -64,15 +65,24 @@ pub mod pallet {
#[derive_impl(frame_system::config_preludes::TestDefaultConfig as frame_system::DefaultConfig, no_aggregated_types)]
impl frame_system::DefaultConfig for TestDefaultConfig {}

parameter_types! {
pub const MinBlockRows: BlockLengthRows = BlockLengthRows(32);
pub const MaxBlockRows: BlockLengthRows = BlockLengthRows(1024);
pub const MinBlockCols: BlockLengthColumns = BlockLengthColumns(64);
pub const MaxBlockCols: BlockLengthColumns = BlockLengthColumns(256);
}
pub type MaxAppKeyLength = ConstU32<64>;
pub type MaxAppDataLength = ConstU32<524_288>; // 512 Kb

#[frame_support::register_default_impl(TestDefaultConfig)]
impl DefaultConfig for TestDefaultConfig {
type BlockLenProposalId = u32;
type MaxAppDataLength = ();
type MaxAppKeyLength = ();
type MaxBlockCols = ();
type MaxBlockRows = ();
type MinBlockCols = ();
type MinBlockRows = ();
type MaxAppDataLength = MaxAppDataLength;
type MaxAppKeyLength = MaxAppKeyLength;
type MaxBlockCols = MaxBlockCols;
type MaxBlockRows = MaxBlockRows;
type MinBlockCols = MinBlockCols;
type MinBlockRows = MinBlockRows;
type WeightInfo = ();
#[inject_runtime_type]
type RuntimeEvent = ();
Expand Down
13 changes: 8 additions & 5 deletions pallets/system/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,7 @@ pub mod pallet {
/// Default implementations of [`DefaultConfig`], which can be used to implement [`Config`].
pub mod config_preludes {
use super::{inject_runtime_type, AccountInfo, BlakeTwo256, DaHeader, DefaultConfig};
use frame_support::derive_impl;
use frame_support::{derive_impl, traits::ConstU32};

/// Provides a viable default config that can be used with
/// [`derive_impl`](`frame_support::derive_impl`) to derive a testing pallet config
Expand Down Expand Up @@ -310,9 +310,12 @@ pub mod pallet {
#[inject_runtime_type]
type RuntimeTask = ();
type BaseCallFilter = frame_support::traits::Everything;
type BlockHashCount = frame_support::traits::ConstU64<10>;
type BlockHashCount = frame_support::traits::ConstU32<10>;
type OnSetCode = ();
type Header = DaHeader<u32, BlakeTwo256>;
type MaxDiffAppIdPerBlock = ConstU32<1_024>;
type MaxTxPerAppIdPerBlock = ConstU32<8_192>;
type TxDataExtractor = ();
}

/// Default configurations of this pallet in a solo-chain environment.
Expand Down Expand Up @@ -409,6 +412,9 @@ pub mod pallet {
type OnSetCode = ();

type Header = DaHeader<u32, BlakeTwo256>;
type MaxDiffAppIdPerBlock = ConstU32<1_024>;
type MaxTxPerAppIdPerBlock = ConstU32<8_192>;
type TxDataExtractor = ();
}

/// Default configurations of this pallet in a relay-chain environment.
Expand Down Expand Up @@ -608,21 +614,18 @@ pub mod pallet {
type MaxConsumers: ConsumerLimits;

/// Filter used by `DataRootBuilder`.
#[pallet::no_default]
type TxDataExtractor: TxDataFilter<Self::AccountId, Self::RuntimeCall>;

/// Maximum different `AppId` allowed per block.
/// This is used during the calculation of padded length of the block when
/// a transaction is validated (see `CheckAppId` signed extension).
#[pallet::constant]
#[pallet::no_default]
type MaxDiffAppIdPerBlock: Get<u32>;

/// Maximum number of Tx per AppId allowed per block.
/// This is used during the calculation of padded length of the block when
/// a transaction is validated (see `CheckAppId` signed extension).
#[pallet::constant]
#[pallet::no_default]
type MaxTxPerAppIdPerBlock: Get<u32>;
}

Expand Down
10 changes: 10 additions & 0 deletions pallets/transaction-payment/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1048,3 +1048,13 @@ where
Self::compute_actual_fee(len, &info, &post_info, Zero::zero())
}
}

pub struct TestLengthToFeeU64;

impl WeightToFee for TestLengthToFeeU64 {
type Balance = u64;

fn weight_to_fee(_weight: &Weight) -> Self::Balance {
0
}
}
Loading

0 comments on commit 58d171f

Please sign in to comment.