Skip to content

Commit

Permalink
Update xvm precompiles mock & tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
shaunxw committed Jul 25, 2023
1 parent 2a81a2d commit e576f74
Show file tree
Hide file tree
Showing 5 changed files with 87 additions and 20 deletions.
2 changes: 2 additions & 0 deletions Cargo.lock

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

7 changes: 5 additions & 2 deletions precompiles/xvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,10 @@ precompile-utils = { workspace = true, features = ["testing"] }
pallet-balances = { workspace = true }
pallet-contracts = { workspace = true }
pallet-timestamp = { workspace = true }
sp-runtime = { workspace = true }

pallet-ethereum = { workspace = true }
pallet-ethereum-checked = { workspace = true }
pallet-insecure-randomness-collective-flip = { workspace = true }
sp-runtime = { workspace = true }

[features]
default = ["std"]
Expand All @@ -59,4 +60,6 @@ std = [
"sp-runtime/std",
"pallet-xvm/std",
"astar-primitives/std",
"pallet-balances/std",
"pallet-ethereum/std",
]
13 changes: 5 additions & 8 deletions precompiles/xvm/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ mod tests;
#[precompile_utils::generate_function_selector]
#[derive(Debug, PartialEq)]
pub enum Action {
XvmCall = "xvm_call(bytes,bytes,bytes)",
XvmCall = "xvm_call(uint8,bytes,bytes)",
}

