3139ffa25e
- snowbridge-pezpallet-* → pezsnowbridge-pezpallet-* (201 refs) - pallet/ directories → pezpallet/ (4 locations) - Fixed pezpallet.rs self-include recursion bug - Fixed sc-chain-spec hardcoded crate name in derive macro - Reverted .pezpallet_by_name() to .pallet_by_name() (subxt API) - Added BizinikiwiConfig type alias for zombienet tests - Deleted obsolete session state files Verified: pezsnowbridge-pezpallet-*, pezpallet-staking, pezpallet-staking-async, pezframe-benchmarking-cli all pass cargo check
191 lines
6.4 KiB
Rust
191 lines
6.4 KiB
Rust
// This file is part of Bizinikiwi.
|
|
|
|
// Copyright (C) Parity Technologies (UK) Ltd.
|
|
// SPDX-License-Identifier: Apache-2.0
|
|
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
|
|
use crate::{
|
|
address::AddressMapper,
|
|
precompiles::{BuiltinAddressMatcher, BuiltinPrecompile, Error, Ext},
|
|
vm::RuntimeCosts,
|
|
Config, H160,
|
|
};
|
|
use alloc::vec::Vec;
|
|
use alloy_core::sol_types::SolValue;
|
|
use codec::Encode;
|
|
use core::{marker::PhantomData, num::NonZero};
|
|
use pezpallet_revive_uapi::precompiles::system::ISystem;
|
|
use pezsp_core::hexdisplay::AsBytesRef;
|
|
|
|
pub struct System<T>(PhantomData<T>);
|
|
|
|
impl<T: Config> BuiltinPrecompile for System<T> {
|
|
type T = T;
|
|
type Interface = ISystem::ISystemCalls;
|
|
const MATCHER: BuiltinAddressMatcher =
|
|
BuiltinAddressMatcher::Fixed(NonZero::new(0x900).unwrap());
|
|
const HAS_CONTRACT_INFO: bool = false;
|
|
|
|
fn call(
|
|
_address: &[u8; 20],
|
|
input: &Self::Interface,
|
|
env: &mut impl Ext<T = Self::T>,
|
|
) -> Result<Vec<u8>, Error> {
|
|
use ISystem::ISystemCalls;
|
|
match input {
|
|
ISystemCalls::terminate(_) if env.is_read_only() =>
|
|
Err(crate::Error::<T>::StateChangeDenied.into()),
|
|
ISystemCalls::hashBlake256(ISystem::hashBlake256Call { input }) => {
|
|
env.gas_meter_mut().charge(RuntimeCosts::HashBlake256(input.len() as u32))?;
|
|
let output = pezsp_io::hashing::blake2_256(input.as_bytes_ref());
|
|
Ok(output.abi_encode())
|
|
},
|
|
ISystemCalls::hashBlake128(ISystem::hashBlake128Call { input }) => {
|
|
env.gas_meter_mut().charge(RuntimeCosts::HashBlake128(input.len() as u32))?;
|
|
let output = pezsp_io::hashing::blake2_128(input.as_bytes_ref());
|
|
Ok(output.abi_encode())
|
|
},
|
|
ISystemCalls::toAccountId(ISystem::toAccountIdCall { input }) => {
|
|
env.gas_meter_mut().charge(RuntimeCosts::ToAccountId)?;
|
|
let account_id = env.to_account_id(&H160::from_slice(input.as_slice()));
|
|
Ok(account_id.encode().abi_encode())
|
|
},
|
|
ISystemCalls::callerIsOrigin(ISystem::callerIsOriginCall {}) => {
|
|
env.gas_meter_mut().charge(RuntimeCosts::CallerIsOrigin)?;
|
|
let is_origin = env.caller_is_origin(true);
|
|
Ok(is_origin.abi_encode())
|
|
},
|
|
ISystemCalls::callerIsRoot(ISystem::callerIsRootCall {}) => {
|
|
env.gas_meter_mut().charge(RuntimeCosts::CallerIsRoot)?;
|
|
let is_root = env.caller_is_root(true);
|
|
Ok(is_root.abi_encode())
|
|
},
|
|
ISystemCalls::ownCodeHash(ISystem::ownCodeHashCall {}) => {
|
|
env.gas_meter_mut().charge(RuntimeCosts::OwnCodeHash)?;
|
|
let caller = env.caller();
|
|
let addr = T::AddressMapper::to_address(caller.account_id()?);
|
|
let output = env.code_hash(&addr.into()).0.abi_encode();
|
|
Ok(output)
|
|
},
|
|
ISystemCalls::minimumBalance(ISystem::minimumBalanceCall {}) => {
|
|
env.gas_meter_mut().charge(RuntimeCosts::MinimumBalance)?;
|
|
let minimum_balance = env.minimum_balance();
|
|
Ok(minimum_balance.to_big_endian().abi_encode())
|
|
},
|
|
ISystemCalls::weightLeft(ISystem::weightLeftCall {}) => {
|
|
env.gas_meter_mut().charge(RuntimeCosts::WeightLeft)?;
|
|
let ref_time = env.gas_meter().gas_left().ref_time();
|
|
let proof_size = env.gas_meter().gas_left().proof_size();
|
|
let res = (ref_time, proof_size);
|
|
Ok(res.abi_encode())
|
|
},
|
|
ISystemCalls::terminate(ISystem::terminateCall { beneficiary }) => {
|
|
// no need to adjust gas because this always deletes code
|
|
env.gas_meter_mut().charge(RuntimeCosts::Terminate { code_removed: true })?;
|
|
let h160 = H160::from_slice(beneficiary.as_slice());
|
|
env.terminate_caller(&h160).map_err(Error::try_to_revert::<T>)?;
|
|
Ok(Vec::new())
|
|
},
|
|
}
|
|
}
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
use crate::{
|
|
address::AddressMapper,
|
|
call_builder::{caller_funding, CallSetup},
|
|
pezpallet,
|
|
precompiles::{
|
|
alloy::sol_types::{sol_data::Bytes, SolType},
|
|
tests::run_test_vectors,
|
|
BuiltinPrecompile,
|
|
},
|
|
tests::{ExtBuilder, Test},
|
|
};
|
|
use codec::Decode;
|
|
use pezframe_support::traits::fungible::Mutate;
|
|
|
|
#[test]
|
|
fn test_system_precompile() {
|
|
run_test_vectors::<System<Test>>(include_str!("testdata/900-blake2_256.json"));
|
|
run_test_vectors::<System<Test>>(include_str!("testdata/900-blake2_128.json"));
|
|
run_test_vectors::<System<Test>>(include_str!("testdata/900-to_account_id.json"));
|
|
}
|
|
|
|
#[test]
|
|
fn test_system_precompile_unmapped_account() {
|
|
ExtBuilder::default().build().execute_with(|| {
|
|
// given
|
|
let mut call_setup = CallSetup::<Test>::default();
|
|
let (mut ext, _) = call_setup.ext();
|
|
let unmapped_address = H160::zero();
|
|
|
|
// when
|
|
let input = ISystem::ISystemCalls::toAccountId(ISystem::toAccountIdCall {
|
|
input: unmapped_address.0.into(),
|
|
});
|
|
let raw_data =
|
|
<System<Test>>::call(&<System<Test>>::MATCHER.base_address(), &input, &mut ext)
|
|
.unwrap();
|
|
|
|
// then
|
|
let expected_fallback_account_id =
|
|
Bytes::abi_decode(&raw_data).expect("decoding failed");
|
|
assert_eq!(
|
|
expected_fallback_account_id.0.as_ref()[20..32],
|
|
[0xEE; 12],
|
|
"no fallback suffix found where one should be"
|
|
);
|
|
})
|
|
}
|
|
|
|
#[test]
|
|
fn test_system_precompile_mapped_account() {
|
|
use crate::test_utils::EVE;
|
|
ExtBuilder::default().build().execute_with(|| {
|
|
// given
|
|
let mapped_address = {
|
|
<Test as pezpallet::Config>::Currency::set_balance(&EVE, caller_funding::<Test>());
|
|
let _ = <Test as pezpallet::Config>::AddressMapper::map(&EVE);
|
|
<Test as pezpallet::Config>::AddressMapper::to_address(&EVE)
|
|
};
|
|
|
|
let mut call_setup = CallSetup::<Test>::default();
|
|
let (mut ext, _) = call_setup.ext();
|
|
|
|
// when
|
|
let input = ISystem::ISystemCalls::toAccountId(ISystem::toAccountIdCall {
|
|
input: mapped_address.0.into(),
|
|
});
|
|
let raw_data =
|
|
<System<Test>>::call(&<System<Test>>::MATCHER.base_address(), &input, &mut ext)
|
|
.unwrap();
|
|
|
|
// then
|
|
let data = Bytes::abi_decode(&raw_data).expect("decoding failed");
|
|
assert_ne!(
|
|
data.0.as_ref()[20..32],
|
|
[0xEE; 12],
|
|
"fallback suffix found where none should be"
|
|
);
|
|
assert_eq!(
|
|
<Test as pezframe_system::Config>::AccountId::decode(&mut data.as_ref()),
|
|
Ok(EVE),
|
|
);
|
|
})
|
|
}
|
|
}
|