This repository was archived by the owner on Nov 15, 2023. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
pallet-evm: return Ok(()) when EVM execution fails (#6493)
* pallet-evm: return Ok(()) when EVM execution fails * Bump spec version * Init test module * Add fail_call_return_ok test * Fix tests and use full match pattern Co-authored-by: Gav Wood <gavin@parity.io>
- Loading branch information
Showing
2 changed files
with
213 additions
and
29 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
#![cfg(test)] | ||
|
||
use super::*; | ||
|
||
use std::{str::FromStr, collections::BTreeMap}; | ||
use frame_support::{ | ||
assert_ok, impl_outer_origin, parameter_types, impl_outer_dispatch, | ||
}; | ||
use sp_core::H256; | ||
// The testing primitives are very useful for avoiding having to work with signatures | ||
// or public keys. `u64` is used as the `AccountId` and no `Signature`s are required. | ||
use sp_runtime::{ | ||
Perbill, | ||
testing::Header, | ||
traits::{BlakeTwo256, IdentityLookup}, | ||
}; | ||
|
||
impl_outer_origin! { | ||
pub enum Origin for Test where system = frame_system {} | ||
} | ||
|
||
impl_outer_dispatch! { | ||
pub enum OuterCall for Test where origin: Origin { | ||
self::EVM, | ||
} | ||
} | ||
|
||
// For testing the pallet, we construct most of a mock runtime. This means | ||
// first constructing a configuration type (`Test`) which `impl`s each of the | ||
// configuration traits of pallets we want to use. | ||
#[derive(Clone, Eq, PartialEq)] | ||
pub struct Test; | ||
parameter_types! { | ||
pub const BlockHashCount: u64 = 250; | ||
pub const MaximumBlockWeight: Weight = 1024; | ||
pub const MaximumBlockLength: u32 = 2 * 1024; | ||
pub const AvailableBlockRatio: Perbill = Perbill::one(); | ||
} | ||
impl frame_system::Trait for Test { | ||
type BaseCallFilter = (); | ||
type Origin = Origin; | ||
type Index = u64; | ||
type BlockNumber = u64; | ||
type Hash = H256; | ||
type Call = OuterCall; | ||
type Hashing = BlakeTwo256; | ||
type AccountId = H256; | ||
type Lookup = IdentityLookup<Self::AccountId>; | ||
type Header = Header; | ||
type Event = (); | ||
type BlockHashCount = BlockHashCount; | ||
type MaximumBlockWeight = MaximumBlockWeight; | ||
type DbWeight = (); | ||
type BlockExecutionWeight = (); | ||
type ExtrinsicBaseWeight = (); | ||
type MaximumExtrinsicWeight = MaximumBlockWeight; | ||
type MaximumBlockLength = MaximumBlockLength; | ||
type AvailableBlockRatio = AvailableBlockRatio; | ||
type Version = (); | ||
type ModuleToIndex = (); | ||
type AccountData = pallet_balances::AccountData<u64>; | ||
type OnNewAccount = (); | ||
type OnKilledAccount = (); | ||
} | ||
|
||
parameter_types! { | ||
pub const ExistentialDeposit: u64 = 1; | ||
} | ||
impl pallet_balances::Trait for Test { | ||
type Balance = u64; | ||
type DustRemoval = (); | ||
type Event = (); | ||
type ExistentialDeposit = ExistentialDeposit; | ||
type AccountStore = System; | ||
} | ||
|
||
parameter_types! { | ||
pub const MinimumPeriod: u64 = 1000; | ||
} | ||
impl pallet_timestamp::Trait for Test { | ||
type Moment = u64; | ||
type OnTimestampSet = (); | ||
type MinimumPeriod = MinimumPeriod; | ||
} | ||
|
||
/// Fixed gas price of `0`. | ||
pub struct FixedGasPrice; | ||
impl FeeCalculator for FixedGasPrice { | ||
fn min_gas_price() -> U256 { | ||
// Gas price is always one token per gas. | ||
0.into() | ||
} | ||
} | ||
parameter_types! { | ||
pub const EVMModuleId: ModuleId = ModuleId(*b"py/evmpa"); | ||
} | ||
impl Trait for Test { | ||
type ChainId = SystemChainId; | ||
type ModuleId = EVMModuleId; | ||
type FeeCalculator = FixedGasPrice; | ||
type ConvertAccountId = HashTruncateConvertAccountId<BlakeTwo256>; | ||
type Currency = Balances; | ||
type Event = Event<Test>; | ||
type Precompiles = (); | ||
} | ||
|
||
type System = frame_system::Module<Test>; | ||
type Balances = pallet_balances::Module<Test>; | ||
type EVM = Module<Test>; | ||
|
||
// This function basically just builds a genesis storage key/value store according to | ||
// our desired mockup. | ||
pub fn new_test_ext() -> sp_io::TestExternalities { | ||
let mut t = frame_system::GenesisConfig::default().build_storage::<Test>().unwrap(); | ||
|
||
let mut accounts = BTreeMap::new(); | ||
accounts.insert( | ||
H160::from_str("1000000000000000000000000000000000000001").unwrap(), | ||
GenesisAccount { | ||
nonce: U256::from(1), | ||
balance: U256::from(1000000), | ||
storage: Default::default(), | ||
code: vec![ | ||
0x00, // STOP | ||
], | ||
} | ||
); | ||
accounts.insert( | ||
H160::from_str("1000000000000000000000000000000000000002").unwrap(), | ||
GenesisAccount { | ||
nonce: U256::from(1), | ||
balance: U256::from(1000000), | ||
storage: Default::default(), | ||
code: vec![ | ||
0xff, // INVALID | ||
], | ||
} | ||
); | ||
|
||
// We use default for brevity, but you can configure as desired if needed. | ||
pallet_balances::GenesisConfig::<Test>::default().assimilate_storage(&mut t).unwrap(); | ||
GenesisConfig { accounts }.assimilate_storage(&mut t).unwrap(); | ||
t.into() | ||
} | ||
|
||
#[test] | ||
fn fail_call_return_ok() { | ||
new_test_ext().execute_with(|| { | ||
assert_ok!(EVM::call( | ||
Origin::signed(H256::default()), | ||
H160::from_str("1000000000000000000000000000000000000001").unwrap(), | ||
Vec::new(), | ||
U256::default(), | ||
1000000, | ||
U256::default(), | ||
None, | ||
)); | ||
|
||
assert_ok!(EVM::call( | ||
Origin::signed(H256::default()), | ||
H160::from_str("1000000000000000000000000000000000000002").unwrap(), | ||
Vec::new(), | ||
U256::default(), | ||
1000000, | ||
U256::default(), | ||
None, | ||
)); | ||
}); | ||
} |