/// A precompile that expose XVM related functions.
Expand Down Expand Up @@ -73,7 +73,7 @@ where
{
fn xvm_call(handle: &mut impl PrecompileHandle) -> EvmResult<PrecompileOutput> {
let mut input = handle.read_input()?;
input.expect_arguments(4)?;
input.expect_arguments(3)?;

let vm_id = {
let id = input.read::<u8>()?;
Expand All @@ -91,7 +91,7 @@ where
let call_input = input.read::<Bytes>()?.0;

let from = R::AddressMapping::into_account_id(handle.context().caller);
match &pallet_xvm::Pallet::<R>::call(xvm_context, vm_id, from, call_to, call_input) {
match pallet_xvm::Pallet::<R>::call(xvm_context, vm_id, from, call_to, call_input) {
Ok(success) => {
log::trace!(
target: "xvm-precompile::xvm_call",
Expand All @@ -101,7 +101,7 @@ where
Ok(succeed(
EvmDataWriter::new()
.write(true)
.write(Bytes(success.output.to_vec())) // TODO redundant clone
.write(Bytes(success.output))
.build(),
))
}
Expand All @@ -112,13 +112,10 @@ where
"failure: {:?}", failure
);

let mut error_buffer = Vec::new();
failure.error.encode_to(&mut error_buffer);

Ok(succeed(
EvmDataWriter::new()
.write(false)
.write(Bytes(error_buffer))
.write(Bytes(failure.error.encode()))
.build(),
))
}
Expand Down
75 changes: 71 additions & 4 deletions precompiles/xvm/src/mock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@
use super::*;

use fp_evm::IsPrecompileResult;
use frame_support::{construct_runtime, parameter_types, traits::Everything, weights::Weight};
use frame_support::{
construct_runtime, parameter_types,
traits::{ConstBool, ConstU32, Everything, Nothing},
weights::Weight,
};
use parity_scale_codec::{Decode, Encode, MaxEncodedLen};
use scale_info::TypeInfo;
use serde::{Deserialize, Serialize};
Expand Down Expand Up @@ -223,10 +227,69 @@ impl pallet_evm::Config for Runtime {
type WeightInfo = ();
}

impl pallet_xvm::Config for Runtime {
impl pallet_ethereum::Config for Runtime {
type RuntimeEvent = RuntimeEvent;
type StateRoot = pallet_ethereum::IntermediateStateRoot<Self>;
type PostLogContent = ();
type ExtraDataLength = ConstU32<30>;
}

impl pallet_insecure_randomness_collective_flip::Config for Runtime {}

parameter_types! {
pub const DepositPerItem: Balance = 1_000;
pub const DepositPerByte: Balance = 1_000;
pub DeletionWeightLimit: Weight = Weight::from_parts(u64::MAX, u64::MAX);
pub Schedule: pallet_contracts::Schedule<Runtime> = Default::default();
}

impl pallet_contracts::Config for Runtime {
type Time = Timestamp;
type Randomness = RandomnessCollectiveFlip;
type Currency = Balances;
type RuntimeEvent = RuntimeEvent;
type SyncVM = ();
type AsyncVM = ();
type RuntimeCall = RuntimeCall;
type CallFilter = Nothing;
type DepositPerItem = DepositPerItem;
type DepositPerByte = DepositPerByte;
type CallStack = [pallet_contracts::Frame<Self>; 5];
type WeightPrice = ();
type WeightInfo = pallet_contracts::weights::SubstrateWeight<Self>;
type ChainExtension = ();
type DeletionQueueDepth = ConstU32<128>;
type DeletionWeightLimit = DeletionWeightLimit;
type Schedule = Schedule;
type AddressGenerator = pallet_contracts::DefaultAddressGenerator;
type MaxCodeLen = ConstU32<{ 123 * 1024 }>;
type MaxStorageKeyLen = ConstU32<128>;
type UnsafeUnstableInterface = ConstBool<true>;
type MaxDebugBufferLen = ConstU32<{ 2 * 1024 * 1024 }>;
}

pub struct HashedAccountMapping;
impl astar_primitives::ethereum_checked::AccountMapping<AccountId> for HashedAccountMapping {
fn into_h160(account_id: AccountId) -> H160 {
let data = (b"evm:", account_id);
return H160::from_slice(&data.using_encoded(sp_io::hashing::blake2_256)[0..20]);
}
}

parameter_types! {
pub XvmTxWeightLimit: Weight = Weight::from_parts(u64::MAX, u64::MAX);
}

impl pallet_ethereum_checked::Config for Runtime {
type ReservedXcmpWeight = XvmTxWeightLimit;
type XvmTxWeightLimit = XvmTxWeightLimit;
type InvalidEvmTransactionError = pallet_ethereum::InvalidTransactionWrapper;
type ValidatedTransaction = pallet_ethereum::ValidatedTransaction<Self>;
type AccountMapping = HashedAccountMapping;
type XcmTransactOrigin = pallet_ethereum_checked::EnsureXcmEthereumTx<AccountId>;
type WeightInfo = ();
}

impl pallet_xvm::Config for Runtime {
type EthereumTransact = EthereumChecked;
}

// Configure a mock runtime to test the pallet.
Expand All @@ -240,6 +303,10 @@ construct_runtime!(
Balances: pallet_balances,
Evm: pallet_evm,
Timestamp: pallet_timestamp,
RandomnessCollectiveFlip: pallet_insecure_randomness_collective_flip,
Contracts: pallet_contracts,
Ethereum: pallet_ethereum,
EthereumChecked: pallet_ethereum_checked,
Xvm: pallet_xvm,
}
);
Expand Down
10 changes: 4 additions & 6 deletions precompiles/xvm/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
use crate::mock::*;
use crate::*;

use astar_primitives::xvm::CallError;
use parity_scale_codec::Encode;
use precompile_utils::testing::*;
use precompile_utils::EvmDataWriter;
Expand Down Expand Up @@ -49,25 +50,22 @@ fn wrong_argument_reverts() {
.write(0u8)
.write(Bytes(b"".to_vec()))
.write(Bytes(b"".to_vec()))
.write(Bytes(b"".to_vec()))
.build(),
)
.expect_no_logs()
.execute_reverts(|output| output == b"can not decode XVM context");
.execute_reverts(|output| output == b"invalid vm id");
})
}

#[test]
fn correct_arguments_works() {
let context: Context = Default::default();
ExtBuilder::default().build().execute_with(|| {
precompiles()
.prepare_test(
TestAccount::Alice,
PRECOMPILE_ADDRESS,
EvmDataWriter::new_with_selector(Action::XvmCall)
.write(Bytes(context.encode()))
.write(Bytes(b"".to_vec()))
.write(0x1Fu8)
.write(Bytes(b"".to_vec()))
.write(Bytes(b"".to_vec()))
.build(),
Expand All @@ -76,7 +74,7 @@ fn correct_arguments_works() {
.execute_returns(
EvmDataWriter::new()
.write(false) // the XVM call should succeed but the internal should fail
.write(vec![0u8])
.write(Bytes(CallError::InvalidTarget.encode()))
.build(),
);
})
Expand Down

0 comments on commit e576f74

Please sign in to comment.