diff --git a/evm-template/Cargo.lock b/evm-template/Cargo.lock index 9ae4468..cd35cb2 100644 --- a/evm-template/Cargo.lock +++ b/evm-template/Cargo.lock @@ -3029,6 +3029,7 @@ dependencies = [ "cumulus-primitives-core", "cumulus-primitives-storage-weight-reclaim", "cumulus-primitives-utility", + "ethereum", "fp-account", "fp-evm", "fp-rpc", diff --git a/evm-template/Cargo.toml b/evm-template/Cargo.toml index ce56e0a..c1da811 100644 --- a/evm-template/Cargo.toml +++ b/evm-template/Cargo.toml @@ -184,6 +184,8 @@ xcm-primitives = { git = "https://github.com/OpenZeppelin/moonbeam.git", branch substrate-runtimes-fuzzers = { git = "https://github.com/srlabs/substrate-runtime-fuzzer.git", default-features = false, tag = "polkadot-v1.12.0" } ziggy = { version = "0.8", default-features = false } +ethereum = { version = "0.15.0" } + [workspace.lints.clippy] large_enum_variant = "allow" too_many_arguments = "allow" diff --git a/evm-template/runtime/Cargo.toml b/evm-template/runtime/Cargo.toml index bba1b6d..936c2a9 100644 --- a/evm-template/runtime/Cargo.toml +++ b/evm-template/runtime/Cargo.toml @@ -112,6 +112,7 @@ xcm-primitives = { workspace = true } [dev-dependencies] +ethereum = { workspace = true } polkadot-runtime-parachains = { workspace = true } sp-io = { workspace = true } sp-tracing = { workspace = true } diff --git a/evm-template/runtime/src/configs/asset_config.rs b/evm-template/runtime/src/configs/asset_config.rs index f8c2ae0..e345cb5 100644 --- a/evm-template/runtime/src/configs/asset_config.rs +++ b/evm-template/runtime/src/configs/asset_config.rs @@ -171,3 +171,167 @@ impl AccountIdAssetIdConversion for Runtime { AccountId::from(data) } } + +#[cfg(test)] +mod tests { + mod asset_registrar { + use pallet_asset_manager::AssetRegistrar; + use sp_io::TestExternalities; + + use crate::{ + configs::{AssetRegistrar as Registrar, AssetRegistrarMetadata}, + types::AssetId, + AssetManager, Assets, Runtime, RuntimeOrigin, + }; + + #[test] + fn test_destroy_asset_dispatch_info_weight() { + let asset_id: AssetId = 1; + let _ = >::destroy_asset_dispatch_info_weight( + asset_id, + ); + } + + #[test] + fn test_destroy_foreign_asset() { + TestExternalities::default().execute_with(|| { + let asset_id: AssetId = 1; + let _ = Assets::force_create( + RuntimeOrigin::root(), + asset_id.into(), + AssetManager::account_id(), + true, + 1, + ); + let res = >::destroy_foreign_asset(asset_id); + assert!(res.is_ok()); + }); + } + + #[test] + fn test_create_foreign_asset() { + TestExternalities::default().execute_with(|| { + let asset_id = 1; + let res = >::create_foreign_asset( + asset_id, + 1, + AssetRegistrarMetadata { + name: vec![0, 1, 2, 3], + symbol: vec![4, 5, 6, 7], + decimals: 6, + is_frozen: false, + }, + false, + ); + assert!(res.is_ok()); + }); + } + } + + mod account_asset_id_conversion { + use core::str::FromStr; + + use fp_account::AccountId20; + + use crate::{ + configs::{ + asset_config::FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, AccountIdAssetIdConversion, + }, + types::AssetId, + AccountId, Runtime, + }; + + #[test] + fn test_account_to_asset_id_success() { + let expected_asset_id: AssetId = 1; + let mut data = [0u8; 32]; + data[0..4].copy_from_slice(FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX); + data[4..20].copy_from_slice(&expected_asset_id.to_be_bytes()); + let account_id = AccountId::from(data); + let (prefix, asset_id) = Runtime::account_to_asset_id(account_id) + .expect("Account to asset id conversion failed"); + assert_eq!(prefix, FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX); + assert_eq!(asset_id, expected_asset_id); + } + + #[test] + fn test_account_to_asset_id_error() { + let expected_asset_id: AssetId = 1; + let mut data = [0u8; 32]; + data[0..3].copy_from_slice(&FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX[0..3]); + data[3..4].copy_from_slice(&[0]); + data[4..20].copy_from_slice(&expected_asset_id.to_be_bytes()); + let account_id = AccountId::from(data); + let res = Runtime::account_to_asset_id(account_id); + assert_eq!(res, None); + } + + #[test] + fn test_asset_id_to_account() { + let expected = + AccountId20::from_str("0xFFFFFFFF00000000000000000000000000000001").unwrap(); + let asset_id = 1; + let result = + Runtime::asset_id_to_account(FOREIGN_ASSET_PRECOMPILE_ADDRESS_PREFIX, asset_id); + assert_eq!(result, expected); + } + } + + mod asset_type { + use crate::{configs::AssetType, types::AssetId}; + + #[test] + fn test_asset_type_default() { + let default_asset_type = AssetType::default(); + assert_eq!( + default_asset_type, + AssetType::Xcm(xcm::v3::Location { + parents: 0, + interior: xcm::v3::Junctions::Here + }) + ); + } + + #[test] + fn test_asset_type_from_location_v3() { + let location = xcm::v3::Location { + parents: 0, + interior: xcm::v3::Junctions::X1(xcm::v3::Junction::OnlyChild), + }; + let asset_type = AssetType::from(location); + + assert_eq!(asset_type, AssetType::Xcm(location)); + } + + #[test] + fn test_asset_type_try_from_location_v4() { + let location = + xcm::latest::Location { parents: 0, interior: xcm::latest::Junctions::Here }; + let old_location: xcm::v3::Location = + xcm::v3::Location { parents: 0, interior: xcm::v3::Junctions::Here }; + let asset_type = AssetType::try_from(location) + .expect("AssetType conversion from location v4 failed"); + + assert_eq!(asset_type, AssetType::Xcm(old_location)); + } + + #[test] + fn test_asset_type_into_location() { + let location = xcm::v3::Location { parents: 0, interior: xcm::v3::Junctions::Here }; + let asset_type = AssetType::Xcm(location); + let converted: Option = asset_type.into(); + assert_eq!(converted, Some(location)); + } + + #[test] + fn test_asset_type_into_asset_id() { + let location = xcm::v3::Location { parents: 0, interior: xcm::v3::Junctions::Here }; + let expected_asset_id: u128 = 114990615950639921045101060455076456094; + let asset_type = AssetType::Xcm(location); + + let asset_id = AssetId::from(asset_type); + + assert_eq!(asset_id, expected_asset_id); + } + } +} diff --git a/evm-template/runtime/src/configs/governance/origins.rs b/evm-template/runtime/src/configs/governance/origins.rs index 03b878c..fa6c1bb 100644 --- a/evm-template/runtime/src/configs/governance/origins.rs +++ b/evm-template/runtime/src/configs/governance/origins.rs @@ -113,3 +113,172 @@ pub mod pallet_custom_origins { } } } + +#[cfg(test)] +mod tests { + use frame_support::traits::EnsureOrigin; + + use crate::{ + configs::{governance::Spender, pallet_custom_origins::Origin}, + constants::currency::{CENTS, GRAND}, + Balance, + }; + + #[derive(Debug, PartialEq)] + enum TestOrigin { + SmallTipper, + SmallSpender, + Treasurer, + BigTipper, + MediumSpender, + BigSpender, + WhitelistedCaller, + ReferendumCanceller, + ReferendumKiller, + } + + impl From for Result { + fn from(value: TestOrigin) -> Self { + match value { + TestOrigin::SmallTipper => Ok(Origin::SmallTipper), + TestOrigin::SmallSpender => Ok(Origin::SmallSpender), + TestOrigin::Treasurer => Ok(Origin::Treasurer), + TestOrigin::ReferendumCanceller => Ok(Origin::ReferendumCanceller), + TestOrigin::ReferendumKiller => Ok(Origin::ReferendumKiller), + TestOrigin::BigTipper => Ok(Origin::BigTipper), + TestOrigin::MediumSpender => Ok(Origin::MediumSpender), + TestOrigin::BigSpender => Ok(Origin::BigSpender), + TestOrigin::WhitelistedCaller => Ok(Origin::WhitelistedCaller), + } + } + } + + impl From for TestOrigin { + fn from(value: Origin) -> Self { + match value { + Origin::SmallTipper => TestOrigin::SmallTipper, + Origin::SmallSpender => TestOrigin::SmallSpender, + Origin::Treasurer => TestOrigin::Treasurer, + Origin::ReferendumCanceller => TestOrigin::ReferendumCanceller, + Origin::ReferendumKiller => TestOrigin::ReferendumKiller, + Origin::BigTipper => TestOrigin::BigTipper, + Origin::MediumSpender => TestOrigin::MediumSpender, + Origin::BigSpender => TestOrigin::BigSpender, + Origin::WhitelistedCaller => TestOrigin::WhitelistedCaller, + } + } + } + mod spender { + use super::*; + + #[test] + fn test_small_tipper() { + let a: Balance = + Spender::try_origin(TestOrigin::SmallTipper).expect("SmallTipper misconfigured"); + assert_eq!(a, 250 * 3 * CENTS); + } + + #[test] + fn test_small_spender() { + let a: Balance = + Spender::try_origin(TestOrigin::SmallSpender).expect("SmallSpender misconfigured"); + assert_eq!(a, 10 * GRAND); + } + + #[test] + fn test_big_tipper() { + let a: Balance = + Spender::try_origin(TestOrigin::BigTipper).expect("BigTipper misconfigured"); + assert_eq!(a, GRAND); + } + + #[test] + fn test_medium_spender() { + let a: Balance = Spender::try_origin(TestOrigin::MediumSpender) + .expect("MediumSpender misconfigured"); + assert_eq!(a, 100 * GRAND); + } + + #[test] + fn test_big_spender() { + let a: Balance = + Spender::try_origin(TestOrigin::BigSpender).expect("BigSpender misconfigured"); + assert_eq!(a, 1_000 * GRAND); + } + + #[test] + fn test_treasurer() { + let a: Balance = + Spender::try_origin(TestOrigin::Treasurer).expect("Treasurer misconfigured"); + assert_eq!(a, 10_000 * GRAND); + } + + #[test] + fn test_referendum_killer() { + let a: TestOrigin = Spender::try_origin(TestOrigin::ReferendumKiller) + .expect_err("ReferendumKiller misconfigured"); + assert_eq!(a, TestOrigin::ReferendumKiller); + } + + #[test] + fn test_referendum_canceller() { + let a: TestOrigin = Spender::try_origin(TestOrigin::ReferendumCanceller) + .expect_err("ReferendumCanceller misconfigured"); + assert_eq!(a, TestOrigin::ReferendumCanceller); + } + + #[test] + fn test_whitelisted_caller() { + let a: TestOrigin = Spender::try_origin(TestOrigin::WhitelistedCaller) + .expect_err("WhitelistedCaller misconfigured"); + assert_eq!(a, TestOrigin::WhitelistedCaller); + } + + #[test] + #[cfg(feature = "runtime-benchmarks")] + fn test_try_successful_origin() { + let a: TestOrigin = Spender::try_successful_origin().expect("incorrect setup"); + assert_eq!(a, TestOrigin::Treasurer); + } + } + + mod treasurer { + use super::*; + use crate::configs::pallet_custom_origins::Treasurer; + + #[test] + pub fn test_treasurer_try_origin() { + let () = Treasurer::try_origin(TestOrigin::Treasurer).expect("incorrect configuration"); + let a = Treasurer::try_origin(TestOrigin::MediumSpender).expect_err("should be err"); + assert_eq!(a, TestOrigin::MediumSpender) + } + + #[test] + #[cfg(feature = "runtime-benchmarks")] + fn test_treasurer_try_successful_origin() { + let a: Result = Treasurer::try_successful_origin(); + assert_eq!(a, Ok(TestOrigin::Treasurer)); + } + } + + mod referendum_canceller { + use super::*; + use crate::configs::pallet_custom_origins::ReferendumCanceller; + + #[test] + pub fn test_referendum_canceller_try_origin() { + let () = ReferendumCanceller::try_origin(TestOrigin::ReferendumCanceller) + .expect("incorrect configuration"); + let a = ReferendumCanceller::try_origin(TestOrigin::MediumSpender) + .expect_err("should be err"); + assert_eq!(a, TestOrigin::MediumSpender) + } + + #[test] + #[cfg(feature = "runtime-benchmarks")] + fn test_treasurer_try_successful_origin() { + let a: Result = ReferendumCanceller::try_successful_origin(); + assert_eq!(a, Ok(TestOrigin::ReferendumCanceller)); + } + } +} diff --git a/evm-template/runtime/src/configs/governance/tracks.rs b/evm-template/runtime/src/configs/governance/tracks.rs index 3ec4b6e..57b0e9d 100644 --- a/evm-template/runtime/src/configs/governance/tracks.rs +++ b/evm-template/runtime/src/configs/governance/tracks.rs @@ -212,3 +212,138 @@ impl pallet_referenda::TracksInfo for TracksInfo { } } pallet_referenda::impl_tracksinfo_get!(TracksInfo, Balance, BlockNumber); + +#[cfg(test)] +mod tests { + use super::origins; + use crate::{Balance, BlockNumber, OriginCaller}; + + #[test] + fn test_track_system_origin() { + let track = + >::track_for(&OriginCaller::system(frame_system::RawOrigin::Root)) + .expect("incorrect config"); + assert_eq!(track, 0); + } + + #[test] + fn test_track_system_origin_error() { + let () = >::track_for(&OriginCaller::system(frame_system::RawOrigin::None)) + .expect_err("incorrect config"); + } + + #[test] + fn test_track_custom_origin_whitelisted_caller() { + let track = + >::track_for(&OriginCaller::Origins(origins::Origin::WhitelistedCaller)) + .expect("incorrect config"); + assert_eq!(track, 1); + } + + #[test] + fn test_track_custom_origin_treasurer() { + let track = + >::track_for(&OriginCaller::Origins(origins::Origin::Treasurer)) + .expect("incorrect config"); + assert_eq!(track, 11); + } + + #[test] + fn test_track_custom_origin_referendum_canceller() { + let track = + >::track_for(&OriginCaller::Origins(origins::Origin::ReferendumCanceller)) + .expect("incorrect config"); + assert_eq!(track, 20); + } + + #[test] + fn test_track_custom_origin_referendum_killer() { + let track = + >::track_for(&OriginCaller::Origins(origins::Origin::ReferendumKiller)) + .expect("incorrect config"); + assert_eq!(track, 21); + } + + #[test] + fn test_track_custom_origin_small_tipper() { + let track = + >::track_for(&OriginCaller::Origins(origins::Origin::SmallTipper)) + .expect("incorrect config"); + assert_eq!(track, 30); + } + + #[test] + fn test_track_custom_origin_big_tipper() { + let track = + >::track_for(&OriginCaller::Origins(origins::Origin::BigTipper)) + .expect("incorrect config"); + assert_eq!(track, 31); + } + + #[test] + fn test_track_custom_origin_small_spender() { + let track = + >::track_for(&OriginCaller::Origins(origins::Origin::SmallSpender)) + .expect("incorrect config"); + assert_eq!(track, 32); + } + + #[test] + fn test_track_custom_origin_medium_spender() { + let track = + >::track_for(&OriginCaller::Origins(origins::Origin::MediumSpender)) + .expect("incorrect config"); + assert_eq!(track, 33); + } + + #[test] + fn test_track_custom_origin_big_spender() { + let track = + >::track_for(&OriginCaller::Origins(origins::Origin::BigSpender)) + .expect("incorrect config"); + assert_eq!(track, 34); + } + + #[test] + fn test_track_error() { + let () = + >::track_for(&OriginCaller::CumulusXcm(cumulus_pallet_xcm::Origin::Relay)) + .expect_err("incorrect config"); + } +} diff --git a/evm-template/runtime/src/configs/mod.rs b/evm-template/runtime/src/configs/mod.rs index 07d8b39..7527df5 100644 --- a/evm-template/runtime/src/configs/mod.rs +++ b/evm-template/runtime/src/configs/mod.rs @@ -224,3 +224,58 @@ impl fp_rpc::ConvertTransaction for TransactionConve .expect("Encoded extrinsic is always valid") } } + +#[cfg(test)] +mod tests { + mod transaction_converter { + use core::str::FromStr; + + use ethereum::{LegacyTransaction, TransactionAction, TransactionSignature}; + use fp_rpc::ConvertTransaction; + use sp_core::{H160, H256, U256}; + + use crate::{configs::TransactionConverter, RuntimeCall, UncheckedExtrinsic}; + + fn get_transaction() -> pallet_ethereum::Transaction { + let mut input = vec![]; + let data = "095ea7b30000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d0000000000000000000000000000000000000000000001b1ae4d6e2ef5000000".as_bytes(); + input.extend_from_slice(data); + pallet_ethereum::Transaction::Legacy(LegacyTransaction { + nonce: U256::from_dec_str("842").unwrap(), + gas_price: U256::from_dec_str("35540887252").unwrap(), + gas_limit: U256::from_dec_str("500000").unwrap(), + action: TransactionAction::Call( + H160::from_str("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48").unwrap(), + ), + value: U256::from_dec_str("0").unwrap(), + input, + signature: TransactionSignature::new( + 27, + H256::from_str( + "dd6a5b9e4f357728f7718589d802ec2317c73c2ee3c72deb51f07766f1294859", + ) + .unwrap(), + H256::from_str( + "32d1883c43f8ed779219374be9e94174aa42fbf5ab63093f3fadd9e2aae0d1d1", + ) + .unwrap(), + ) + .unwrap(), + }) + } + + #[test] + fn test_convert_transaction() { + let converter = TransactionConverter; + let extrinsic: UncheckedExtrinsic = converter.convert_transaction(get_transaction()); + assert!(matches!(extrinsic.0.function, RuntimeCall::Ethereum(_))); + } + + #[test] + fn test_convert_transaction_to_opaque() { + let converter = TransactionConverter; + let _: crate::opaque::UncheckedExtrinsic = + converter.convert_transaction(get_transaction()); + } + } +} diff --git a/evm-template/runtime/src/lib.rs b/evm-template/runtime/src/lib.rs index 56e8bb8..86e43e7 100644 --- a/evm-template/runtime/src/lib.rs +++ b/evm-template/runtime/src/lib.rs @@ -273,3 +273,237 @@ mod apis { #[cfg(feature = "runtime-benchmarks")] mod benchmark; + +#[cfg(test)] +mod test { + use frame_support::weights::WeightToFeePolynomial; + + use crate::{ + constants::{POLY_DEGREE, VERSION}, + native_version, WeightToFee, + }; + + #[test] + fn test_native_version() { + let version = native_version(); + assert_eq!(version.runtime_version, VERSION); + } + + #[test] + fn test_weight_to_fee() { + let mut fee = WeightToFee::polynomial(); + let coef = fee.pop().expect("no coef"); + assert!(!coef.negative); + assert_eq!(coef.degree, POLY_DEGREE); + } + + mod self_contained_call { + mod is_self_contained { + use core::str::FromStr; + + use ethereum::{LegacyTransaction, TransactionSignature}; + use fp_account::AccountId20; + use fp_self_contained::SelfContainedCall; + use frame_support::dispatch::GetDispatchInfo; + use pallet_ethereum::TransactionAction; + use sp_core::{H160, H256, U256}; + + use crate::{Runtime, RuntimeCall, RuntimeOrigin}; + + fn get_transaction() -> pallet_ethereum::Transaction { + let mut input = vec![]; + let data = "095ea7b30000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d0000000000000000000000000000000000000000000001b1ae4d6e2ef5000000".as_bytes(); + input.extend_from_slice(data); + pallet_ethereum::Transaction::Legacy(LegacyTransaction { + nonce: U256::from_dec_str("842").unwrap(), + gas_price: U256::from_dec_str("35540887252").unwrap(), + gas_limit: U256::from_dec_str("500000").unwrap(), + action: TransactionAction::Call( + H160::from_str("0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48").unwrap(), + ), + value: U256::from_dec_str("0").unwrap(), + input, + signature: TransactionSignature::new( + 27, + H256::from_str( + "dd6a5b9e4f357728f7718589d802ec2317c73c2ee3c72deb51f07766f1294859", + ) + .unwrap(), + H256::from_str( + "32d1883c43f8ed779219374be9e94174aa42fbf5ab63093f3fadd9e2aae0d1d1", + ) + .unwrap(), + ) + .unwrap(), + }) + } + + #[test] + fn test_is_self_contained_ethereum() { + let call = RuntimeCall::Ethereum(pallet_ethereum::Call::transact { + transaction: get_transaction(), + }); + assert!(call.is_self_contained()) + } + + #[test] + fn test_is_not_self_contained() { + let call = RuntimeCall::Balances(pallet_balances::Call::burn { + value: 1, + keep_alive: true, + }); + assert!(!call.is_self_contained()) + } + + #[test] + fn test_check_self_contained() { + let call = RuntimeCall::Ethereum(pallet_ethereum::Call::transact { + transaction: get_transaction(), + }); + assert!(call.check_self_contained().is_some()); + assert!(call.check_self_contained().unwrap().is_ok()); + } + + #[test] + fn test_check_not_self_contained() { + let call = RuntimeCall::Balances(pallet_balances::Call::burn { + value: 1, + keep_alive: true, + }); + + assert!(call.check_self_contained().is_none()); + } + + #[test] + fn test_validate_self_contained() { + let call = RuntimeCall::Ethereum(pallet_ethereum::Call::transact { + transaction: get_transaction(), + }); + let info = call.get_dispatch_info(); + + sp_io::TestExternalities::default().execute_with(|| { + let addr = + H160::from_str("0x78DFFE34196A5987fb73fb9bbfd55a2A33e467Fb").unwrap(); + let _ = pallet_balances::Pallet::::force_set_balance( + RuntimeOrigin::root(), + AccountId20(addr.0), + 90000000000000000, + ); + let i = call + .validate_self_contained(&addr, &info, 0) + .expect("wrong implementation") + .expect("wrong transaction"); + + assert_eq!(i.priority, 34540887252); + }); + } + + #[test] + fn test_validate_not_self_contained() { + let call = RuntimeCall::Balances(pallet_balances::Call::burn { + value: 1, + keep_alive: true, + }); + let info = call.get_dispatch_info(); + + sp_io::TestExternalities::default().execute_with(|| { + let i = call.validate_self_contained( + &H160::from_str("0x78DFFE34196A5987fb73fb9bbfd55a2A33e467Fb").unwrap(), + &info, + 0, + ); + + assert!(i.is_none()); + }); + } + + #[test] + fn test_pre_dispatch_self_contained() { + let call = RuntimeCall::Ethereum(pallet_ethereum::Call::transact { + transaction: get_transaction(), + }); + let info = call.get_dispatch_info(); + + sp_io::TestExternalities::default().execute_with(|| { + let addr = + H160::from_str("0x78DFFE34196A5987fb73fb9bbfd55a2A33e467Fb").unwrap(); + let who = AccountId20(addr.0); + let _ = pallet_balances::Pallet::::force_set_balance( + RuntimeOrigin::root(), + who, + 90000000000000000, + ); + // I do not know any other way to increase nonce + for _ in 0..842 { + frame_system::Pallet::::inc_account_nonce(who); + } + let () = call + .pre_dispatch_self_contained(&addr, &info, 0) + .expect("wrong implementation") + .expect("wrong transaction"); + }); + } + + #[test] + fn test_pre_dispatch_not_self_contained() { + let call = RuntimeCall::Balances(pallet_balances::Call::burn { + value: 1, + keep_alive: true, + }); + let info = call.get_dispatch_info(); + + sp_io::TestExternalities::default().execute_with(|| { + let i = call.pre_dispatch_self_contained( + &H160::from_str("0x78DFFE34196A5987fb73fb9bbfd55a2A33e467Fb").unwrap(), + &info, + 0, + ); + + assert!(i.is_none()); + }); + } + + #[test] + fn test_apply_self_contained() { + let call = RuntimeCall::Ethereum(pallet_ethereum::Call::transact { + transaction: get_transaction(), + }); + + sp_io::TestExternalities::default().execute_with(|| { + let addr = + H160::from_str("0x78DFFE34196A5987fb73fb9bbfd55a2A33e467Fb").unwrap(); + let who = AccountId20(addr.0); + let _ = pallet_balances::Pallet::::force_set_balance( + RuntimeOrigin::root(), + who, + 90000000000000000, + ); + // I do not know any other way to increase nonce + for _ in 0..842 { + frame_system::Pallet::::inc_account_nonce(who); + } + let _ = call + .apply_self_contained(addr) + .expect("wrong implementation") + .expect("wrong transaction"); + }); + } + + #[test] + fn test_apply_not_self_contained() { + let call = RuntimeCall::Balances(pallet_balances::Call::burn { + value: 1, + keep_alive: true, + }); + + sp_io::TestExternalities::default().execute_with(|| { + let i = call.apply_self_contained( + H160::from_str("0x78DFFE34196A5987fb73fb9bbfd55a2A33e467Fb").unwrap(), + ); + + assert!(i.is_none()); + }); + } + } + } +} diff --git a/evm-template/runtime/src/types.rs b/evm-template/runtime/src/types.rs index 113fb67..93418f0 100644 --- a/evm-template/runtime/src/types.rs +++ b/evm-template/runtime/src/types.rs @@ -193,3 +193,66 @@ parameter_types! { pub MessageQueueServiceWeight: Weight = Perbill::from_percent(35) * RuntimeBlockWeights::get().max_block; pub PrecompilesValue: OpenZeppelinPrecompiles = OpenZeppelinPrecompiles::<_>::new(); } + +#[cfg(test)] +mod test { + mod filter { + use frame_support::traits::InstanceFilter; + use sp_core::H256; + + use crate::{types::ProxyType, AssetManager, RuntimeCall}; + + #[test] + fn test_filter_any() { + let call = RuntimeCall::CollatorSelection( + pallet_collator_selection::Call::set_desired_candidates { max: 10 }, + ); + let proxy_type = ProxyType::Any; + assert!(proxy_type.filter(&call)); + } + + #[test] + fn test_filter_nontransfer() { + let proxy_type = ProxyType::NonTransfer; + let valid_call = RuntimeCall::CollatorSelection( + pallet_collator_selection::Call::set_desired_candidates { max: 10 }, + ); + assert!(proxy_type.filter(&valid_call)); + let invalid_call = + RuntimeCall::Balances(pallet_balances::Call::burn { value: 1, keep_alive: true }); + assert!(!proxy_type.filter(&invalid_call)); + } + + #[test] + fn test_filter_cancel_proxy() { + let proxy_type = ProxyType::CancelProxy; + let invalid_call = RuntimeCall::CollatorSelection( + pallet_collator_selection::Call::set_desired_candidates { max: 10 }, + ); + assert!(!proxy_type.filter(&invalid_call)); + let valid_call = RuntimeCall::Proxy(pallet_proxy::Call::reject_announcement { + delegate: AssetManager::account_id(), + call_hash: H256::zero(), + }); + assert!(proxy_type.filter(&valid_call)); + } + + #[test] + fn test_filter_collator() { + let proxy_type = ProxyType::Collator; + let valid_call = RuntimeCall::CollatorSelection( + pallet_collator_selection::Call::set_desired_candidates { max: 10 }, + ); + assert!(proxy_type.filter(&valid_call)); + let invalid_call = + RuntimeCall::Balances(pallet_balances::Call::burn { value: 1, keep_alive: true }); + assert!(!proxy_type.filter(&invalid_call)); + } + + #[test] + fn test_filter_default() { + let expected = ProxyType::Any; + assert_eq!(expected, ProxyType::default()); + } + } +} diff --git a/evm-template/runtime/tests/constants_test.rs b/evm-template/runtime/tests/constants_test.rs index dd2b668..976d57d 100644 --- a/evm-template/runtime/tests/constants_test.rs +++ b/evm-template/runtime/tests/constants_test.rs @@ -11,8 +11,12 @@ mod constant_tests { assert_eq!(DOLLARS, 100 * CENTS); + #[cfg(not(feature = "runtime-benchmarks"))] assert_eq!(EXISTENTIAL_DEPOSIT, 0); + #[cfg(feature = "runtime-benchmarks")] + assert_eq!(EXISTENTIAL_DEPOSIT, 1); + // Ensure deposit function behavior remains constant assert_eq!(deposit(2, 3), 2 * 15 * CENTS + 3 * 6 * CENTS); }