From 38258571a219035feb5215614a5e49d2d99d6e3d Mon Sep 17 00:00:00 2001 From: wd30130 Date: Wed, 7 Aug 2024 12:00:44 +0800 Subject: [PATCH 01/12] feat(test): add fn hybridvm_evm_abi in wasm contrat --- external/contract/src/erc20wasm/lib.rs | 161 +++++++++---------------- frame/hybrid-vm/fixtures/erc20.wasm | Bin 20702 -> 19223 bytes 2 files changed, 54 insertions(+), 107 deletions(-) diff --git a/external/contract/src/erc20wasm/lib.rs b/external/contract/src/erc20wasm/lib.rs index 40bc500..de1bf4c 100644 --- a/external/contract/src/erc20wasm/lib.rs +++ b/external/contract/src/erc20wasm/lib.rs @@ -22,9 +22,7 @@ use ink_env::Environment; use ink_prelude::string::String; -use sp_core::H160; use ink_prelude::vec::Vec; -//use sp_std::vec::Vec; type AccountId = ::AccountId; #[ink::chain_extension( extension = 0 )] @@ -33,8 +31,6 @@ pub trait MyChainExtension { #[ink(function = 5, handle_status = false)] fn call_evm_extension(vm_input: Vec) -> String; - #[ink(function = 6, handle_status = false)] - fn h160_to_accountid(evm_address: H160) -> AccountId; } @@ -64,14 +60,13 @@ mod erc20 { use ink::storage::Lazy; use ink::storage::Mapping as StorageHashMap; - use ink_env::{hash, ReturnFlags}; use ink_prelude::string::String; use ink_prelude::string::ToString; use ink_prelude::vec; use ink_prelude::vec::Vec; - use precompile_utils::prelude::*; - use sp_core::U256; + //evm_fun_abi, wasm_message_name, wasm_message_selector + pub type EvmABI = (String, String, Option<[u8; 4]>); /// A simple ERC-20 contract. #[ink(storage)] @@ -155,110 +150,21 @@ mod erc20 { instance } - /// Evm ABI interface. + /// Get Evm ABI interface . #[ink(message)] - pub fn evm_abi_call(&mut self, para: Vec) -> Vec { - let who = self.env().caller(); - - let mut a: [u8; 4] = Default::default(); - a.copy_from_slice(&Self::hash_keccak_256(b"balanceOf(address)")[0..4]); - let balance_selector = u32::from_be_bytes(a); - - let mut a: [u8; 4] = Default::default(); - a.copy_from_slice(&Self::hash_keccak_256(b"transfer(address,uint256)")[0..4]); - let transfer_selector = u32::from_be_bytes(a); - - let evm_selector = if para.len() < 4 { 0 } else { - let mut a: [u8; 4] = Default::default(); - a.copy_from_slice(¶[0..4]); - u32::from_be_bytes(a) - }; - - match evm_selector { - // 1. balanceOf(address account) external view returns (uint256); - // balance_of(&self, owner: AccountId) -> Balance; - a if a == balance_selector => { - if para.len() < 5 { - self.env().emit_event(ParameterError { - caller: who, - parameter: para, - }); - ink_env::return_value::(ReturnFlags::REVERT, &13u8); - }; - let parameter = solidity::codec::decode_arguments::
(¶[4..]); - match parameter { - Ok(t) => { - let accountid = self.env().extension().h160_to_accountid(t.0); - - let return_result = self.balance_of(accountid); - solidity::codec::encode_arguments::(return_result) - } - Err(_) => { - self.env().emit_event(ParameterError { - caller: who, - parameter: para, - }); - ink_env::return_value::(ReturnFlags::REVERT, &12u8); - } - }; - } - // 2. transfer(address to, uint256 amount) external returns (bool); - // transfer(&mut self, to: AccountId, value: Balance) -> Result<()> - b if b == transfer_selector => { - if para.len() < 5 { - self.env().emit_event(ParameterError { - caller: who, - parameter: para, - }); - ink_env::return_value::(ReturnFlags::REVERT, &13u8); - }; - let parameter = solidity::codec::decode_arguments::<(Address, U256)>(¶[4..]); - match parameter { - Ok(t) => { - let accountid = self.env().extension().h160_to_accountid(t.0.0); - let balance = match Balance::try_from(t.1) { - Ok(t) => t, - Err(_) => { - self.env().emit_event(ParameterError { - caller: who, - parameter: para, - }); - ink_env::return_value::(ReturnFlags::REVERT, &1u8); - } - }; - let return_result = if self.transfer(accountid, balance).is_ok(){ - true - } else { false }; - solidity::codec::encode_arguments::(return_result) - } - Err(_) => { - self.env().emit_event(ParameterError { - caller: who, - parameter: para, - }); - ink_env::return_value::(ReturnFlags::REVERT, &2u8); - } - }; - } - // None - _ => { - self.env().emit_event(SelectorError { - caller: who, - selector: evm_selector, - }); - ink_env::return_value::(ReturnFlags::REVERT, &3u8); - } - } + pub fn hybridvm_evm_abi(&mut self) -> Vec { + let mut evm_abi: Vec = vec![]; + evm_abi.push(("total_supply()returns(uint128)".to_string(), "total_supply".to_string(), None)); + evm_abi.push(("balanceOf(address)returns(uint128)".to_string(), "balance_of".to_string(), None)); + evm_abi.push(("allowance(address,address)returns(uint128)".to_string(), "allowance".to_string(), None)); + evm_abi.push(("transfer(address,uint128)returns(bool,string)".to_string(), "transfer_abi".to_string(), None)); + evm_abi.push(("approve(address,uint128)returns(bool,string)".to_string(), "approve_abi".to_string(), None)); + evm_abi.push(("transfer_from(address,address,uint128)returns(bool,string)".to_string(), "transfer_from_abi".to_string(), None)); + evm_abi.push(("transfer_from_to(address,address,uint128)returns(bool,string)".to_string(), "transfer_from_to_abi".to_string(), None)); - vec![] + evm_abi } - pub fn hash_keccak_256(input: &[u8]) -> [u8; 32] { - let mut output = ::Type::default(); - ink_env::hash_bytes::(input, &mut output); - output - } - /// Returns the total token supply. #[ink(message)] pub fn total_supply(&self) -> Balance { @@ -294,6 +200,22 @@ mod erc20 { let from = self.env().caller(); self.transfer_from_to(from, to, value) } + + fn result_to_abidata(result: Result<()>) -> (bool, String) { + match result { + Ok(_) => (true, String::new()), + Err(e) => match e { + Error::InsufficientBalance => (false, String::from("InsufficientBalance")), + Error::InsufficientAllowance => (false, String::from("InsufficientAllowance")), + Error::OtherError(s) => (false, s), + } + } + } + + #[ink(message)] + pub fn transfer_abi(&mut self, to: AccountId, value: Balance) -> (bool, String) { + Self::result_to_abidata(self.transfer(to, value)) + } /// Allows `spender` to withdraw from the caller's account multiple times, up to /// the `value` amount. @@ -312,6 +234,11 @@ mod erc20 { }); Ok(()) } + + #[ink(message)] + pub fn approve_abi(&mut self, spender: AccountId, value: Balance) -> (bool, String) { + Self::result_to_abidata(self.approve(spender, value)) + } /// Transfers `value` tokens on the behalf of `from` to the account `to`. /// @@ -344,6 +271,16 @@ mod erc20 { self.allowances.insert((from, caller), &(allowance - value)); Ok(()) } + + #[ink(message)] + pub fn transfer_from_abi( + &mut self, + from: AccountId, + to: AccountId, + value: Balance, + ) -> (bool, String) { + Self::result_to_abidata(self.transfer_from(from, to, value)) + } /// Transfers `value` amount of tokens from the caller's account to account `to`. /// @@ -376,6 +313,16 @@ mod erc20 { Ok(()) } + #[ink(message)] + pub fn transfer_from_to_abi( + &mut self, + from: AccountId, + to: AccountId, + value: Balance, + ) -> (bool, String) { + Self::result_to_abidata(self.transfer_from_to(from, to, value)) + } + // Test call EVM contract from this contract #[ink(message)] pub fn wasmCallEvm( diff --git a/frame/hybrid-vm/fixtures/erc20.wasm b/frame/hybrid-vm/fixtures/erc20.wasm index 8ca1d8519ef22f95c17ba0f47e61d863cafed879..596b428940e807421b39e8d8cd19dac41094db91 100644 GIT binary patch literal 19223 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 J@b7pO{(l5o_GkbA literal 20702 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 H1|R)DEA^`1 From 9f2f50452052329c63555bbc5e4d8dfb92151c14 Mon Sep 17 00:00:00 2001 From: wd30130 Date: Thu, 8 Aug 2024 00:27:43 +0800 Subject: [PATCH 02/12] feat(*): add evm abi process in regist_contract --- frame/hybrid-vm-port/Cargo.toml | 3 +- frame/hybrid-vm/Cargo.toml | 18 ++++++- frame/hybrid-vm/src/lib.rs | 94 +++++++++++++++++++++++++++------ 3 files changed, 97 insertions(+), 18 deletions(-) diff --git a/frame/hybrid-vm-port/Cargo.toml b/frame/hybrid-vm-port/Cargo.toml index 7a12f5b..e290e2d 100644 --- a/frame/hybrid-vm-port/Cargo.toml +++ b/frame/hybrid-vm-port/Cargo.toml @@ -29,7 +29,7 @@ fp-rpc = { workspace = true } fp-storage = { workspace = true } pallet-evm = { workspace = true } # ink! -ink_env = { workspace = true } +ink_env = { workspace = true, features = ["no-panic-handler"] } #local pallet-hybrid-vm = { workspace = true, default-features = false } hp-system = { workspace = true, default-features = false } @@ -58,6 +58,7 @@ std = [ "rlp/std", "scale-codec/std", "scale-info/std", + "ink_env/std", # Substrate "frame-support/std", "frame-system/std", diff --git a/frame/hybrid-vm/Cargo.toml b/frame/hybrid-vm/Cargo.toml index 6a7d17f..d2adf77 100644 --- a/frame/hybrid-vm/Cargo.toml +++ b/frame/hybrid-vm/Cargo.toml @@ -36,6 +36,9 @@ pallet-contracts = { workspace = true, default-features = false} pallet-evm = { workspace = true, default-features = false} fp-evm = { workspace = true, default-features = false} +#ink +ink_env = { workspace = true, features = ["no-panic-handler"] } + # hybrid vm hp-system = { workspace = true, default-features = false } @@ -53,8 +56,6 @@ pallet-transaction-payment = { workspace = true, default-features = false} pallet-evm-precompile-simple = { workspace = true, default-features = false} -ink_env = { workspace = true } - pallet-evm-precompile-call-hybrid-vm = { workspace = true } [features] @@ -82,4 +83,17 @@ std = [ "pallet-contracts/std", "pallet-evm/std", "fp-evm/std", + "ink_env/std", +] +runtime-benchmarks = [ + "frame-support/runtime-benchmarks", + "frame-system/runtime-benchmarks", + "pallet-evm/runtime-benchmarks", + "pallet-contracts/runtime-benchmarks", ] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "pallet-evm/try-runtime", + "pallet-contracts/try-runtime", +] \ No newline at end of file diff --git a/frame/hybrid-vm/src/lib.rs b/frame/hybrid-vm/src/lib.rs index 9d53ebf..5f38e42 100644 --- a/frame/hybrid-vm/src/lib.rs +++ b/frame/hybrid-vm/src/lib.rs @@ -23,12 +23,15 @@ mod tests; mod interoperate; use self::interoperate::InterCall; -use ethereum::TransactionV2 as Transaction; -use frame_support::traits::{tokens::fungible::Inspect, Currency, Get}; -use frame_support::RuntimeDebugNoBound; +use frame_support::traits::{tokens::fungible::Inspect, ConstU32, Currency, Get}; +use frame_support::{weights::Weight, RuntimeDebugNoBound}; +use ink_env::call::{ExecutionInput, Selector}; use pallet_contracts::chain_extension::{Environment, Ext, InitState, RetVal}; +use pallet_contracts::{CollectEvents, DebugInfo, Determinism}; +use sha3::{Digest, Keccak256}; use sp_core::{H160, U256}; -use sp_runtime::{AccountId32, DispatchError}; +use sp_runtime::traits::{BlakeTwo256, Hash}; +use sp_runtime::{AccountId32, BoundedVec, DispatchError}; use sp_std::vec::Vec; //use sp_std::fmt::Debug; use hp_system::{AccountId32Mapping, AccountIdMapping, U256BalanceMapping}; @@ -41,8 +44,16 @@ pub mod pallet { use frame_support::pallet_prelude::*; use frame_system::pallet_prelude::*; + const WEIGHT_LIMIT: Weight = Weight::from_parts(1_000_000_000_000, u64::MAX); + type Result = sp_std::result::Result; + //evm_fun_abi, wasm_message_name, wasm_message_selector + pub type EvmABI = (String, String, Option<[u8; 4]>); + + //wasm_message_selector, evm_fun_abi + pub type FunABI = ([u8; 4], BoundedVec>); + #[derive(Encode, Decode, MaxEncodedLen, TypeInfo, Clone, RuntimeDebugNoBound, PartialEq)] #[scale_info(skip_type_params(T))] pub enum UnifiedAddress { @@ -78,12 +89,18 @@ pub mod pallet { #[pallet::pallet] pub struct Pallet(_); - // HybridVM contracts + // HybridVM contracts, keys: address #[pallet::storage] #[pallet::getter(fn hvm_contracts)] pub type HvmContracts = StorageMap<_, Twox64Concat, H160, UnifiedAddress, OptionQuery>; + // HybridVM EVM ABI, keys: address+selector + #[pallet::storage] + #[pallet::getter(fn evm_fun_abi)] + pub type EvmABInfo = + StorageDoubleMap<_, Twox64Concat, H160, Twox64Concat, u32, FunABI, OptionQuery>; + #[pallet::event] #[pallet::generate_deposit(pub(super) fn deposit_event)] pub enum Event { @@ -99,7 +116,10 @@ pub mod pallet { EVMExecuteFailed, WasmVMExecuteFailed, UnifiedAddressError, - NoWasmVMContract, + NoWasmContractOrCallError, + EvmABIDecodeError, + EvmABIError, + WasmContractRevert, } #[pallet::hooks] @@ -108,7 +128,7 @@ pub mod pallet { #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(1))] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(2))] pub fn regist_contract( origin: OriginFor, unified_address: UnifiedAddress, @@ -117,18 +137,62 @@ pub mod pallet { match unified_address.clone() { UnifiedAddress::::WasmVM(account) => { - let value = pallet_contracts::Pallet::::get_storage(account.clone(), vec![]); - match value { - Err(t) => { - if t == pallet_contracts::ContractAccessError::DoesntExist { - return Err(Error::::NoWasmVMContract.into()); - } - }, - _ => {}, + let mut a: [u8; 4] = Default::default(); + a.copy_from_slice(&BlakeTwo256::hash(b"hybridvm_evm_abi")[0..4]); + let abi_of_call = ExecutionInput::new(Selector::new(a)); + + let result = pallet_contracts::Pallet::::bare_call( + who.clone(), + account.clone(), + 0u8.into(), + WEIGHT_LIMIT, + None, + abi_of_call.encode(), + DebugInfo::Skip, + CollectEvents::Skip, + Determinism::Enforced, + ) + .result + .unwrap_or(return Err(Error::::NoWasmContractOrCallError.into())); + + if result.did_revert() { + return Err(Error::::WasmContractRevert.into()); } + + let evm_abi = > as Decode>::decode(&mut &result.data[..]) + .unwrap_or(return Err(Error::::EvmABIDecodeError.into())) + .unwrap_or(return Err(Error::::EvmABIDecodeError.into())); + + let mut abi_info: Vec<(u32, FunABI)> = vec![]; + for abi in evm_abi { + let index = + abi.0.find(')').unwrap_or(return Err(Error::::EvmABIError.into())); + let mut a: [u8; 4] = Default::default(); + a.copy_from_slice(&Keccak256::digest(abi.0[0..index + 1].as_bytes())[0..4]); + let selector = u32::from_be_bytes(a); + + let wasm_selector = match abi.2 { + Some(t) => t, + None => { + let mut a: [u8; 4] = Default::default(); + a.copy_from_slice(&BlakeTwo256::hash(abi.1.as_bytes())[0..4]); + a + }, + }; + let evm_fun_abi = + BoundedVec::>::truncate_from(abi.0.into_bytes()); + abi_info.push((selector, (wasm_selector, evm_fun_abi))); + } + let address = T::AccountIdMapping::into_address(account); HvmContracts::::insert(address, unified_address.clone()); + //if EvmABInfo::::contains_prefix(address) { + _ = EvmABInfo::::clear_prefix(address, 10000, None); + //} + for abi in abi_info { + EvmABInfo::::insert(address, abi.0, abi.1); + } Self::deposit_event(Event::RegistContract(address, unified_address, who)); Ok(().into()) From 1d5f5e6f361038460eba1beebc45a73815f62aa5 Mon Sep 17 00:00:00 2001 From: wd30130 Date: Sun, 11 Aug 2024 22:10:15 +0800 Subject: [PATCH 03/12] feat(*): add evm abi process in hybrid-vm-port --- Cargo.lock | 136 +++++- Cargo.toml | 1 + .../evm-precompile/call-hybrid-vm/Cargo.toml | 2 +- .../evm-precompile/call-hybrid-vm/src/lib.rs | 6 +- frame/hybrid-vm-port/Cargo.toml | 4 +- frame/hybrid-vm-port/src/lib.rs | 253 +--------- frame/hybrid-vm-port/src/mock.rs | 9 +- frame/hybrid-vm-port/src/port.rs | 444 ++++++++++++++++++ frame/hybrid-vm-port/src/tests/eip1559.rs | 16 +- frame/hybrid-vm-port/src/tests/eip2930.rs | 16 +- frame/hybrid-vm-port/src/tests/legacy.rs | 16 +- frame/hybrid-vm-port/src/tests/mod.rs | 10 +- frame/hybrid-vm/Cargo.toml | 2 +- frame/hybrid-vm/src/interoperate/mod.rs | 59 ++- frame/hybrid-vm/src/lib.rs | 37 +- frame/hybrid-vm/src/mock.rs | 5 +- frame/hybrid-vm/src/tests.rs | 71 +-- 17 files changed, 724 insertions(+), 363 deletions(-) create mode 100644 frame/hybrid-vm-port/src/port.rs diff --git a/Cargo.lock b/Cargo.lock index d66f0aa..cc25898 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -672,6 +672,12 @@ version = "1.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a12916984aab3fa6e39d655a33e09c0071eb36d6ab3aea5c2d78551f1df6d952" +[[package]] +name = "case" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fd6c0e7b807d60291f42f33f58480c0bfafe28ed08286446f45e463728cf9c1c" + [[package]] name = "cc" version = "1.1.5" @@ -696,7 +702,7 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "common" version = "0.1.0" -source = "git+https://github.com/w3f/ring-proof#626c9598be949aa3dbdd72e8a40531f68b01d6c2" +source = "git+https://github.com/w3f/ring-proof#665f5f51af5734c7b6d90b985dd6861d4c5b4752" dependencies = [ "ark-ec", "ark-ff", @@ -953,6 +959,15 @@ dependencies = [ "zeroize", ] +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "derivative" version = "2.2.0" @@ -1862,10 +1877,11 @@ dependencies = [ [[package]] name = "hp-system" -version = "0.1.0" +version = "0.3.0" dependencies = [ "frame-support", "frame-system", + "sp-core", "sp-runtime", "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.11.0)", ] @@ -2414,6 +2430,12 @@ dependencies = [ "num-traits", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + [[package]] name = "num-format" version = "0.4.4" @@ -2477,7 +2499,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "681030a937600a36906c185595136d26abfebb4aa9c65701cefcaf8578bb982b" dependencies = [ - "proc-macro-crate 3.1.0", + "proc-macro-crate 1.3.1", "proc-macro2", "quote", "syn 2.0.71", @@ -2634,7 +2656,7 @@ dependencies = [ [[package]] name = "pallet-evm-precompile-call-hybrid-vm" -version = "0.1.0" +version = "0.3.0" dependencies = [ "evm", "fp-evm", @@ -2664,7 +2686,7 @@ dependencies = [ [[package]] name = "pallet-hybrid-vm" -version = "0.2.0" +version = "0.3.0" dependencies = [ "assert_matches", "blake2-rfc", @@ -2705,8 +2727,9 @@ dependencies = [ [[package]] name = "pallet-hybrid-vm-port" -version = "0.2.0-dev" +version = "0.3.0" dependencies = [ + "byte-slice-cast", "ethereum", "ethereum-types", "evm", @@ -2719,19 +2742,24 @@ dependencies = [ "frame-support", "frame-system", "hex", + "hp-system", "ink_env", "libsecp256k1", "pallet-balances", "pallet-contracts", "pallet-evm", "pallet-hybrid-vm", + "pallet-insecure-randomness-collective-flip", "pallet-timestamp", "parity-scale-codec", + "precompile-utils", "rlp", "scale-info", + "sha3 0.8.2", "sp-core", "sp-io", "sp-runtime", + "sp-std 14.0.0 (git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot-v1.11.0)", ] [[package]] @@ -2987,12 +3015,56 @@ dependencies = [ "syn 2.0.71", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "ppv-lite86" version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "precompile-utils" +version = "0.1.0" +source = "git+https://github.com/paritytech/frontier?branch=polkadot-v1.11.0#5779b59043ae018d07d84f4e8e0c49087f804d3a" +dependencies = [ + "environmental", + "evm", + "fp-evm", + "frame-support", + "frame-system", + "hex", + "impl-trait-for-tuples", + "log", + "num_enum", + "pallet-evm", + "parity-scale-codec", + "precompile-utils-macro", + "sp-core", + "sp-io", + "sp-runtime", + "sp-weights 27.0.0", + "staging-xcm 7.0.0", +] + +[[package]] +name = "precompile-utils-macro" +version = "0.1.0" +source = "git+https://github.com/paritytech/frontier?branch=polkadot-v1.11.0#5779b59043ae018d07d84f4e8e0c49087f804d3a" +dependencies = [ + "case", + "num_enum", + "prettyplease", + "proc-macro2", + "quote", + "sp-crypto-hashing", + "syn 1.0.109", +] + [[package]] name = "pretty_assertions" version = "0.7.2" @@ -3270,7 +3342,7 @@ dependencies = [ [[package]] name = "ring" version = "0.1.0" -source = "git+https://github.com/w3f/ring-proof#626c9598be949aa3dbdd72e8a40531f68b01d6c2" +source = "git+https://github.com/w3f/ring-proof#665f5f51af5734c7b6d90b985dd6861d4c5b4752" dependencies = [ "ark-ec", "ark-ff", @@ -3929,7 +4001,7 @@ dependencies = [ [[package]] name = "sp-crypto-ec-utils" version = "0.10.0" -source = "git+https://github.com/paritytech/polkadot-sdk#4bcdf8166972b63a70b618c90424b9f7d64b719b" +source = "git+https://github.com/paritytech/polkadot-sdk#149c70938f2b29f8d92ba1cc952aeb63d4084e27" dependencies = [ "ark-bls12-377", "ark-bls12-377-ext", @@ -3993,7 +4065,7 @@ dependencies = [ [[package]] name = "sp-debug-derive" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#4bcdf8166972b63a70b618c90424b9f7d64b719b" +source = "git+https://github.com/paritytech/polkadot-sdk#149c70938f2b29f8d92ba1cc952aeb63d4084e27" dependencies = [ "proc-macro2", "quote", @@ -4013,7 +4085,7 @@ dependencies = [ [[package]] name = "sp-externalities" version = "0.25.0" -source = "git+https://github.com/paritytech/polkadot-sdk#4bcdf8166972b63a70b618c90424b9f7d64b719b" +source = "git+https://github.com/paritytech/polkadot-sdk#149c70938f2b29f8d92ba1cc952aeb63d4084e27" dependencies = [ "environmental", "parity-scale-codec", @@ -4148,7 +4220,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface" version = "24.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#4bcdf8166972b63a70b618c90424b9f7d64b719b" +source = "git+https://github.com/paritytech/polkadot-sdk#149c70938f2b29f8d92ba1cc952aeb63d4084e27" dependencies = [ "bytes", "impl-trait-for-tuples", @@ -4180,7 +4252,7 @@ dependencies = [ [[package]] name = "sp-runtime-interface-proc-macro" version = "17.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#4bcdf8166972b63a70b618c90424b9f7d64b719b" +source = "git+https://github.com/paritytech/polkadot-sdk#149c70938f2b29f8d92ba1cc952aeb63d4084e27" dependencies = [ "Inflector", "expander", @@ -4237,7 +4309,7 @@ source = "git+https://github.com/paritytech/polkadot-sdk?branch=release-polkadot [[package]] name = "sp-std" version = "14.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#4bcdf8166972b63a70b618c90424b9f7d64b719b" +source = "git+https://github.com/paritytech/polkadot-sdk#149c70938f2b29f8d92ba1cc952aeb63d4084e27" [[package]] name = "sp-storage" @@ -4254,7 +4326,7 @@ dependencies = [ [[package]] name = "sp-storage" version = "19.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#4bcdf8166972b63a70b618c90424b9f7d64b719b" +source = "git+https://github.com/paritytech/polkadot-sdk#149c70938f2b29f8d92ba1cc952aeb63d4084e27" dependencies = [ "impl-serde", "parity-scale-codec", @@ -4289,7 +4361,7 @@ dependencies = [ [[package]] name = "sp-tracing" version = "16.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#4bcdf8166972b63a70b618c90424b9f7d64b719b" +source = "git+https://github.com/paritytech/polkadot-sdk#149c70938f2b29f8d92ba1cc952aeb63d4084e27" dependencies = [ "parity-scale-codec", "tracing", @@ -4361,7 +4433,7 @@ dependencies = [ [[package]] name = "sp-wasm-interface" version = "20.0.0" -source = "git+https://github.com/paritytech/polkadot-sdk#4bcdf8166972b63a70b618c90424b9f7d64b719b" +source = "git+https://github.com/paritytech/polkadot-sdk#149c70938f2b29f8d92ba1cc952aeb63d4084e27" dependencies = [ "impl-trait-for-tuples", "log", @@ -4605,6 +4677,37 @@ dependencies = [ "once_cell", ] +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", +] + [[package]] name = "tiny-keccak" version = "2.0.2" @@ -4741,6 +4844,7 @@ dependencies = [ "sharded-slab", "smallvec", "thread_local", + "time", "tracing", "tracing-core", "tracing-log", diff --git a/Cargo.toml b/Cargo.toml index 51c6b68..7563485 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -76,6 +76,7 @@ fp-self-contained = { git = "https://github.com/paritytech/frontier", branch = " fp-storage = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.11.0", default-features = false } pallet-evm = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.11.0", default-features = false } pallet-evm-precompile-simple = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.11.0", default-features = false } +precompile-utils = { git = "https://github.com/paritytech/frontier", branch = "polkadot-v1.11.0", default-features = false } # ink ink_env = { git = "https://github.com/paritytech/ink" } diff --git a/frame/evm-precompile/call-hybrid-vm/Cargo.toml b/frame/evm-precompile/call-hybrid-vm/Cargo.toml index 59cbfe7..d9356a7 100644 --- a/frame/evm-precompile/call-hybrid-vm/Cargo.toml +++ b/frame/evm-precompile/call-hybrid-vm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-evm-precompile-call-hybrid-vm" -version = "0.3.0" +version = "0.4.0" description = "Call Hybrid vm precompiles for EVM pallet." repository.workspace = true edition.workspace = true diff --git a/frame/evm-precompile/call-hybrid-vm/src/lib.rs b/frame/evm-precompile/call-hybrid-vm/src/lib.rs index 4654c51..0707146 100644 --- a/frame/evm-precompile/call-hybrid-vm/src/lib.rs +++ b/frame/evm-precompile/call-hybrid-vm/src/lib.rs @@ -16,8 +16,10 @@ #![cfg_attr(not(feature = "std"), no_std)] use core::marker::PhantomData; -use fp_evm::{ExitError, ExitSucceed, Precompile, PrecompileFailure}; -use fp_evm::{PrecompileHandle, PrecompileOutput, PrecompileResult}; +use fp_evm::{ + ExitError, ExitSucceed, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput, + PrecompileResult, +}; use frame_system::RawOrigin; use hp_system::EvmHybridVMExtension; use pallet_evm::AddressMapping; diff --git a/frame/hybrid-vm-port/Cargo.toml b/frame/hybrid-vm-port/Cargo.toml index e290e2d..c5efe2a 100644 --- a/frame/hybrid-vm-port/Cargo.toml +++ b/frame/hybrid-vm-port/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-hybrid-vm-port" -version = "0.3.0" +version = "0.4.0" license = "Apache-2.0" description = "HybridVM port pallet for HybridVM." edition = { workspace = true } @@ -28,6 +28,7 @@ fp-evm = { workspace = true } fp-rpc = { workspace = true } fp-storage = { workspace = true } pallet-evm = { workspace = true } +precompile-utils = { workspace = true } # ink! ink_env = { workspace = true, features = ["no-panic-handler"] } #local @@ -72,6 +73,7 @@ std = [ "fp-storage/std", "pallet-evm/std", "pallet-contracts/std", + "precompile-utils/std", ] runtime-benchmarks = [ "frame-support/runtime-benchmarks", diff --git a/frame/hybrid-vm-port/src/lib.rs b/frame/hybrid-vm-port/src/lib.rs index 1d90853..92782d5 100644 --- a/frame/hybrid-vm-port/src/lib.rs +++ b/frame/hybrid-vm-port/src/lib.rs @@ -17,6 +17,11 @@ // See the License for the specific language governing permissions and // limitations under the License. +//! # Ethereum pallet +//! +//! The Ethereum pallet works together with EVM pallet to provide full emulation +//! for Ethereum block processing. + // Modified by Alex Wang 2024 //! # Hybrid-vm-port pallet @@ -36,6 +41,8 @@ mod mock; #[cfg(all(feature = "std", test))] mod tests; +mod port; + use alloc::{vec, vec::Vec}; use core::marker::PhantomData; pub use ethereum::{ @@ -43,7 +50,7 @@ pub use ethereum::{ TransactionAction, TransactionV2 as Transaction, }; use ethereum_types::{Bloom, BloomInput, H160, H256, H64, U256}; -use evm::{ExitReason, ExitSucceed}; +use evm::ExitReason; use scale_codec::{Decode, Encode, MaxEncodedLen}; use scale_info::TypeInfo; // Substrate @@ -57,34 +64,22 @@ use frame_support::{ use frame_system::{pallet_prelude::OriginFor, CheckWeight, WeightInfo}; use sp_runtime::{ generic::DigestItem, - traits::{ - BlakeTwo256, DispatchInfoOf, Dispatchable, Hash, One, Saturating, UniqueSaturatedInto, Zero, - }, + traits::{DispatchInfoOf, Dispatchable, One, Saturating, UniqueSaturatedInto, Zero}, transaction_validity::{ InvalidTransaction, TransactionValidity, TransactionValidityError, ValidTransactionBuilder, }, - DispatchError, RuntimeDebug, SaturatedConversion, + RuntimeDebug, SaturatedConversion, }; // Frontier use fp_consensus::{PostLog, PreLog, FRONTIER_ENGINE_ID}; pub use fp_ethereum::TransactionData; use fp_ethereum::ValidatedTransaction as ValidatedTransactionT; use fp_evm::{ - CallInfo, CallOrCreateInfo, CheckEvmTransaction, CheckEvmTransactionConfig, - TransactionValidationError, UsedGas, + CallOrCreateInfo, CheckEvmTransaction, CheckEvmTransactionConfig, TransactionValidationError, }; pub use fp_rpc::TransactionStatus; use fp_storage::{EthereumStorageSchema, PALLET_ETHEREUM_SCHEMA}; -use hp_system::U256BalanceMapping; -use ink_env::call::{ExecutionInput, Selector}; -use pallet_contracts::chain_extension::SysConfig; -use pallet_contracts::{CollectEvents, DebugInfo, Determinism}; -use pallet_evm::{AddressMapping, BlockHashMapping, FeeCalculator, GasWeightMapping, Runner}; -use pallet_hybrid_vm::UnifiedAddress; - -fn str2s(s: String) -> &'static str { - Box::leak(s.into_boxed_str()) -} +use pallet_evm::{BlockHashMapping, FeeCalculator, GasWeightMapping, Runner}; #[derive(Clone, Eq, PartialEq, RuntimeDebug, Encode, Decode, MaxEncodedLen, TypeInfo)] pub enum RawOrigin { @@ -122,7 +117,8 @@ impl Call where OriginFor: Into>>, T: Send + Sync + Config, - ::RuntimeCall: Dispatchable, + ::RuntimeCall: + Dispatchable, { pub fn is_self_contained(&self) -> bool { matches!(self, Call::transact { .. }) @@ -147,7 +143,7 @@ where pub fn pre_dispatch_self_contained( &self, origin: &H160, - dispatch_info: &DispatchInfoOf<::RuntimeCall>, + dispatch_info: &DispatchInfoOf<::RuntimeCall>, len: usize, ) -> Option> { if let Call::transact { transaction } = self { @@ -164,7 +160,7 @@ where pub fn validate_self_contained( &self, origin: &H160, - dispatch_info: &DispatchInfoOf<::RuntimeCall>, + dispatch_info: &DispatchInfoOf<::RuntimeCall>, len: usize, ) -> Option { if let Call::transact { transaction } = self { @@ -260,10 +256,10 @@ pub mod pallet { } } // Account for `on_finalize` weight: - // - read: frame_system::Pallet::::digest() - // - read: frame_system::Pallet::::block_number() - // - write: >::store_block() - // - write: >::remove() + // - read: frame_system::Pallet::::digest() + // - read: frame_system::Pallet::::block_number() + // - write: >::store_block() + // - write: >::remove() weight.saturating_add(T::DbWeight::get().reads_writes(2, 2)) } @@ -569,222 +565,13 @@ impl Pallet { builder.build() } - fn is_hybrid_vm_transaction(transaction: Transaction) -> bool { - let action = { - match transaction { - Transaction::Legacy(t) => t.action, - Transaction::EIP2930(t) => t.action, - Transaction::EIP1559(t) => t.action, - } - }; - - match action { - ethereum::TransactionAction::Call(target) => { - if pallet_hybrid_vm::HvmContracts::::contains_key(target) { - return true; - } - }, - _ => {}, - } - - false - } - - fn call_hybrid_vm( - source: H160, - transaction: Transaction, - ) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> { - let ( - input, - value, - gas_limit, - _max_fee_per_gas, - _max_priority_fee_per_gas, - _nonce, - action, - _access_list, - ) = { - match transaction { - // max_fee_per_gas and max_priority_fee_per_gas in legacy and 2930 transactions is - // the provided gas_price. - Transaction::Legacy(t) => ( - t.input.clone(), - t.value, - t.gas_limit, - Some(t.gas_price), - Some(t.gas_price), - Some(t.nonce), - t.action, - Vec::new(), - ), - Transaction::EIP2930(t) => { - let access_list: Vec<(H160, Vec)> = t - .access_list - .iter() - .map(|item| (item.address, item.storage_keys.clone())) - .collect(); - ( - t.input.clone(), - t.value, - t.gas_limit, - Some(t.gas_price), - Some(t.gas_price), - Some(t.nonce), - t.action, - access_list, - ) - }, - Transaction::EIP1559(t) => { - let access_list: Vec<(H160, Vec)> = t - .access_list - .iter() - .map(|item| (item.address, item.storage_keys.clone())) - .collect(); - ( - t.input.clone(), - t.value, - t.gas_limit, - Some(t.max_fee_per_gas), - Some(t.max_priority_fee_per_gas), - Some(t.nonce), - t.action, - access_list, - ) - }, - } - }; - - match action { - ethereum::TransactionAction::Call(target) => { - let vm_target = pallet_hybrid_vm::Pallet::::hvm_contracts(target); - let target = match vm_target { - Some(UnifiedAddress::::WasmVM(t)) => t, - None => { - return Err(DispatchErrorWithPostInfo { - post_info: PostDispatchInfo { - actual_weight: None, - pays_fee: Pays::Yes, - }, - error: DispatchError::from("Not HybridVM Contract(REVERT)"), - })?; - }, - }; - - let mut a: [u8; 4] = Default::default(); - a.copy_from_slice(&BlakeTwo256::hash(b"evm_abi_call")[0..4]); - let evm_abi_call = ExecutionInput::new(Selector::new(a)).push_arg(input); - - let mut gas_limit_u64 = u64::max_value(); - if gas_limit.lt(&U256::from(gas_limit_u64)) { - gas_limit_u64 = gas_limit.as_u64(); - } - let weight_limit: Weight = - ::GasWeightMapping::gas_to_weight( - gas_limit_u64, - false, - ); - - let origin = ::AddressMapping::into_account_id(source); - let balance_result = - ::U256BalanceMapping::u256_to_balance(value); - let balance = match balance_result { - Ok(t) => t, - Err(_) => { - return Err(DispatchErrorWithPostInfo { - post_info: PostDispatchInfo { - actual_weight: None, - pays_fee: Pays::Yes, - }, - error: DispatchError::from( - "Call HybridVM Contract value is error(REVERT)", - ), - })?; - }, - }; - - let info = pallet_contracts::Pallet::::bare_call( - origin, - target.into(), - balance, - weight_limit, - None, - evm_abi_call.encode(), - DebugInfo::Skip, - CollectEvents::Skip, - Determinism::Enforced, - ); - let output: Vec; - match info.result { - Ok(return_value) => { - if !return_value.did_revert() { - // because return_value.data = MessageResult, so, the first byte is zhe Ok() Code, be removed - output = return_value.data[1..].iter().cloned().collect(); - let call_info = CallInfo { - exit_reason: ExitReason::Succeed(ExitSucceed::Returned), - value: output, - used_gas: UsedGas { - standard: U256::from( - ::GasWeightMapping::weight_to_gas( - info.gas_consumed, - ), - ), - effective: U256::from(0u64), - }, - weight_info: None, - logs: vec![], - }; - return Ok(( - PostDispatchInfo { - actual_weight: Some(info.gas_consumed), - pays_fee: Pays::Yes, - }, - CallOrCreateInfo::Call(call_info), - )); - } else { - let mut return_code = String::from("None"); - if return_value.data.len() > 0 { - return_code = return_value.data[0].to_string(); - } - return Err(DispatchErrorWithPostInfo { - post_info: PostDispatchInfo { - actual_weight: Some(info.gas_consumed), - pays_fee: Pays::Yes, - }, - error: DispatchError::from(str2s( - ["Call wasm contract failed(REVERT):", &return_code].concat(), - )), - }); - } - }, - Err(e) => { - return Err(DispatchErrorWithPostInfo { - post_info: PostDispatchInfo { - actual_weight: None, - pays_fee: Pays::Yes, - }, - error: e, - }); - }, - } - }, - _ => { - return Err(DispatchErrorWithPostInfo { - post_info: PostDispatchInfo { actual_weight: None, pays_fee: Pays::Yes }, - error: DispatchError::from("Not HybridVM Contract Call(REVERT)"), - }); - }, - } - } - fn apply_validated_transaction( source: H160, transaction: Transaction, ) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> { - //firstly, check if it's the ethereum transaction or HybridVM transaction if Self::is_hybrid_vm_transaction(transaction.clone()) { return Self::call_hybrid_vm(source, transaction); } - let (to, _, info) = Self::execute(source, &transaction, None)?; let pending = Pending::::get(); diff --git a/frame/hybrid-vm-port/src/mock.rs b/frame/hybrid-vm-port/src/mock.rs index e61fdcb..dcb7909 100644 --- a/frame/hybrid-vm-port/src/mock.rs +++ b/frame/hybrid-vm-port/src/mock.rs @@ -30,12 +30,12 @@ use frame_support::{ weights::Weight, ConsensusEngineId, PalletId, }; -use sp_core::crypto::UncheckedFrom; -use sp_core::{hashing::keccak_256, ConstBool, H160, H256, U256}; + +use sp_core::{crypto::UncheckedFrom, hashing::keccak_256, ConstBool, H160, H256, U256}; use sp_runtime::{ traits::{BlakeTwo256, Convert, Dispatchable, IdentityLookup}, - AccountId32, BuildStorage, Perbill, + AccountId32, BuildStorage, DispatchError, Perbill, }; // Frontier use pallet_evm::{AddressMapping, BalanceOf, EnsureAddressTruncated, FeeCalculator}; @@ -209,7 +209,8 @@ impl pallet_contracts::chain_extension::ChainExtension for HybridVMChainEx fn call(&mut self, env: Environment) -> Result where E: Ext, - ::AccountId: UncheckedFrom<::Hash> + AsRef<[u8]>, + ::AccountId: + UncheckedFrom<::Hash> + AsRef<[u8]>, { let func_id = env.func_id(); match func_id { diff --git a/frame/hybrid-vm-port/src/port.rs b/frame/hybrid-vm-port/src/port.rs new file mode 100644 index 0000000..1aa10e9 --- /dev/null +++ b/frame/hybrid-vm-port/src/port.rs @@ -0,0 +1,444 @@ +// Copyright (C) HybridVM. +// This file is part of HybridVM. + +// 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 super::*; + +use fp_evm::{CallInfo, ExitSucceed, UsedGas}; +use hp_system::{AccountIdMapping, U256BalanceMapping}; +use pallet_contracts::{CollectEvents, DebugInfo, Determinism}; +use pallet_evm::AddressMapping; +use pallet_hybrid_vm::UnifiedAddress; +use precompile_utils::{ + prelude::*, + solidity::codec::{ + bytes::{BoundedBytesString, BytesKind, StringKind}, + Reader, Writer, + }, +}; +use sp_runtime::{traits::ConstU32, DispatchError}; + +fn str2s(s: String) -> &'static str { + Box::leak(s.into_boxed_str()) +} + +macro_rules! b { + ($data_type:ident, $winput:ident, $reader:ident, $err_data:ident, $($s:expr, $t:ty)*) => { + $( + if $data_type == $s { + <$t>::read(&mut $reader).map_err(|_| $err_data)?.encode_to(&mut $winput); + continue; + } + )* + } +} + +macro_rules! c { + ($data_type:ident, $writer:ident, $woutput:ident, $($s:expr, $t:ty)*) => { + $( + if $data_type == $s { + $writer = $writer.write(<$t as Decode>::decode(&mut $woutput).map_err(|_| 2)?); + continue; + } + )* + } +} +impl Pallet { + pub fn is_hybrid_vm_transaction(transaction: Transaction) -> bool { + let action = { + match transaction { + Transaction::Legacy(t) => t.action, + Transaction::EIP2930(t) => t.action, + Transaction::EIP1559(t) => t.action, + } + }; + + match action { + ethereum::TransactionAction::Call(target) => { + if pallet_hybrid_vm::HvmContracts::::contains_key(target) { + return true; + } + }, + _ => {}, + } + + false + } + + fn build_wasm_call<'a>( + input: &Vec, + abi0: [u8; 4], + abi_fun: &'a str, + ) -> Result<(Vec, Vec<&'a str>), DispatchErrorWithPostInfo> { + let err = DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { actual_weight: None, pays_fee: Pays::Yes }, + error: DispatchError::from("Fun abi error(REVERT)"), + }; + + let err_data = DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { actual_weight: None, pays_fee: Pays::Yes }, + error: DispatchError::from("Decode input data error(REVERT)"), + }; + + let index_s1 = abi_fun.find('(').ok_or(err)?; + let index_e1 = abi_fun.find(')').ok_or(err)?; + + let mut index_s2: usize = 0; + let mut index_e2: usize = 1; + + if abi_fun.len() > index_e1 { + if abi_fun[index_e1 + 1..].find('(').is_some() { + index_s2 = abi_fun[index_e1 + 1..].find('(').ok_or(err)? + index_e1 + 1; + index_e2 = abi_fun[index_e1 + 1..].find(')').ok_or(err)? + index_e1 + 1; + } + } + + if index_e1 < index_s1 || index_e2 < index_s2 { + return Err(err); + } + + let input_type: Vec<&str> = abi_fun[index_s1 + 1..index_e1].split(',').collect(); + let output_type: Vec<&str> = abi_fun[index_s2 + 1..index_e2].split(',').collect(); + + // wasm type: AccountId,bool,Vec,H256,String,u8,u16,u32,u64,u128,U256,Vec + let data_type = "address,bool,bytes,bytes32,string,uint8,uint16,uint32,uint64,uint128,uint256,address[],bool[],bytes32[],uint8[],uint16[],uint32[],uint64[],uint128[],uint256[]"; + + if input_type.iter().find(|&x| data_type.find(x).is_none()).is_some() { + return Err(err); + } + if output_type.iter().find(|&x| data_type.find(x).is_none()).is_some() { + return Err(err); + } + + let mut winput: Vec = vec![]; + abi0.encode_to(&mut winput); + + let mut reader = Reader::new_skip_selector(input).map_err(|_| err_data)?; + + for data_type in input_type { + if data_type == "address" { + let address = Address::read(&mut reader).map_err(|_| err_data)?; + let account_id = + ::AddressMapping::into_account_id(address.into()); + account_id.encode_to(&mut winput); + continue; + } else if data_type == "address[]" { + let addresses = Vec::
::read(&mut reader).map_err(|_| err_data)?; + let account_ids: Vec<_> = addresses + .iter() + .map(|&x| ::AddressMapping::into_account_id(x.into())) + .collect(); + account_ids.encode_to(&mut winput); + continue; + } else if data_type == "bytes" { + Vec::::from( + BoundedBytesString::>::read(&mut reader) + .map_err(|_| err_data)?, + ) + .encode_to(&mut winput); + continue; + } else if data_type == "string" { + String::try_from( + BoundedBytesString::>::read(&mut reader) + .map_err(|_| err_data)?, + ) + .map_err(|_| err_data)? + .encode_to(&mut winput); + continue; + } + + b!(data_type, winput, reader, err_data, "bool", bool "bytes32", H256 "uint8", u8 "uint16", u16 "uint32", u32 "uint64", u64 "uint128", u128 "uint256", U256); + b!(data_type, winput, reader, err_data, "bool[]", bool "bytes32[]", H256 "uint8[]", u8 "uint16[]", u16 "uint32[]", u32 "uint64[]", u64 "uint128[]", u128 "uint256[]", U256); + + return Err(err_data); + } + + Ok((winput, output_type)) + } + + fn convert_wasm_return(wasm_output: Vec, output_type: Vec<&str>) -> Result, u8> { + let mut woutput = wasm_output.as_slice(); + _ = as Decode>::decode(&mut woutput).map_err(|_| 1)?; + + let mut writer = Writer::new(); + for data_type in output_type { + if data_type == "address" { + let account_id = + <::AccountId as Decode>::decode(&mut woutput) + .map_err(|_| 3)?; + // address: H160 + let address = + ::AccountIdMapping::into_address(account_id); + writer = writer.write(Address::from(address)); + continue; + } else if data_type == "address[]" { + let account_ids = + ::AccountId> as Decode>::decode(&mut woutput) + .map_err(|_| 4)?; + for account_id in account_ids { + let address = + ::AccountIdMapping::into_address(account_id); + writer = writer.write(Address::from(address)); + } + continue; + } else if data_type == "bytes" { + let bounded_bytes = BoundedBytesString::>::from( + as Decode>::decode(&mut woutput).map_err(|_| 5)?, + ); + writer = writer.write(bounded_bytes); + continue; + } else if data_type == "string" { + let bounded_string = + BoundedBytesString::>::try_from( + ::decode(&mut woutput).map_err(|_| 5)?, + ) + .map_err(|_| 5)?; + writer = writer.write(bounded_string); + continue; + } + + c!(data_type, writer, woutput, "bool", bool "bytes32", H256 "uint8", u8 "uint16", u16 "uint32", u32 "uint64", u64 "uint128", u128 "uint256", U256); + c!(data_type, writer, woutput, "bool[]", bool "bytes32[]", H256 "uint8[]", u8 "uint16[]", u16 "uint32[]", u32 "uint64[]", u64 "uint128[]", u128 "uint256[]", U256); + + return Err(6); + } + + Ok(writer.build()) + } + + pub fn call_hybrid_vm( + source: H160, + transaction: Transaction, + ) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> { + let ( + input, + value, + gas_limit, + _max_fee_per_gas, + _max_priority_fee_per_gas, + _nonce, + action, + _access_list, + ) = { + match transaction { + // max_fee_per_gas and max_priority_fee_per_gas in legacy and 2930 transactions is + // the provided gas_price. + Transaction::Legacy(t) => ( + t.input.clone(), + t.value, + t.gas_limit, + Some(t.gas_price), + Some(t.gas_price), + Some(t.nonce), + t.action, + Vec::new(), + ), + Transaction::EIP2930(t) => { + let access_list: Vec<(H160, Vec)> = t + .access_list + .iter() + .map(|item| (item.address, item.storage_keys.clone())) + .collect(); + ( + t.input.clone(), + t.value, + t.gas_limit, + Some(t.gas_price), + Some(t.gas_price), + Some(t.nonce), + t.action, + access_list, + ) + }, + Transaction::EIP1559(t) => { + let access_list: Vec<(H160, Vec)> = t + .access_list + .iter() + .map(|item| (item.address, item.storage_keys.clone())) + .collect(); + ( + t.input.clone(), + t.value, + t.gas_limit, + Some(t.max_fee_per_gas), + Some(t.max_priority_fee_per_gas), + Some(t.nonce), + t.action, + access_list, + ) + }, + } + }; + + match action { + ethereum::TransactionAction::Call(target) => { + let vm_target = pallet_hybrid_vm::Pallet::::hvm_contracts(target); + match vm_target { + Some(UnifiedAddress::::WasmVM(t)) => { + let selector = if input.len() < 4 { + 0 + } else { + let mut a: [u8; 4] = Default::default(); + a.copy_from_slice(&input[0..4]); + u32::from_be_bytes(a) + }; + + let abi = pallet_hybrid_vm::Pallet::::evm_fun_abi(target, selector) + .ok_or(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: None, + pays_fee: Pays::Yes, + }, + error: DispatchError::from("No abi of the selector(REVERT)"), + })?; + + let err = DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: None, + pays_fee: Pays::Yes, + }, + error: DispatchError::from("Fun abi error(REVERT)"), + }; + let abi_fun = String::from_utf8(abi.1.to_vec()).map_err(|_| err)?; + let (wasm_call, output_type) = + Self::build_wasm_call(&input, abi.0, &abi_fun)?; + + let mut gas_limit_u64 = u64::max_value(); + if gas_limit.lt(&U256::from(gas_limit_u64)) { + gas_limit_u64 = gas_limit.as_u64(); + } + let weight_limit: Weight = + ::GasWeightMapping::gas_to_weight( + gas_limit_u64, + false, + ); + + let origin = + ::AddressMapping::into_account_id(source); + let balance_result = + ::U256BalanceMapping::u256_to_balance( + value, + ); + let balance = match balance_result { + Ok(t) => t, + Err(_) => { + return Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: None, + pays_fee: Pays::Yes, + }, + error: DispatchError::from( + "Call HybridVM Contract value is error(REVERT)", + ), + }) + }, + }; + + let info = pallet_contracts::Pallet::::bare_call( + origin, + t.into(), + balance, + weight_limit, + None, + wasm_call, + DebugInfo::Skip, + CollectEvents::Skip, + Determinism::Enforced, + ); + + match info.result { + Ok(return_value) => { + if !return_value.did_revert() { + // because return_value.data = MessageResult, so, the + // first byte is zhe Ok() Code, be removed + let err_data = DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: Some(info.gas_consumed), + pays_fee: Pays::Yes, + }, + error: DispatchError::from("Return data decode error!"), + }; + let output = + Self::convert_wasm_return(return_value.data, output_type) + .map_err(|_| err_data)?; + + let call_info = CallInfo { + exit_reason: ExitReason::Succeed(ExitSucceed::Returned), + value: output, + used_gas: UsedGas { + standard: U256::from( + ::GasWeightMapping::weight_to_gas( + info.gas_consumed, + ), + ), + effective: U256::from(0u64), + }, + weight_info: None, + logs: vec![], + }; + return Ok(( + PostDispatchInfo { + actual_weight: Some(info.gas_consumed), + pays_fee: Pays::Yes, + }, + CallOrCreateInfo::Call(call_info), + )); + } else { + let mut return_code = String::from("None"); + if return_value.data.len() > 1 { + return_code = return_value.data[1].to_string(); + } + return Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: Some(info.gas_consumed), + pays_fee: Pays::Yes, + }, + error: DispatchError::from(str2s( + ["Call wasm contract failed(REVERT):", &return_code] + .concat(), + )), + }); + } + }, + Err(e) => { + return Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: None, + pays_fee: Pays::Yes, + }, + error: e, + }); + }, + } + }, + None => { + return Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { + actual_weight: None, + pays_fee: Pays::Yes, + }, + error: DispatchError::from("Not HybridVM Contract(REVERT)"), + }); + }, + }; + }, + _ => { + return Err(DispatchErrorWithPostInfo { + post_info: PostDispatchInfo { actual_weight: None, pays_fee: Pays::Yes }, + error: DispatchError::from("Not HybridVM Contract Call(REVERT)"), + }); + }, + } + } +} diff --git a/frame/hybrid-vm-port/src/tests/eip1559.rs b/frame/hybrid-vm-port/src/tests/eip1559.rs index 82126ed..06f4163 100644 --- a/frame/hybrid-vm-port/src/tests/eip1559.rs +++ b/frame/hybrid-vm-port/src/tests/eip1559.rs @@ -624,7 +624,7 @@ fn call_hybrid_vm_works() { ::AddressMapping::into_account_id(alice.address); let substrate_bob = ::AddressMapping::into_account_id(bob.address); - // 1. Get wasm and evm contract bin + // 1. Get wasm and evm contract bin let (wasm, wasm_code_hash) = contract_module::("erc20.wasm", true).unwrap(); ext.execute_with(|| { @@ -655,14 +655,14 @@ fn call_hybrid_vm_works() { let wasm_addr = Contracts::contract_address(&substrate_alice, &wasm_code_hash, &new_call.encode(), &[]); - //3. regist contract + // 3. regist contract assert_ok!(HybridVM::regist_contract( RuntimeOrigin::signed(substrate_alice.clone()), UnifiedAddress::::WasmVM(wasm_addr.clone()), )); - //4. Transfer Token to substrate_bob + // 4. Transfer Token to substrate_bob let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&BlakeTwo256::hash(b"transfer")[0..4]); let transfer_call = ExecutionInput::new(Selector::new(a)); @@ -685,7 +685,7 @@ fn call_hybrid_vm_works() { .unwrap(); assert!(!result.did_revert()); - //5. Get substrate_bob balance of wasm token + // 5. Get substrate_bob balance of wasm token let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&BlakeTwo256::hash(b"balance_of")[0..4]); let balance_of_call = ExecutionInput::new(Selector::new(a)); @@ -711,10 +711,10 @@ fn call_hybrid_vm_works() { println!("result data before:{:?}", result); let bob_balance_before = result.data; - //6. Ethereum call hybrid vm (wasm contract) transfer wasm token to bob + // 6. Ethereum call hybrid vm (wasm contract) transfer wasm token to bob let wasm_contract = ::AccountIdMapping::into_address(wasm_addr.clone()); - let transfer_selector = &Keccak256::digest(b"transfer(address,uint256)")[0..4]; + let transfer_selector = &Keccak256::digest(b"transfer(address,uint128)")[0..4]; let transfer_value: u128 = 12_000_000_000_000_000; let call_input = [ @@ -738,7 +738,7 @@ fn call_hybrid_vm_works() { let result = Ethereum::transact(RawOrigin::EthereumTransaction(alice.address).into(), t); assert_ok!(result); - //7. Get bob balance of wasm token + // 7. Get bob balance of wasm token let result = Contracts::bare_call( substrate_bob.clone(), wasm_addr.clone(), @@ -757,7 +757,7 @@ fn call_hybrid_vm_works() { println!("result data after:{:?}", result); let bob_balance_after = result.data; - //8. Test the balance of bob being correct + // 8. Test the balance of bob being correct let after = as Decode>::decode(&mut &bob_balance_after[..]) .unwrap() .unwrap(); diff --git a/frame/hybrid-vm-port/src/tests/eip2930.rs b/frame/hybrid-vm-port/src/tests/eip2930.rs index 241c054..a5c4320 100644 --- a/frame/hybrid-vm-port/src/tests/eip2930.rs +++ b/frame/hybrid-vm-port/src/tests/eip2930.rs @@ -539,7 +539,7 @@ fn call_hybrid_vm_works() { ::AddressMapping::into_account_id(alice.address); let substrate_bob = ::AddressMapping::into_account_id(bob.address); - // 1. Get wasm and evm contract bin + // 1. Get wasm and evm contract bin let (wasm, wasm_code_hash) = contract_module::("erc20.wasm", true).unwrap(); ext.execute_with(|| { @@ -570,14 +570,14 @@ fn call_hybrid_vm_works() { let wasm_addr = Contracts::contract_address(&substrate_alice, &wasm_code_hash, &new_call.encode(), &[]); - //3. regist contract + // 3. regist contract assert_ok!(HybridVM::regist_contract( RuntimeOrigin::signed(substrate_alice.clone()), UnifiedAddress::::WasmVM(wasm_addr.clone()), )); - //4. Transfer Token to substrate_bob + // 4. Transfer Token to substrate_bob let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&BlakeTwo256::hash(b"transfer")[0..4]); let transfer_call = ExecutionInput::new(Selector::new(a)); @@ -600,7 +600,7 @@ fn call_hybrid_vm_works() { .unwrap(); assert!(!result.did_revert()); - //5. Get substrate_bob balance of wasm token + // 5. Get substrate_bob balance of wasm token let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&BlakeTwo256::hash(b"balance_of")[0..4]); let balance_of_call = ExecutionInput::new(Selector::new(a)); @@ -626,10 +626,10 @@ fn call_hybrid_vm_works() { println!("result data before:{:?}", result); let bob_balance_before = result.data; - //6. Ethereum call hybrid vm (wasm contract) transfer wasm token to bob + // 6. Ethereum call hybrid vm (wasm contract) transfer wasm token to bob let wasm_contract = ::AccountIdMapping::into_address(wasm_addr.clone()); - let transfer_selector = &Keccak256::digest(b"transfer(address,uint256)")[0..4]; + let transfer_selector = &Keccak256::digest(b"transfer(address,uint128)")[0..4]; let transfer_value: u128 = 12_000_000_000_000_000; let call_input = [ @@ -653,7 +653,7 @@ fn call_hybrid_vm_works() { let result = Ethereum::transact(RawOrigin::EthereumTransaction(alice.address).into(), t); assert_ok!(result); - //7. Get bob balance of wasm token + // 7. Get bob balance of wasm token let result = Contracts::bare_call( substrate_bob.clone(), wasm_addr.clone(), @@ -672,7 +672,7 @@ fn call_hybrid_vm_works() { println!("result data after:{:?}", result); let bob_balance_after = result.data; - //8. Test the balance of bob being correct + // 8. Test the balance of bob being correct let after = as Decode>::decode(&mut &bob_balance_after[..]) .unwrap() .unwrap(); diff --git a/frame/hybrid-vm-port/src/tests/legacy.rs b/frame/hybrid-vm-port/src/tests/legacy.rs index 08fe853..0ef630a 100644 --- a/frame/hybrid-vm-port/src/tests/legacy.rs +++ b/frame/hybrid-vm-port/src/tests/legacy.rs @@ -535,7 +535,7 @@ fn call_hybrid_vm_works() { ::AddressMapping::into_account_id(alice.address); let substrate_bob = ::AddressMapping::into_account_id(bob.address); - // 1. Get wasm and evm contract bin + // 1. Get wasm and evm contract bin let (wasm, wasm_code_hash) = contract_module::("erc20.wasm", true).unwrap(); ext.execute_with(|| { @@ -566,14 +566,14 @@ fn call_hybrid_vm_works() { let wasm_addr = Contracts::contract_address(&substrate_alice, &wasm_code_hash, &new_call.encode(), &[]); - //3. regist contract + // 3. regist contract assert_ok!(HybridVM::regist_contract( RuntimeOrigin::signed(substrate_alice.clone()), UnifiedAddress::::WasmVM(wasm_addr.clone()), )); - //4. Transfer Token to substrate_bob + // 4. Transfer Token to substrate_bob let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&BlakeTwo256::hash(b"transfer")[0..4]); let transfer_call = ExecutionInput::new(Selector::new(a)); @@ -596,7 +596,7 @@ fn call_hybrid_vm_works() { .unwrap(); assert!(!result.did_revert()); - //5. Get substrate_bob balance of wasm token + // 5. Get substrate_bob balance of wasm token let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&BlakeTwo256::hash(b"balance_of")[0..4]); let balance_of_call = ExecutionInput::new(Selector::new(a)); @@ -622,10 +622,10 @@ fn call_hybrid_vm_works() { println!("result data before:{:?}", result); let bob_balance_before = result.data; - //6. Ethereum call hybrid vm (wasm contract) transfer wasm token to bob + // 6. Ethereum call hybrid vm (wasm contract) transfer wasm token to bob let wasm_contract = ::AccountIdMapping::into_address(wasm_addr.clone()); - let transfer_selector = &Keccak256::digest(b"transfer(address,uint256)")[0..4]; + let transfer_selector = &Keccak256::digest(b"transfer(address,uint128)")[0..4]; let transfer_value: u128 = 12_000_000_000_000_000; let call_input = [ @@ -649,7 +649,7 @@ fn call_hybrid_vm_works() { let result = Ethereum::transact(RawOrigin::EthereumTransaction(alice.address).into(), t); assert_ok!(result); - //7. Get bob balance of wasm token + // 7. Get bob balance of wasm token let result = Contracts::bare_call( substrate_bob.clone(), wasm_addr.clone(), @@ -668,7 +668,7 @@ fn call_hybrid_vm_works() { println!("result data after:{:?}", result); let bob_balance_after = result.data; - //8. Test the balance of bob being correct + // 8. Test the balance of bob being correct let after = as Decode>::decode(&mut &bob_balance_after[..]) .unwrap() .unwrap(); diff --git a/frame/hybrid-vm-port/src/tests/mod.rs b/frame/hybrid-vm-port/src/tests/mod.rs index 099e323..b3ba585 100644 --- a/frame/hybrid-vm-port/src/tests/mod.rs +++ b/frame/hybrid-vm-port/src/tests/mod.rs @@ -34,11 +34,11 @@ use crate::{ }; use fp_self_contained::CheckedExtrinsic; -use sp_runtime::codec::{Decode, Encode}; -use sp_runtime::traits::{BlakeTwo256, Hash}; -use std::error::Error; -use std::fs::File; -use std::io::Read; +use sp_runtime::{ + codec::{Decode, Encode}, + traits::{BlakeTwo256, Hash}, +}; +use std::{error::Error, fs::File, io::Read}; mod eip1559; mod eip2930; diff --git a/frame/hybrid-vm/Cargo.toml b/frame/hybrid-vm/Cargo.toml index d2adf77..f46c45a 100644 --- a/frame/hybrid-vm/Cargo.toml +++ b/frame/hybrid-vm/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "pallet-hybrid-vm" -version = "0.3.0" +version = "0.4.0" description = "Engine for Hybrid vm" repository.workspace = true edition.workspace = true diff --git a/frame/hybrid-vm/src/interoperate/mod.rs b/frame/hybrid-vm/src/interoperate/mod.rs index 52fa02c..d019044 100644 --- a/frame/hybrid-vm/src/interoperate/mod.rs +++ b/frame/hybrid-vm/src/interoperate/mod.rs @@ -25,14 +25,16 @@ use alloc::string::{String, ToString}; use codec::{Decode, Encode}; use core::fmt; -use sp_std::vec; -use sp_std::vec::Vec; -use sp_std::{prelude::*, str}; +use sp_std::{prelude::*, str, vec, vec::Vec}; -use pallet_contracts::chain_extension::{Environment, Ext, InitState, RetVal}; -use pallet_contracts::{CollectEvents, DebugInfo, Determinism}; -use sp_runtime::app_crypto::sp_core::{H160, U256}; -use sp_runtime::DispatchError; +use pallet_contracts::{ + chain_extension::{Environment, Ext, InitState, RetVal}, + CollectEvents, DebugInfo, Determinism, +}; +use sp_runtime::{ + app_crypto::sp_core::{H160, U256}, + DispatchError, +}; use serde::{Deserialize, Serialize}; @@ -112,7 +114,8 @@ impl InterCall { match info.result { Ok(return_value) => { if !return_value.did_revert() { - // because return_value.data = MessageResult, so, the first byte is zhe Ok() Code, be removed + // because return_value.data = MessageResult, so, the first byte is zhe + // Ok() Code, be removed output = vm_codec::wasm_decode( &data[32..].iter().cloned().collect(), &return_value.data[1..].iter().cloned().collect(), @@ -234,13 +237,11 @@ impl fmt::Display for CustomError { pub mod vm_codec { use super::*; - use codec::Compact; - use codec::Encode; + use codec::{Compact, Encode}; use core::mem::size_of; use sha3::{Digest, Keccak256}; use sp_runtime::{traits::BlakeTwo256, AccountId32}; - use sp_std::convert::TryInto; - use sp_std::str::FromStr; + use sp_std::{convert::TryInto, str::FromStr}; type Result = sp_std::result::Result; @@ -289,10 +290,10 @@ pub mod vm_codec { let mut data_ex: Vec = Vec::new(); let mut i: usize = 0; - // 256 bit for per fix parameter, dyn parameter occupy 256bit offset value, and value add after all fix paramter - // dyn parameter in offset one 256bit length value, and after real value - // uint int using big endian, and patch 0 in high bit. else for address byte patch 0 in low bit. - // array's inputValue: len, v1,v2, ..., vlen. + // 256 bit for per fix parameter, dyn parameter occupy 256bit offset value, and value add + // after all fix paramter dyn parameter in offset one 256bit length value, and after real + // value uint int using big endian, and patch 0 in high bit. else for address byte patch + // 0 in low bit. array's inputValue: len, v1,v2, ..., vlen. for p in call_vm.InputType { let value = call_vm.InputValue.get(i).ok_or(CustomError::new("Data number error"))?; let mut value_data: Vec = Vec::new(); @@ -628,10 +629,10 @@ pub mod vm_codec { let mut data: Vec = Vec::new(); let mut i: usize = 0; - // scale codec LE: fixlength per fixed-width parameter, dyn parameter: prefixed with a compact encoding of the number of items - // compact integer with compact encoding: 00--one byte 01--two bytes 10--four bytes 11--big number - // The upper six bits are the number of bytes following - // list inputValue: Vector u8 u8 u8 "3", "12","34","56" + // scale codec LE: fixlength per fixed-width parameter, dyn parameter: prefixed with a + // compact encoding of the number of items compact integer with compact encoding: 00--one + // byte 01--two bytes 10--four bytes 11--big number The upper six bits are the + // number of bytes following list inputValue: Vector u8 u8 u8 "3", "12","34","56" for p in call_vm.InputType { let value = call_vm.InputValue.get(i).ok_or(CustomError::new("Data number error"))?; let mut value_data: Vec = Vec::new(); @@ -649,7 +650,9 @@ pub mod vm_codec { //"f32" => value_data.append(&mut to_scale::(&value)), //"f64" => value_data.append(&mut to_scale::(&value)), "bool" => value_data.append(&mut to_scale::(&value)), // false: 00 true: 01 - "enum" => value_data.append(&mut to_scale::(&value)), //Option Result are enum: None 00 Some 01 Ok 00 Err 01 + "enum" => value_data.append(&mut to_scale::(&value)), /* Option Result are + * enum: None 00 Some + * 01 Ok 00 Err 01 */ //Option : None 00 Some true 01 Some false 02 "char" => { let c = value.chars().next().ok_or(CustomError::new("Char value error"))?; @@ -687,9 +690,11 @@ pub mod vm_codec { ret } - //number 0 Vec , when it has Vector or Enum type, then the number 0+1 Vec it set number x Vec, Vec has detail info and Enum has index nmber x of the second Vec means 00:vec 01:vec - //example Vec [ ... "10", ...] 10th ["u8","string"...] "0" means none - //example Enum [ ... "13", ...] 13th ["16","17","18"] 16th ["u8","string"] "0" means none index is the index position's type + //number 0 Vec , when it has Vector or Enum type, then the number 0+1 Vec it + // set number x Vec, Vec has detail info and Enum has index nmber x of the second + // Vec means 00:vec 01:vec example Vec [ ... "10", ...] 10th ["u8","string"...] + // "0" means none example Enum [ ... "13", ...] 13th ["16","17","18"] 16th + // ["u8","string"] "0" means none index is the index position's type pub fn wasm_decode( input: &Vec, output: &Vec, @@ -798,7 +803,8 @@ pub mod vm_codec { } } }, - //Option Result are enum: None 00 Some 01, Ok00 Err01; Option : None 00 Some true 01 Some false 02 + //Option Result are enum: None 00 Some 01, Ok00 Err01; Option : None 00 + // Some true 01 Some false 02 "enum" => { let a = output[*offset] as usize; call_return.ReturnValue.push(to_string_value::(&output, offset)); @@ -876,7 +882,8 @@ pub mod vm_codec { let val_bytes = [a, output[*offset + 1], output[*offset + 2], output[*offset + 3]]; val = u32::from_le_bytes(val_bytes) as usize; }, - _ => return Err(CustomError::new("Not support.")), //ob11 not support, which up six is the bignumber length. + _ => return Err(CustomError::new("Not support.")), /* ob11 not support, which up six + * is the bignumber length. */ } b = b * 2; diff --git a/frame/hybrid-vm/src/lib.rs b/frame/hybrid-vm/src/lib.rs index 5f38e42..b3c6863 100644 --- a/frame/hybrid-vm/src/lib.rs +++ b/frame/hybrid-vm/src/lib.rs @@ -23,15 +23,22 @@ mod tests; mod interoperate; use self::interoperate::InterCall; -use frame_support::traits::{tokens::fungible::Inspect, ConstU32, Currency, Get}; -use frame_support::{weights::Weight, RuntimeDebugNoBound}; +use frame_support::{ + traits::{tokens::fungible::Inspect, ConstU32, Currency, Get}, + weights::Weight, + RuntimeDebugNoBound, +}; use ink_env::call::{ExecutionInput, Selector}; -use pallet_contracts::chain_extension::{Environment, Ext, InitState, RetVal}; -use pallet_contracts::{CollectEvents, DebugInfo, Determinism}; +use pallet_contracts::{ + chain_extension::{Environment, Ext, InitState, RetVal}, + CollectEvents, DebugInfo, Determinism, +}; use sha3::{Digest, Keccak256}; use sp_core::{H160, U256}; -use sp_runtime::traits::{BlakeTwo256, Hash}; -use sp_runtime::{AccountId32, BoundedVec, DispatchError}; +use sp_runtime::{ + traits::{BlakeTwo256, Hash}, + AccountId32, BoundedVec, DispatchError, +}; use sp_std::vec::Vec; //use sp_std::fmt::Debug; use hp_system::{AccountId32Mapping, AccountIdMapping, U256BalanceMapping}; @@ -128,7 +135,7 @@ pub mod pallet { #[pallet::call] impl Pallet { #[pallet::call_index(0)] - #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(2))] + #[pallet::weight(Weight::from_parts(10_000, 0) + T::DbWeight::get().writes(3))] pub fn regist_contract( origin: OriginFor, unified_address: UnifiedAddress, @@ -152,21 +159,22 @@ pub mod pallet { CollectEvents::Skip, Determinism::Enforced, ) - .result - .unwrap_or(return Err(Error::::NoWasmContractOrCallError.into())); + .result?; if result.did_revert() { return Err(Error::::WasmContractRevert.into()); } let evm_abi = > as Decode>::decode(&mut &result.data[..]) - .unwrap_or(return Err(Error::::EvmABIDecodeError.into())) - .unwrap_or(return Err(Error::::EvmABIDecodeError.into())); + .map_err(|_| DispatchError::from(Error::::EvmABIDecodeError))? + .map_err(|_| DispatchError::from(Error::::EvmABIDecodeError))?; let mut abi_info: Vec<(u32, FunABI)> = vec![]; for abi in evm_abi { - let index = - abi.0.find(')').unwrap_or(return Err(Error::::EvmABIError.into())); + let index = abi + .0 + .find(')') + .ok_or::(Error::::EvmABIError.into())?; let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&Keccak256::digest(abi.0[0..index + 1].as_bytes())[0..4]); let selector = u32::from_be_bytes(a); @@ -187,9 +195,8 @@ pub mod pallet { let address = T::AccountIdMapping::into_address(account); HvmContracts::::insert(address, unified_address.clone()); - //if EvmABInfo::::contains_prefix(address) { _ = EvmABInfo::::clear_prefix(address, 10000, None); - //} + for abi in abi_info { EvmABInfo::::insert(address, abi.0, abi.1); } diff --git a/frame/hybrid-vm/src/mock.rs b/frame/hybrid-vm/src/mock.rs index a6adfe6..e140729 100644 --- a/frame/hybrid-vm/src/mock.rs +++ b/frame/hybrid-vm/src/mock.rs @@ -17,10 +17,10 @@ use super::*; use byte_slice_cast::AsByteSlice; use fp_evm::Precompile; -use frame_support::pallet_prelude::*; use frame_support::{ derive_impl, dispatch::DispatchClass, + pallet_prelude::*, parameter_types, traits::{ConstU128, ConstU32, ConstU64, FindAuthor, Get}, weights::Weight, @@ -452,7 +452,8 @@ const A_SHADOW: [u8; 32] = [ const B_SHADOW: [u8; 32] = [ 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ]; -// Account shadow is the account which data is the source account data with the last 12 bytes setting zero +// Account shadow is the account which data is the source account data with the last 12 bytes +// setting zero pub const ALICE_SHADOW: AccountId32 = AccountId32::new(A_SHADOW); pub const BOB_SHADOW: AccountId32 = AccountId32::new(B_SHADOW); diff --git a/frame/hybrid-vm/src/tests.rs b/frame/hybrid-vm/src/tests.rs index 3da9faf..3494d8a 100644 --- a/frame/hybrid-vm/src/tests.rs +++ b/frame/hybrid-vm/src/tests.rs @@ -67,8 +67,7 @@ where Ok((wasm_binary, code_hash)) } -use std::fs::File; -use std::io::Read; +use std::{fs::File, io::Read}; fn read_a_file(filename: &str) -> std::io::Result> { let mut file = File::open(filename)?; @@ -103,7 +102,7 @@ where // Perform test for wasm contract calling EVM contract to transfer EVM ERC20 token #[test] fn test_wasm_call_evm() { - // 1. Get wasm and evm contract bin + // 1. Get wasm and evm contract bin let (wasm, wasm_code_hash) = contract_module::("erc20.wasm", true).unwrap(); let (evm, _evm_code_hash) = contract_module::("erc20_evm_bytecode.txt", false).unwrap(); @@ -136,7 +135,7 @@ fn test_wasm_call_evm() { //assert!(ContractInfoOf::::contains_key(&wasm_addr)); - //3. Create EVM contract and tranfer to bob token + // 3. Create EVM contract and tranfer to bob token let source = H160::from_slice(&(AsRef::<[u8; 32]>::as_ref(&ALICE_SHADOW)[0..20])); let creation4evm = ::Runner::create( @@ -212,7 +211,7 @@ fn test_wasm_call_evm() { }; println!("Alice transfer to Bob token:{}", transfer_result); - //4. Get BOB_SHADOW balance of EVM token + // 4. Get BOB_SHADOW balance of EVM token let balance_of_selector = &Keccak256::digest(b"balanceOf(address)")[0..4]; let source_bob = H160::from_slice(&(AsRef::<[u8; 32]>::as_ref(&BOB_SHADOW)[0..20])); @@ -253,7 +252,8 @@ fn test_wasm_call_evm() { }; println!("bob_balance_before={}", bob_balance_before); - //5. Call wasm contract to call evm transfer evm token to bob. H160: evm contract address, H160: bob's address u128: value + // 5. Call wasm contract to call evm transfer evm token to bob. H160: evm contract address, + // H160: bob's address u128: value let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&BlakeTwo256::hash(b"wasmCallEvm")[0..4]); let call = ExecutionInput::new(Selector::new(a)); @@ -281,7 +281,7 @@ fn test_wasm_call_evm() { assert!(!result.did_revert()); println!("Alice transfer to Bob from wasm_call_evm:{}", transfer_value); - //6. Get BOB_SHADOW balance of EVM token + // 6. Get BOB_SHADOW balance of EVM token let call4evm = ::Runner::call( source_bob, evm_addr, @@ -314,7 +314,7 @@ fn test_wasm_call_evm() { }, }; println!("bob_balance_after={}", bob_balance_after); - //7. Test the balance of BOB_SHADOW being correct + // 7. Test the balance of BOB_SHADOW being correct assert_eq!(bob_balance_after, bob_balance_before + transfer_value); }); } @@ -322,7 +322,7 @@ fn test_wasm_call_evm() { // Perform test for EVM contract calling wasm contract to transfer wasm ERC20 token #[test] fn test_evm_call_wasm() { - // 1. Get wasm and evm contract bin + // 1. Get wasm and evm contract bin let (wasm, wasm_code_hash) = contract_module::("erc20.wasm", true).unwrap(); let (evm, _evm_code_hash) = contract_module::("erc20_evm_bytecode.txt", false).unwrap(); @@ -378,7 +378,7 @@ fn test_evm_call_wasm() { assert!(!result.did_revert()); - //3. Create EVM contract + // 3. Create EVM contract let source = H160::from_slice(&(AsRef::<[u8; 32]>::as_ref(&ALICE_SHADOW)[0..20])); let creation4evm = ::Runner::create( @@ -410,7 +410,7 @@ fn test_evm_call_wasm() { }, } - //4. Get BOB_SHADOW balance of wasm token + // 4. Get BOB_SHADOW balance of wasm token let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&BlakeTwo256::hash(b"balance_of")[0..4]); let balance_of_call = ExecutionInput::new(Selector::new(a)); @@ -436,7 +436,8 @@ fn test_evm_call_wasm() { println!("result data before:{:?}", result); let bob_balance_before = result.data; - //5. Call EVM contract to call wasm contract transfer wasm token to bob, the last bytes32 is the wasm contract accountid + // 5. Call EVM contract to call wasm contract transfer wasm token to bob, the last bytes32 + // is the wasm contract accountid let evm_call_wasm_selector = &Keccak256::digest(b"evmCallWasm(bytes32,uint256,bytes32)")[0..4]; @@ -475,7 +476,7 @@ fn test_evm_call_wasm() { assert!(&call4evm.unwrap().exit_reason.is_succeed()); println!("Alice transfer to Bob from evm_call_wasm:{}", transfer_value); - //6. Get BOB_SHADOW balance of wasm token + // 6. Get BOB_SHADOW balance of wasm token let result = Contracts::bare_call( BOB_SHADOW.clone(), wasm_addr.clone(), @@ -494,7 +495,7 @@ fn test_evm_call_wasm() { println!("result data after:{:?}", result); let bob_balance_after = result.data; - //7. Test the balance of BOB_SHADOW being correct + // 7. Test the balance of BOB_SHADOW being correct let after = as Decode>::decode(&mut &bob_balance_after[..]) .unwrap() .unwrap(); @@ -508,7 +509,7 @@ fn test_evm_call_wasm() { // Perform test for wasm contract calling EVM contract to get bob's EVM ERC20 token balance #[test] fn test_wasm_call_evm_balance() { - // 1. Get wasm and evm contract bin + // 1. Get wasm and evm contract bin let (wasm, wasm_code_hash) = contract_module::("erc20.wasm", true).unwrap(); let (evm, _evm_code_hash) = contract_module::("erc20_evm_bytecode.txt", false).unwrap(); @@ -541,7 +542,7 @@ fn test_wasm_call_evm_balance() { //assert!(ContractInfoOf::::contains_key(&wasm_addr)); - //3. Create EVM contract and tranfer to bob token + // 3. Create EVM contract and tranfer to bob token let source = H160::from_slice(&(AsRef::<[u8; 32]>::as_ref(&ALICE_SHADOW)[0..20])); let creation4evm = ::Runner::create( @@ -618,7 +619,8 @@ fn test_wasm_call_evm_balance() { println!("Alice transfer to Bob evm result:{}, tokens:{}", transfer_result, token); - //4. Call wasm contract to call evm for getting BOB_SHADOW balance of EVM token. H160: evm contract address, H160: BOB_SHADOW's address + // 4. Call wasm contract to call evm for getting BOB_SHADOW balance of EVM token. H160: evm + // contract address, H160: BOB_SHADOW's address let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&BlakeTwo256::hash(b"wasmCallEvmBalance")[0..4]); let call = ExecutionInput::new(Selector::new(a)); @@ -651,7 +653,7 @@ fn test_wasm_call_evm_balance() { .unwrap(); println!("BOB_SHADOW's evm token balance:{:?}", balance_return); - //5. Test the evm token balance of BOB_SHADOW being correct + // 5. Test the evm token balance of BOB_SHADOW being correct assert_eq!(balance_return, token); }); } @@ -659,7 +661,7 @@ fn test_wasm_call_evm_balance() { // Perform test for EVM contract calling wasm contract to get bob's wasm ERC20 token balance #[test] fn test_evm_call_wasm_balance() { - // 1. Get wasm and evm contract bin + // 1. Get wasm and evm contract bin let (wasm, wasm_code_hash) = contract_module::("erc20.wasm", true).unwrap(); let (evm, _evm_code_hash) = contract_module::("erc20_evm_bytecode.txt", false).unwrap(); @@ -716,7 +718,7 @@ fn test_evm_call_wasm_balance() { assert!(!result.did_revert()); println!("Alice transfer to Bob wasm token:{}", token); - //3. Create EVM contract + // 3. Create EVM contract let source = H160::from_slice(&(AsRef::<[u8; 32]>::as_ref(&ALICE_SHADOW)[0..20])); let creation4evm = ::Runner::create( @@ -748,7 +750,8 @@ fn test_evm_call_wasm_balance() { }, } - //4. Call evm contract to call wasm for getting BOB_SHADOW balance of wasm token. H160: BOB_SHADOW's address , the last bytes32 is the wasm contract accountid + // 4. Call evm contract to call wasm for getting BOB_SHADOW balance of wasm token. H160: + // BOB_SHADOW's address , the last bytes32 is the wasm contract accountid let evm_call_wasm_selector = &Keccak256::digest(b"evmCallWasmBalance(bytes32,bytes32)")[0..4]; @@ -794,15 +797,16 @@ fn test_evm_call_wasm_balance() { println!("BOB_SHADOW's wasm token balance:{}", bob_balance); - //5. Test the wasm token balance of BOB_SHADOW being correct + // 5. Test the wasm token balance of BOB_SHADOW being correct assert_eq!(bob_balance, token); }); } -// Perform test for wasm contract calling EVM echo contract, testing parameters of different data types. +// Perform test for wasm contract calling EVM echo contract, testing parameters of different data +// types. #[test] fn test_wasm_call_evm_echo() { - // 1. Get wasm and evm contract bin + // 1. Get wasm and evm contract bin let (wasm, wasm_code_hash) = contract_module::("erc20.wasm", true).unwrap(); let (evm, _evm_code_hash) = contract_module::("erc20_evm_bytecode.txt", false).unwrap(); @@ -835,7 +839,7 @@ fn test_wasm_call_evm_echo() { //assert!(ContractInfoOf::::contains_key(&wasm_addr)); - //3. Create EVM contract + // 3. Create EVM contract let source = H160::from_slice(&(AsRef::<[u8; 32]>::as_ref(&ALICE_SHADOW)[0..20])); let creation4evm = ::Runner::create( @@ -867,7 +871,7 @@ fn test_wasm_call_evm_echo() { }, } - //4. Call wasm contract to call evm using parameters of different data types. + // 4. Call wasm contract to call evm using parameters of different data types. let mut a: [u8; 4] = Default::default(); a.copy_from_slice(&BlakeTwo256::hash(b"wasmCallEvmProxy")[0..4]); let call = ExecutionInput::new(Selector::new(a)); @@ -912,16 +916,17 @@ fn test_wasm_call_evm_echo() { i += 1; } println!("array:{:?}", echo_arr); - //5. Test whether the evm echo result is correct + // 5. Test whether the evm echo result is correct assert_eq!(&echo_string, "test string!"); assert_eq!(echo_arr[0..echo_arr_len], [231usize, 19usize, 6usize][..]); }); } -// Perform test for EVM contract calling wasm echo contract, testing parameters of different data types. +// Perform test for EVM contract calling wasm echo contract, testing parameters of different data +// types. #[test] fn test_evm_call_wasm_echo() { - // 1. Get wasm and evm contract bin + // 1. Get wasm and evm contract bin let (wasm, wasm_code_hash) = contract_module::("erc20.wasm", true).unwrap(); let (evm, _evm_code_hash) = contract_module::("erc20_evm_bytecode.txt", false).unwrap(); @@ -953,7 +958,7 @@ fn test_evm_call_wasm_echo() { assert_ok!(creation); //assert!(ContractInfoOf::::contains_key(&wasm_addr)); - //3. Create EVM contract + // 3. Create EVM contract let source = H160::from_slice(&(AsRef::<[u8; 32]>::as_ref(&ALICE_SHADOW)[0..20])); let creation4evm = ::Runner::create( @@ -985,7 +990,7 @@ fn test_evm_call_wasm_echo() { }, } - //4. Call evm contract to call wasm using parameters of different data types. + // 4. Call evm contract to call wasm using parameters of different data types. let evm_call_wasm_selector = &Keccak256::digest(b"evmCallWasmProxy(string)")[0..4]; let wasm_contract: [u8; 32] = wasm_addr.clone().into(); @@ -1060,7 +1065,7 @@ fn test_evm_call_wasm_echo() { i += 1; } println!("array:{:?}", echo_arr); - //5. Test whether the wasm echo result is correct + // 5. Test whether the wasm echo result is correct assert_eq!(&echo_string, "test string!"); assert_eq!(echo_arr[0..echo_arr_len], [231usize, 19usize, 6usize][..]); }); @@ -1069,7 +1074,7 @@ fn test_evm_call_wasm_echo() { // Perform test for regist_contract. #[test] fn regist_contract_works() { - // 1. Get wasm bin + // 1. Get wasm bin let (wasm, wasm_code_hash) = contract_module::("erc20.wasm", true).unwrap(); ExtBuilder::default().existential_deposit(100).build().execute_with(|| { From 83e685f1dd8d62eb3c96a9a7c945ab0b03311a39 Mon Sep 17 00:00:00 2001 From: wd30130 Date: Sun, 11 Aug 2024 23:43:50 +0800 Subject: [PATCH 04/12] feat(*): remove special AccountId32 using --- frame/hybrid-vm-port/src/mock.rs | 41 +++++++++---------------- frame/hybrid-vm/src/interoperate/mod.rs | 15 ++++----- frame/hybrid-vm/src/lib.rs | 11 ++----- frame/hybrid-vm/src/mock.rs | 29 ++++++----------- 4 files changed, 32 insertions(+), 64 deletions(-) diff --git a/frame/hybrid-vm-port/src/mock.rs b/frame/hybrid-vm-port/src/mock.rs index dcb7909..5f68459 100644 --- a/frame/hybrid-vm-port/src/mock.rs +++ b/frame/hybrid-vm-port/src/mock.rs @@ -45,7 +45,7 @@ use pallet_contracts::chain_extension::{Environment, Ext, InitState, RetVal}; // HybridVM use byte_slice_cast::AsByteSlice; -use hp_system::{AccountId32Mapping, AccountIdMapping, U256BalanceMapping}; +use hp_system::{AccountIdMapping, U256BalanceMapping}; use super::*; use crate::IntermediateStateRoot; @@ -54,6 +54,8 @@ pub type SignedExtra = (frame_system::CheckSpecVersion,); type Balance = u128; +type AccountId = AccountId32; + frame_support::construct_runtime! { pub enum Test { System: frame_system::{Pallet, Call, Config, Storage, Event}, @@ -85,7 +87,7 @@ impl frame_system::Config for Test { type Nonce = u64; type Hash = H256; type Hashing = BlakeTwo256; - type AccountId = AccountId32; + type AccountId = AccountId; type Lookup = IdentityLookup; type Block = frame_system::mocking::MockBlock; type BlockHashCount = BlockHashCount; @@ -150,21 +152,21 @@ parameter_types! { } pub struct HashedAddressMapping; -impl AddressMapping for HashedAddressMapping { - fn into_account_id(address: H160) -> AccountId32 { +impl AddressMapping for HashedAddressMapping { + fn into_account_id(address: H160) -> AccountId { let mut data = [0u8; 32]; data[0..20].copy_from_slice(&address[..]); - AccountId32::from(Into::<[u8; 32]>::into(data)) + AccountId::from(Into::<[u8; 32]>::into(data)) } } pub struct CompactAddressMapping; -impl AddressMapping for CompactAddressMapping { - fn into_account_id(address: H160) -> AccountId32 { +impl AddressMapping for CompactAddressMapping { + fn into_account_id(address: H160) -> AccountId { let mut data = [0u8; 32]; data[0..20].copy_from_slice(&address[..]); - AccountId32::from(data) + AccountId::from(data) } } @@ -271,10 +273,10 @@ parameter_types! { } pub struct EnsureAccount(sp_std::marker::PhantomData<(T, A)>); -impl>> +impl>> EnsureOrigin<::RuntimeOrigin> for EnsureAccount where - ::AccountId: From, + ::AccountId: From, { type Success = T::AccountId; @@ -362,22 +364,11 @@ impl AccountIdMapping for Test { } } -impl AccountId32Mapping for Test { - fn id32_to_id(id32: AccountId32) -> ::AccountId { - id32.into() - } - - fn id_to_id32(account_id: ::AccountId) -> AccountId32 { - account_id.into() - } -} - impl pallet_hybrid_vm::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type U256BalanceMapping = Self; type AccountIdMapping = Self; - type AccountId32Mapping = Self; type EnableCallEVM = EnableCallEVM; type EnableCallWasmVM = EnableCallWasmVM; type GasLimit = GasLimit; @@ -453,7 +444,7 @@ impl fp_self_contained::SelfContainedCall for RuntimeCall { pub struct AccountInfo { pub address: H160, - pub account_id: AccountId32, + pub account_id: AccountId, pub private_key: H256, } @@ -466,11 +457,7 @@ fn address_build(seed: u8) -> AccountInfo { let mut data = [0u8; 32]; data[0..20].copy_from_slice(&address[..]); - AccountInfo { - private_key, - account_id: AccountId32::from(Into::<[u8; 32]>::into(data)), - address, - } + AccountInfo { private_key, account_id: AccountId::from(Into::<[u8; 32]>::into(data)), address } } // This function basically just builds a genesis storage key/value store according to diff --git a/frame/hybrid-vm/src/interoperate/mod.rs b/frame/hybrid-vm/src/interoperate/mod.rs index d019044..44ffa94 100644 --- a/frame/hybrid-vm/src/interoperate/mod.rs +++ b/frame/hybrid-vm/src/interoperate/mod.rs @@ -39,7 +39,6 @@ use sp_runtime::{ use serde::{Deserialize, Serialize}; use fp_evm::ExecutionInfoV2; -use frame_support::sp_runtime::AccountId32; use pallet_evm::Runner; use super::*; @@ -87,7 +86,7 @@ impl InterCall { } let input: Vec; - let target: AccountId32; + let target: Vec; match vm_codec::wasm_encode(&data[32..].iter().cloned().collect()) { Ok(r) => (input, target) = r, @@ -97,7 +96,8 @@ impl InterCall { let gas_limit: Weight = target_gas; let origin = ensure_signed(origin)?; - let target = T::AccountId32Mapping::id32_to_id(target); + let target = ::AccountId::decode(&mut target.as_slice()) + .map_err(|e| DispatchError::from(str2s(e.to_string())))?; let info = pallet_contracts::Pallet::::bare_call( origin, @@ -240,7 +240,7 @@ pub mod vm_codec { use codec::{Compact, Encode}; use core::mem::size_of; use sha3::{Digest, Keccak256}; - use sp_runtime::{traits::BlakeTwo256, AccountId32}; + use sp_runtime::traits::BlakeTwo256; use sp_std::{convert::TryInto, str::FromStr}; type Result = sp_std::result::Result; @@ -618,13 +618,10 @@ pub mod vm_codec { Ok(String::encode(&return_json)) } - pub fn wasm_encode(input: &Vec) -> Result<(Vec, AccountId32)> { + pub fn wasm_encode(input: &Vec) -> Result<(Vec, Vec)> { let call_vm: CallVM = t!(serde_json::from_slice(input.as_slice())); let account = call_vm.Account; - let mut bytes = [0u8; 32]; - let target = t!(hex::decode_to_slice(&account[2..], &mut bytes) - .map_err(|_| "invalid hex address.") - .map(|_| AccountId32::from(bytes))); + let target = t!(hex::decode(&account[2..]).map_err(|_| "invalid hex address.")); let selector = &::hash(call_vm.Fun.as_bytes())[0..4]; let mut data: Vec = Vec::new(); let mut i: usize = 0; diff --git a/frame/hybrid-vm/src/lib.rs b/frame/hybrid-vm/src/lib.rs index b3c6863..482f822 100644 --- a/frame/hybrid-vm/src/lib.rs +++ b/frame/hybrid-vm/src/lib.rs @@ -37,11 +37,11 @@ use sha3::{Digest, Keccak256}; use sp_core::{H160, U256}; use sp_runtime::{ traits::{BlakeTwo256, Hash}, - AccountId32, BoundedVec, DispatchError, + BoundedVec, DispatchError, }; use sp_std::vec::Vec; //use sp_std::fmt::Debug; -use hp_system::{AccountId32Mapping, AccountIdMapping, U256BalanceMapping}; +use hp_system::{AccountIdMapping, U256BalanceMapping}; pub use self::pallet::*; @@ -78,8 +78,6 @@ pub mod pallet { type AccountIdMapping: AccountIdMapping; - type AccountId32Mapping: AccountId32Mapping; - #[pallet::constant] type EnableCallEVM: Get; @@ -208,10 +206,7 @@ pub mod pallet { } } - impl Pallet - where - T::AccountId: From + Into, - { + impl Pallet { pub fn call_wasm_vm( origin: OriginFor, data: Vec, diff --git a/frame/hybrid-vm/src/mock.rs b/frame/hybrid-vm/src/mock.rs index e140729..d18e0b7 100644 --- a/frame/hybrid-vm/src/mock.rs +++ b/frame/hybrid-vm/src/mock.rs @@ -27,7 +27,7 @@ use frame_support::{ ConsensusEngineId, }; use frame_system::pallet_prelude::*; -use hp_system::{AccountId32Mapping, AccountIdMapping, EvmHybridVMExtension, U256BalanceMapping}; +use hp_system::{AccountIdMapping, EvmHybridVMExtension, U256BalanceMapping}; use pallet_contracts::chain_extension::SysConfig; use pallet_evm::{ AddressMapping, BalanceOf, EnsureAddressTruncated, FeeCalculator, GasWeightMapping, @@ -183,11 +183,11 @@ where pub struct CompactAddressMapping; -impl AddressMapping for CompactAddressMapping { - fn into_account_id(address: H160) -> AccountId32 { +impl AddressMapping for CompactAddressMapping { + fn into_account_id(address: H160) -> AccountId { let mut data = [0u8; 32]; data[0..20].copy_from_slice(&address[..]); - AccountId32::from(data) + AccountId::from(data) } } @@ -323,7 +323,7 @@ parameter_types! { } pub struct EnsureAccount(sp_std::marker::PhantomData<(T, A)>); -impl>> +impl>> EnsureOrigin<::RuntimeOrigin> for EnsureAccount where ::AccountId: From, @@ -414,22 +414,11 @@ impl AccountIdMapping for Test { } } -impl AccountId32Mapping for Test { - fn id32_to_id(id32: AccountId32) -> ::AccountId { - id32.into() - } - - fn id_to_id32(account_id: ::AccountId) -> AccountId32 { - account_id.into() - } -} - impl pallet_hybrid_vm::Config for Test { type RuntimeEvent = RuntimeEvent; type Currency = Balances; type U256BalanceMapping = Self; type AccountIdMapping = Self; - type AccountId32Mapping = Self; type EnableCallEVM = EnableCallEVM; type EnableCallWasmVM = EnableCallWasmVM; type GasLimit = GasLimit; @@ -443,8 +432,8 @@ const B: [u8; 32] = [ 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 7, 7, 7, 7, 7, 8, 8, ]; -pub const ALICE: AccountId32 = AccountId32::new(A); -pub const BOB: AccountId32 = AccountId32::new(B); +pub const ALICE: AccountId = AccountId::new(A); +pub const BOB: AccountId = AccountId::new(B); const A_SHADOW: [u8; 32] = [ 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -454,8 +443,8 @@ const B_SHADOW: [u8; 32] = [ ]; // Account shadow is the account which data is the source account data with the last 12 bytes // setting zero -pub const ALICE_SHADOW: AccountId32 = AccountId32::new(A_SHADOW); -pub const BOB_SHADOW: AccountId32 = AccountId32::new(B_SHADOW); +pub const ALICE_SHADOW: AccountId = AccountId::new(A_SHADOW); +pub const BOB_SHADOW: AccountId = AccountId::new(B_SHADOW); pub struct ExtBuilder { existential_deposit: u64, From 41ac6ed4baa7dbb5f2811fa8539d8275ae65b147 Mon Sep 17 00:00:00 2001 From: wd30130 Date: Mon, 12 Aug 2024 15:50:57 +0800 Subject: [PATCH 05/12] feat(test): the wasm contract completely compatible with ERC20 --- external/contract/src/erc20wasm/lib.rs | 71 +++++++++++----------- frame/hybrid-vm-port/src/tests/eip1559.rs | 2 +- frame/hybrid-vm-port/src/tests/eip2930.rs | 2 +- frame/hybrid-vm-port/src/tests/legacy.rs | 2 +- frame/hybrid-vm/fixtures/erc20.wasm | Bin 19223 -> 20645 bytes 5 files changed, 37 insertions(+), 40 deletions(-) diff --git a/external/contract/src/erc20wasm/lib.rs b/external/contract/src/erc20wasm/lib.rs index de1bf4c..043820b 100644 --- a/external/contract/src/erc20wasm/lib.rs +++ b/external/contract/src/erc20wasm/lib.rs @@ -64,6 +64,7 @@ mod erc20 { use ink_prelude::string::ToString; use ink_prelude::vec; use ink_prelude::vec::Vec; + use sp_core::U256; //evm_fun_abi, wasm_message_name, wasm_message_selector pub type EvmABI = (String, String, Option<[u8; 4]>); @@ -154,13 +155,12 @@ mod erc20 { #[ink(message)] pub fn hybridvm_evm_abi(&mut self) -> Vec { let mut evm_abi: Vec = vec![]; - evm_abi.push(("total_supply()returns(uint128)".to_string(), "total_supply".to_string(), None)); - evm_abi.push(("balanceOf(address)returns(uint128)".to_string(), "balance_of".to_string(), None)); - evm_abi.push(("allowance(address,address)returns(uint128)".to_string(), "allowance".to_string(), None)); - evm_abi.push(("transfer(address,uint128)returns(bool,string)".to_string(), "transfer_abi".to_string(), None)); - evm_abi.push(("approve(address,uint128)returns(bool,string)".to_string(), "approve_abi".to_string(), None)); - evm_abi.push(("transfer_from(address,address,uint128)returns(bool,string)".to_string(), "transfer_from_abi".to_string(), None)); - evm_abi.push(("transfer_from_to(address,address,uint128)returns(bool,string)".to_string(), "transfer_from_to_abi".to_string(), None)); + evm_abi.push(("totalSupply()returns(uint256)".to_string(), "total_supply_abi".to_string(), None)); + evm_abi.push(("balanceOf(address)returns(uint256)".to_string(), "balance_of_abi".to_string(), None)); + evm_abi.push(("allowance(address,address)returns(uint256)".to_string(), "allowance_abi".to_string(), None)); + evm_abi.push(("transfer(address,uint256)returns(bool)".to_string(), "transfer_abi".to_string(), None)); + evm_abi.push(("approve(address,uint256)returns(bool)".to_string(), "approve_abi".to_string(), None)); + evm_abi.push(("transferFrom(address,address,uint256)returns(bool)".to_string(), "transfer_from_abi".to_string(), None)); evm_abi } @@ -170,6 +170,11 @@ mod erc20 { pub fn total_supply(&self) -> Balance { self.total_supply } + + #[ink(message)] + pub fn total_supply_abi(&self) -> U256 { + self.total_supply.into() + } /// Returns the account balance for the specified `owner`. /// @@ -178,6 +183,11 @@ mod erc20 { pub fn balance_of(&self, owner: AccountId) -> Balance { self.balances.get(&owner).unwrap_or(0) } + + #[ink(message)] + pub fn balance_of_abi(&self, owner: AccountId) -> U256 { + self.balances.get(&owner).unwrap_or(0).into() + } /// Returns the amount which `spender` is still allowed to withdraw from `owner`. /// @@ -186,6 +196,11 @@ mod erc20 { pub fn allowance(&self, owner: AccountId, spender: AccountId) -> Balance { self.allowances.get(&(owner, spender)).unwrap_or(0) } + + #[ink(message)] + pub fn allowance_abi(&self, owner: AccountId, spender: AccountId) -> U256 { + self.allowances.get(&(owner, spender)).unwrap_or(0).into() + } /// Transfers `value` amount of tokens from the caller's account to account `to`. /// @@ -200,21 +215,11 @@ mod erc20 { let from = self.env().caller(); self.transfer_from_to(from, to, value) } - - fn result_to_abidata(result: Result<()>) -> (bool, String) { - match result { - Ok(_) => (true, String::new()), - Err(e) => match e { - Error::InsufficientBalance => (false, String::from("InsufficientBalance")), - Error::InsufficientAllowance => (false, String::from("InsufficientAllowance")), - Error::OtherError(s) => (false, s), - } - } - } - + #[ink(message)] - pub fn transfer_abi(&mut self, to: AccountId, value: Balance) -> (bool, String) { - Self::result_to_abidata(self.transfer(to, value)) + pub fn transfer_abi(&mut self, to: AccountId, value: U256) -> bool { + let Ok(value) = Balance::try_from(value) else { return false }; + self.transfer(to, value).is_ok() } /// Allows `spender` to withdraw from the caller's account multiple times, up to @@ -236,8 +241,9 @@ mod erc20 { } #[ink(message)] - pub fn approve_abi(&mut self, spender: AccountId, value: Balance) -> (bool, String) { - Self::result_to_abidata(self.approve(spender, value)) + pub fn approve_abi(&mut self, spender: AccountId, value: U256) -> bool { + let Ok(value) = Balance::try_from(value) else { return false }; + self.approve(spender, value).is_ok() } /// Transfers `value` tokens on the behalf of `from` to the account `to`. @@ -277,9 +283,10 @@ mod erc20 { &mut self, from: AccountId, to: AccountId, - value: Balance, - ) -> (bool, String) { - Self::result_to_abidata(self.transfer_from(from, to, value)) + value: U256, + ) -> bool { + let Ok(value) = Balance::try_from(value) else { return false }; + self.transfer_from(from, to, value).is_ok() } /// Transfers `value` amount of tokens from the caller's account to account `to`. @@ -312,17 +319,7 @@ mod erc20 { }); Ok(()) } - - #[ink(message)] - pub fn transfer_from_to_abi( - &mut self, - from: AccountId, - to: AccountId, - value: Balance, - ) -> (bool, String) { - Self::result_to_abidata(self.transfer_from_to(from, to, value)) - } - + // Test call EVM contract from this contract #[ink(message)] pub fn wasmCallEvm( diff --git a/frame/hybrid-vm-port/src/tests/eip1559.rs b/frame/hybrid-vm-port/src/tests/eip1559.rs index 06f4163..e09d6df 100644 --- a/frame/hybrid-vm-port/src/tests/eip1559.rs +++ b/frame/hybrid-vm-port/src/tests/eip1559.rs @@ -714,7 +714,7 @@ fn call_hybrid_vm_works() { // 6. Ethereum call hybrid vm (wasm contract) transfer wasm token to bob let wasm_contract = ::AccountIdMapping::into_address(wasm_addr.clone()); - let transfer_selector = &Keccak256::digest(b"transfer(address,uint128)")[0..4]; + let transfer_selector = &Keccak256::digest(b"transfer(address,uint256)")[0..4]; let transfer_value: u128 = 12_000_000_000_000_000; let call_input = [ diff --git a/frame/hybrid-vm-port/src/tests/eip2930.rs b/frame/hybrid-vm-port/src/tests/eip2930.rs index a5c4320..72bc2fe 100644 --- a/frame/hybrid-vm-port/src/tests/eip2930.rs +++ b/frame/hybrid-vm-port/src/tests/eip2930.rs @@ -629,7 +629,7 @@ fn call_hybrid_vm_works() { // 6. Ethereum call hybrid vm (wasm contract) transfer wasm token to bob let wasm_contract = ::AccountIdMapping::into_address(wasm_addr.clone()); - let transfer_selector = &Keccak256::digest(b"transfer(address,uint128)")[0..4]; + let transfer_selector = &Keccak256::digest(b"transfer(address,uint256)")[0..4]; let transfer_value: u128 = 12_000_000_000_000_000; let call_input = [ diff --git a/frame/hybrid-vm-port/src/tests/legacy.rs b/frame/hybrid-vm-port/src/tests/legacy.rs index 0ef630a..1635801 100644 --- a/frame/hybrid-vm-port/src/tests/legacy.rs +++ b/frame/hybrid-vm-port/src/tests/legacy.rs @@ -625,7 +625,7 @@ fn call_hybrid_vm_works() { // 6. Ethereum call hybrid vm (wasm contract) transfer wasm token to bob let wasm_contract = ::AccountIdMapping::into_address(wasm_addr.clone()); - let transfer_selector = &Keccak256::digest(b"transfer(address,uint128)")[0..4]; + let transfer_selector = &Keccak256::digest(b"transfer(address,uint256)")[0..4]; let transfer_value: u128 = 12_000_000_000_000_000; let call_input = [ diff --git a/frame/hybrid-vm/fixtures/erc20.wasm b/frame/hybrid-vm/fixtures/erc20.wasm index 596b428940e807421b39e8d8cd19dac41094db91..532562b0d67ef322226e61f61bc1eedf9dfffe14 100644 GIT binary patch literal 20645 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 literal 19223 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 J@b7pO{(l5o_GkbA From 200a8f1bcde8c34265e496716ec0eb026739a85e Mon Sep 17 00:00:00 2001 From: wd30130 Date: Tue, 13 Aug 2024 09:52:20 +0800 Subject: [PATCH 06/12] fix(*): modify fn call_hybrid_vm using TransactionData --- frame/hybrid-vm-port/src/lib.rs | 2 +- frame/hybrid-vm-port/src/port.rs | 62 ++++++-------------------------- 2 files changed, 12 insertions(+), 52 deletions(-) diff --git a/frame/hybrid-vm-port/src/lib.rs b/frame/hybrid-vm-port/src/lib.rs index 92782d5..8292fd5 100644 --- a/frame/hybrid-vm-port/src/lib.rs +++ b/frame/hybrid-vm-port/src/lib.rs @@ -570,7 +570,7 @@ impl Pallet { transaction: Transaction, ) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> { if Self::is_hybrid_vm_transaction(transaction.clone()) { - return Self::call_hybrid_vm(source, transaction); + return Self::call_hybrid_vm(source, TransactionData::from(&transaction)); } let (to, _, info) = Self::execute(source, &transaction, None)?; diff --git a/frame/hybrid-vm-port/src/port.rs b/frame/hybrid-vm-port/src/port.rs index 1aa10e9..cd4987d 100644 --- a/frame/hybrid-vm-port/src/port.rs +++ b/frame/hybrid-vm-port/src/port.rs @@ -219,7 +219,7 @@ impl Pallet { pub fn call_hybrid_vm( source: H160, - transaction: Transaction, + t: TransactionData, ) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> { let ( input, @@ -230,56 +230,16 @@ impl Pallet { _nonce, action, _access_list, - ) = { - match transaction { - // max_fee_per_gas and max_priority_fee_per_gas in legacy and 2930 transactions is - // the provided gas_price. - Transaction::Legacy(t) => ( - t.input.clone(), - t.value, - t.gas_limit, - Some(t.gas_price), - Some(t.gas_price), - Some(t.nonce), - t.action, - Vec::new(), - ), - Transaction::EIP2930(t) => { - let access_list: Vec<(H160, Vec)> = t - .access_list - .iter() - .map(|item| (item.address, item.storage_keys.clone())) - .collect(); - ( - t.input.clone(), - t.value, - t.gas_limit, - Some(t.gas_price), - Some(t.gas_price), - Some(t.nonce), - t.action, - access_list, - ) - }, - Transaction::EIP1559(t) => { - let access_list: Vec<(H160, Vec)> = t - .access_list - .iter() - .map(|item| (item.address, item.storage_keys.clone())) - .collect(); - ( - t.input.clone(), - t.value, - t.gas_limit, - Some(t.max_fee_per_gas), - Some(t.max_priority_fee_per_gas), - Some(t.nonce), - t.action, - access_list, - ) - }, - } - }; + ) = ( + t.input, + t.value, + t.gas_limit, + t.max_fee_per_gas, + t.max_priority_fee_per_gas, + t.nonce, + t.action, + t.access_list, + ); match action { ethereum::TransactionAction::Call(target) => { From d854799e3ebe42e0c7cdd66e9a7a7bb7b0c5a70b Mon Sep 17 00:00:00 2001 From: wd30130 Date: Tue, 13 Aug 2024 15:18:15 +0800 Subject: [PATCH 07/12] fix(*): modify fn call_hybrid_vm called position --- frame/hybrid-vm-port/src/lib.rs | 7 ++++--- frame/hybrid-vm-port/src/port.rs | 8 +++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/frame/hybrid-vm-port/src/lib.rs b/frame/hybrid-vm-port/src/lib.rs index 8292fd5..0df6191 100644 --- a/frame/hybrid-vm-port/src/lib.rs +++ b/frame/hybrid-vm-port/src/lib.rs @@ -569,9 +569,6 @@ impl Pallet { source: H160, transaction: Transaction, ) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> { - if Self::is_hybrid_vm_transaction(transaction.clone()) { - return Self::call_hybrid_vm(source, TransactionData::from(&transaction)); - } let (to, _, info) = Self::execute(source, &transaction, None)?; let pending = Pending::::get(); @@ -732,6 +729,10 @@ impl Pallet { let is_transactional = true; let validate = false; + if Self::is_hybrid_vm_transaction(transaction.clone()) { + return Self::call_hybrid_vm(from, transaction_data); + } + let ( input, value, diff --git a/frame/hybrid-vm-port/src/port.rs b/frame/hybrid-vm-port/src/port.rs index cd4987d..358f221 100644 --- a/frame/hybrid-vm-port/src/port.rs +++ b/frame/hybrid-vm-port/src/port.rs @@ -220,7 +220,7 @@ impl Pallet { pub fn call_hybrid_vm( source: H160, t: TransactionData, - ) -> Result<(PostDispatchInfo, CallOrCreateInfo), DispatchErrorWithPostInfo> { + ) -> Result<(Option, Option, CallOrCreateInfo), DispatchErrorWithPostInfo> { let ( input, value, @@ -348,10 +348,8 @@ impl Pallet { logs: vec![], }; return Ok(( - PostDispatchInfo { - actual_weight: Some(info.gas_consumed), - pays_fee: Pays::Yes, - }, + Some(target), + None, CallOrCreateInfo::Call(call_info), )); } else { From 109d53d19618f31eba56318ef4c9554d339052d4 Mon Sep 17 00:00:00 2001 From: wd30130 Date: Tue, 13 Aug 2024 16:48:19 +0800 Subject: [PATCH 08/12] fix(test): add name symbol and decimals fun in wasm contract --- external/contract/src/erc20wasm/lib.rs | 20 +++++++++++++++++++- frame/hybrid-vm/fixtures/erc20.wasm | Bin 20645 -> 21236 bytes 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/external/contract/src/erc20wasm/lib.rs b/external/contract/src/erc20wasm/lib.rs index 043820b..f12736d 100644 --- a/external/contract/src/erc20wasm/lib.rs +++ b/external/contract/src/erc20wasm/lib.rs @@ -155,6 +155,9 @@ mod erc20 { #[ink(message)] pub fn hybridvm_evm_abi(&mut self) -> Vec { let mut evm_abi: Vec = vec![]; + evm_abi.push(("name()returns(string)".to_string(), "name".to_string(), None)); + evm_abi.push(("symbol()returns(string)".to_string(), "symbol".to_string(), None)); + evm_abi.push(("decimals()returns(uint8)".to_string(), "decimals".to_string(), None)); evm_abi.push(("totalSupply()returns(uint256)".to_string(), "total_supply_abi".to_string(), None)); evm_abi.push(("balanceOf(address)returns(uint256)".to_string(), "balance_of_abi".to_string(), None)); evm_abi.push(("allowance(address,address)returns(uint256)".to_string(), "allowance_abi".to_string(), None)); @@ -163,8 +166,23 @@ mod erc20 { evm_abi.push(("transferFrom(address,address,uint256)returns(bool)".to_string(), "transfer_from_abi".to_string(), None)); evm_abi - } + } + + #[ink(message)] + pub fn name(&self) -> String { + String::from("WasmTokenT") + } + + #[ink(message)] + pub fn symbol(&self) -> String { + String::from("WTT") + } + #[ink(message)] + pub fn decimals(&self) -> u8 { + 18u8 + } + /// Returns the total token supply. #[ink(message)] pub fn total_supply(&self) -> Balance { diff --git a/frame/hybrid-vm/fixtures/erc20.wasm b/frame/hybrid-vm/fixtures/erc20.wasm index 532562b0d67ef322226e61f61bc1eedf9dfffe14..c2f7835eb38988971d5ae5b8e0ff716f41ada977 100644 GIT binary patch delta 7919 zcmbtZ4RBo5b-q7uS1Y|;>1kL0^3Q!wva~Dz$+9iU!r;BKELoNfruAS#Q(~96gq1O_ ztWZ2*SUENhSf14Jb%{LzDj0h(CCt#M(|B4Zbqgg4r42AiOVdf>PMVgPc2Yu{fdbR^ zJNLa^$ve{#?Mz4sktTdKbPMLsoqp_&(x2vj{;)-eIb(jP3)iiiM{xm4ZD)!)I z_A3>w!g-eSxOu&Dqt+nSP9cbSt%_$wGKf=?7)vn~qbEnjy=IWGUa<^pWv|Ghae75N zjqCP;*;UoHq=WNf8`Iu+AljJ{iVd(DkO^H=(A?|5gI8!buT&l9gJ!4O1~8v-13ozW zqL9+ zme}#5gm!=ZS*paFYvAAc*{b* z&HR2#z;8Bx)$(!PXS!NHBTha#`%G)M&)vSPLP*WE$eQ1i0ri9B}JNJ;dfio?9yfVeSJabR-vLdZz z_0$w3C7?`;!4Y}5tRsrVj|Ea6o|>9^V8qFnp@5MzTa>#LWSSE;p@lUw9-M-wl_0O< z5fTf;OsR$Evi_ZZV{^#_03bul&}t#TeBN&;_FN&1hnisI zowNx_78a8X#PwuBlY&h0KzXlmcqlI^g_kX2y#n2^#BgMZ$gn$oMlNT)C0RBR(L3}* zngNQQ5Jco0Y|a_BmL-S25V`>P7#^%z4QLr=nTFD^I)eLo&SUe9I0z5wi#*8e2@aCt zE(dEDmv^(>)xsN`56kN@YuZMMwAj|bd(2~Pcko{G)3(*E8{DTih}vT8A%vf|<#@oL z6Q)n|Lcq<2_61y+kGE%=Im~@z`z8c67V7JSRhJUxiT2jcmniVO$6-vYf4o6h2E&U@lf;dG_KVu^k6R8I6BNAm>HWVB4y63N*z$@_C8Eucv2 zSkfbkzX8~g34x6SeGiYo$n*(b!0&s!;4M;YIXl5^uj%PnH;jo%u4yM7H)^aWnXG3KWg%UNvy_Zo8S68AGYk%TV@{YqJ%q~}Om|IEym z&dE>wzxY=slf?h2GJiak_)noLi&(>&DG@T(6W<0COmCM${QKbDz(XHF3UOslR!y{)T^y7-X>2|&{WdOx-#g0BhZ!Le_BRf zAMnucPfOcRyCLeqP5@;VkqSGyW}6*0uP*&WQQ~L|V_BA+kr+%+{E|9h9j{JF^1phr z)f1BTPLBP7B-`a^&se`aL;hBstRR#}%4&FaP7PnjV+z|#Ul3Q}ydbi6fEF+Zok&CI z3UcHLjyRk!Z!CMjDr^Q@0%oqGq0>Bs_B9bgdtHRk&d3njQxec>l5v9eMj6_RbI{%) z6;@oKLgDq2qE3@8!XuFg5IUsaiS=7#5e?3SISQ*=N@frlD`aORx3CLBc=3_ z;^vg%%!Ah4eS1$PDclIhx3PGkUn1>GZBvZ-vD+Hp1P@|ny1TytyJR_orL8;!Zm!d= zFU{X|A1K!KAt|#vU#0D%s_&C;(z#sQhZuu4(}&oC))_$TN6SeK5S^Hu2yljPoD?zIH}iS8at@Z4cX*IrFvHw$!COca!Z9FQ~% zYv+X1M>^Ks1KRr?P&cZmc^NoH9qb6I2?I(u zk%bo*io6oGgo#c1OroGsF%-ra11kVY*p_GmiJYA*9uCym7JbA(Hx-t%utv0%1?BdM zTM!h`!c7WMSp-6kgCl9n10s~Rqyr^VQKFP6jiO@nimiW6n5YYMFdzITifo$_2;Pr5WRl8 z;qt(0>#ZzZCD`+n9D>6k@Q#9#VdK$zKie;tMnlJzm?P_RBiN3g(87P4i9*j*?6cLFu5$?MRau&F1bj$xx_pwSn}gucX|C3 zo@`x3%OoX$ImzJQ7Hu$uVp>aC3o|?t15HL;TR@Le55I4+LQYtt@-W%ZuTf7i>UzWy zeRCesTa1{5X0&qOwjH4zZO41IBh)5!0K3Td$tgS_9KhOg7X;gN0<(wvt`KghS`R4; z&-RPNFQeNTZua+g;;7^lX)cjS<%%8x^cUu$*_EG&-T9m#5dt1J?8Lg3J= zRp}$!Q>+C;Uq)=}M)ay1_gs3f>jeo~xLI1&T5ef_Y?Dx_Y)&e>;jt2@d&m#oJIC*g z<%fV8@>93hK7$}Jz$nvj;q}o8Q_!7Ci~~Nl9>7^mT(rNJXi-A{F&4GZE)zn|+L7}D znqc~In_zD=m-9`m=@2U>u&{tNpgm-n}$)6Pn)VR-uC-f+8W^QcBAiJi0bRBOA&op=p zsRAmIuE>kLsz8>S!VSKX<9-e47k>`^;-js~(Z%7wZN;vMX>VJrpTaa~6QgdcpMW{| zIFyf!d))VQjn5?*5(`lTV;nT9vH(RtGRP0R+wG++I{a#L-%ZWM6jrSqnxbe$xVEdJ zl%op9$2=II0*N#tsj4pcRguwr`bGeeTqTj(s4DynBk7S z;j&3$Oh!F_THH!qMBsC)Y4AhtUM&*%2!tzf6ne)t_*;ec#}EYtEes1mStn_h2NxtT zwjB3IQ;>xVF;?(nWIp^)D_nv@d+>62BAuQpZQk9mu;}Q@F;ruMwqj0xYLNX3iVX>$ zrPo~#1{qbmgNj2^I&>jPu%xm5L7j4*e-MOqI|4^#@JFxd+hEGNJ6f@Rm#{H9U3^)B z0SFw1pt>YRk_QP5&R`0RgH>LtEC(1!%Jv|wVpd9e$MX-;G5{bDHhExZ{RByq;@9sUm}Js_Lfo) zl6(Yx9*%if0CT;YYz`VFnx*`bcIyS9KTGui?t3vscXP#ZPV625Qc1+Ct5b!?DWYjr4Z&aE_XT!yl`r zFb+S#aaVx|Y%UM~bu|bON6@W1H1`>-mjjyzzBnn#%>5J3QHLh!@^R;R7%9ajsaoW7I zWo@e+p>Fasgf)04c5jOdHfC_F6Ce5tW4`-Am89tJxF@U3V`Iy2+qe7PJ=xsEp2<&7 z>^qP>FgbD0zPoeOdEnr^zj5E*Ylgz^Pwu(vo_lxiJuo-?>3jA~_UB6dvoDUV0%gV~)Gp+`7Hl?AjhPh3$>)*emYh4#wC*{HK=w-yk{L MjsFkf|5?fZ2b}lMng9R* delta 7617 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 From 974eab5b601b4fca25ef68d0dca4a1e3c90e32a8 Mon Sep 17 00:00:00 2001 From: wd30130 Date: Thu, 15 Aug 2024 19:07:50 +0800 Subject: [PATCH 09/12] feat(*): add OutOfGas processing --- frame/hybrid-vm-port/Cargo.toml | 5 ++- frame/hybrid-vm-port/src/port.rs | 76 +++++++++++++++++++++++--------- 2 files changed, 58 insertions(+), 23 deletions(-) diff --git a/frame/hybrid-vm-port/Cargo.toml b/frame/hybrid-vm-port/Cargo.toml index c5efe2a..978bf4f 100644 --- a/frame/hybrid-vm-port/Cargo.toml +++ b/frame/hybrid-vm-port/Cargo.toml @@ -29,8 +29,7 @@ fp-rpc = { workspace = true } fp-storage = { workspace = true } pallet-evm = { workspace = true } precompile-utils = { workspace = true } -# ink! -ink_env = { workspace = true, features = ["no-panic-handler"] } + #local pallet-hybrid-vm = { workspace = true, default-features = false } hp-system = { workspace = true, default-features = false } @@ -49,6 +48,8 @@ sp-core = { workspace = true, features = ["default"] } sp-std = { workspace = true, features = ["default"] } # Frontier fp-self-contained = { workspace = true, features = ["default"] } +# ink! +ink_env = { workspace = true, features = ["no-panic-handler"] } [features] default = ["std"] diff --git a/frame/hybrid-vm-port/src/port.rs b/frame/hybrid-vm-port/src/port.rs index 358f221..8235dcd 100644 --- a/frame/hybrid-vm-port/src/port.rs +++ b/frame/hybrid-vm-port/src/port.rs @@ -18,7 +18,7 @@ use super::*; use fp_evm::{CallInfo, ExitSucceed, UsedGas}; use hp_system::{AccountIdMapping, U256BalanceMapping}; use pallet_contracts::{CollectEvents, DebugInfo, Determinism}; -use pallet_evm::AddressMapping; +use pallet_evm::{AddressMapping, ExitError}; use pallet_hybrid_vm::UnifiedAddress; use precompile_utils::{ prelude::*, @@ -220,6 +220,38 @@ impl Pallet { pub fn call_hybrid_vm( source: H160, t: TransactionData, + ) -> Result<(Option, Option, CallOrCreateInfo), DispatchErrorWithPostInfo> { + let to = match t.action { + ethereum::TransactionAction::Call(target) => Some(target), + _ => None, + }; + let base_weight = Weight::from_parts(10_000, 0); + + Ok(Self::exec_hybrid_vm(source, t).unwrap_or_else(|e| { + let used_gas = U256::from(::GasWeightMapping::weight_to_gas( + e.post_info.actual_weight.unwrap_or(base_weight), + )); + let error_str: &'static str = e.error.into(); + let reason = match e.error { + t if t == DispatchError::from(pallet_contracts::Error::::OutOfGas) => { + ExitReason::Error(ExitError::OutOfGas) + }, + _ => ExitReason::Error(ExitError::Other(std::borrow::Cow::Borrowed(error_str))), + }; + let call_info = CallInfo { + exit_reason: reason, + value: vec![], + used_gas: UsedGas { standard: used_gas, effective: used_gas }, + weight_info: None, + logs: vec![], + }; + (to, None, fp_evm::CallOrCreateInfo::Call(call_info)) + })) + } + + pub fn exec_hybrid_vm( + source: H160, + t: TransactionData, ) -> Result<(Option, Option, CallOrCreateInfo), DispatchErrorWithPostInfo> { let ( input, @@ -241,6 +273,8 @@ impl Pallet { t.access_list, ); + let base_weight = Some(Weight::from_parts(10_000, 0)); + match action { ethereum::TransactionAction::Call(target) => { let vm_target = pallet_hybrid_vm::Pallet::::hvm_contracts(target); @@ -257,7 +291,7 @@ impl Pallet { let abi = pallet_hybrid_vm::Pallet::::evm_fun_abi(target, selector) .ok_or(DispatchErrorWithPostInfo { post_info: PostDispatchInfo { - actual_weight: None, + actual_weight: base_weight, pays_fee: Pays::Yes, }, error: DispatchError::from("No abi of the selector(REVERT)"), @@ -265,7 +299,7 @@ impl Pallet { let err = DispatchErrorWithPostInfo { post_info: PostDispatchInfo { - actual_weight: None, + actual_weight: base_weight, pays_fee: Pays::Yes, }, error: DispatchError::from("Fun abi error(REVERT)"), @@ -295,7 +329,7 @@ impl Pallet { Err(_) => { return Err(DispatchErrorWithPostInfo { post_info: PostDispatchInfo { - actual_weight: None, + actual_weight: base_weight, pays_fee: Pays::Yes, }, error: DispatchError::from( @@ -332,21 +366,21 @@ impl Pallet { let output = Self::convert_wasm_return(return_value.data, output_type) .map_err(|_| err_data)?; - + let used_gas = U256::from( + ::GasWeightMapping::weight_to_gas( + info.gas_consumed, + ), + ); let call_info = CallInfo { - exit_reason: ExitReason::Succeed(ExitSucceed::Returned), - value: output, - used_gas: UsedGas { - standard: U256::from( - ::GasWeightMapping::weight_to_gas( - info.gas_consumed, - ), - ), - effective: U256::from(0u64), - }, - weight_info: None, - logs: vec![], - }; + exit_reason: ExitReason::Succeed(ExitSucceed::Returned), + value: output, + used_gas: UsedGas { + standard: used_gas, + effective: used_gas, + }, + weight_info: None, + logs: vec![], + }; return Ok(( Some(target), None, @@ -372,7 +406,7 @@ impl Pallet { Err(e) => { return Err(DispatchErrorWithPostInfo { post_info: PostDispatchInfo { - actual_weight: None, + actual_weight: base_weight, pays_fee: Pays::Yes, }, error: e, @@ -383,7 +417,7 @@ impl Pallet { None => { return Err(DispatchErrorWithPostInfo { post_info: PostDispatchInfo { - actual_weight: None, + actual_weight: base_weight, pays_fee: Pays::Yes, }, error: DispatchError::from("Not HybridVM Contract(REVERT)"), @@ -393,7 +427,7 @@ impl Pallet { }, _ => { return Err(DispatchErrorWithPostInfo { - post_info: PostDispatchInfo { actual_weight: None, pays_fee: Pays::Yes }, + post_info: PostDispatchInfo { actual_weight: base_weight, pays_fee: Pays::Yes }, error: DispatchError::from("Not HybridVM Contract Call(REVERT)"), }); }, From 7ccd723106dce3b9df70561ad933aa5c22c3c0b2 Mon Sep 17 00:00:00 2001 From: wd30130 Date: Thu, 15 Aug 2024 22:32:05 +0800 Subject: [PATCH 10/12] fix(*): modify Pays value for Hybrid VM --- frame/hybrid-vm-port/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/frame/hybrid-vm-port/src/lib.rs b/frame/hybrid-vm-port/src/lib.rs index 0df6191..3e050cd 100644 --- a/frame/hybrid-vm-port/src/lib.rs +++ b/frame/hybrid-vm-port/src/lib.rs @@ -680,6 +680,11 @@ impl Pallet { } }; + let pay = match Self::is_hybrid_vm_transaction(transaction.clone()) { + true => Pays::Yes, + _ => Pays::No, + }; + Pending::::append((transaction, status, receipt)); Self::deposit_event(Event::Executed { @@ -707,7 +712,7 @@ impl Pallet { } Some(gas_to_weight) }, - pays_fee: Pays::No, + pays_fee: pay, }, info, )) From 4763e69d8cc25c74d4c77bec11e4db8a5f778ebb Mon Sep 17 00:00:00 2001 From: wd30130 Date: Fri, 16 Aug 2024 13:43:26 +0800 Subject: [PATCH 11/12] feat(*): add gas processing in vm intercall --- .../evm-precompile/call-hybrid-vm/src/lib.rs | 10 +++++-- frame/hybrid-vm-port/src/mock.rs | 10 ------- frame/hybrid-vm/src/interoperate/mod.rs | 30 +++++++++++-------- frame/hybrid-vm/src/lib.rs | 6 ---- frame/hybrid-vm/src/mock.rs | 10 ------- 5 files changed, 26 insertions(+), 40 deletions(-) diff --git a/frame/evm-precompile/call-hybrid-vm/src/lib.rs b/frame/evm-precompile/call-hybrid-vm/src/lib.rs index 0707146..65b794e 100644 --- a/frame/evm-precompile/call-hybrid-vm/src/lib.rs +++ b/frame/evm-precompile/call-hybrid-vm/src/lib.rs @@ -22,7 +22,7 @@ use fp_evm::{ }; use frame_system::RawOrigin; use hp_system::EvmHybridVMExtension; -use pallet_evm::AddressMapping; +use pallet_evm::{AddressMapping, GasWeightMapping}; pub struct CallHybridVM { _marker: PhantomData, @@ -39,7 +39,13 @@ where match T::call_hybrid_vm(origin.into(), handle.input().iter().cloned().collect(), target_gas) { - Ok(ret) => Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, output: ret.0 }), + Ok(ret) => { + let gas_consume = ret.1; + let gas_limit = target_gas.unwrap_or(0); + let gas_record = if gas_consume > gas_limit { gas_limit } else { gas_consume }; + handle.record_cost(gas_record)?; + Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, output: ret.0 }) + }, Err(e) => { let err_str: &'static str = e.into(); diff --git a/frame/hybrid-vm-port/src/mock.rs b/frame/hybrid-vm-port/src/mock.rs index 5f68459..841a2cc 100644 --- a/frame/hybrid-vm-port/src/mock.rs +++ b/frame/hybrid-vm-port/src/mock.rs @@ -335,17 +335,9 @@ impl pallet_contracts::Config for Test { type Xcm = (); } -pub struct GasPrice; -impl Get> for GasPrice { - fn get() -> Option { - Some(U256::from(100_000_000_000u64)) - } -} - parameter_types! { pub const EnableCallEVM: bool = true; pub const EnableCallWasmVM: bool = true; - pub const GasLimit: u64 = 10_000_000u64; } impl U256BalanceMapping for Test { @@ -371,8 +363,6 @@ impl pallet_hybrid_vm::Config for Test { type AccountIdMapping = Self; type EnableCallEVM = EnableCallEVM; type EnableCallWasmVM = EnableCallWasmVM; - type GasLimit = GasLimit; - type GasPrice = GasPrice; } parameter_types! { diff --git a/frame/hybrid-vm/src/interoperate/mod.rs b/frame/hybrid-vm/src/interoperate/mod.rs index 44ffa94..bbe40a0 100644 --- a/frame/hybrid-vm/src/interoperate/mod.rs +++ b/frame/hybrid-vm/src/interoperate/mod.rs @@ -38,8 +38,8 @@ use sp_runtime::{ use serde::{Deserialize, Serialize}; -use fp_evm::ExecutionInfoV2; -use pallet_evm::Runner; +use fp_evm::{ExecutionInfoV2, FeeCalculator}; +use pallet_evm::{GasWeightMapping, Runner}; use super::*; use frame_support::pallet_prelude::*; @@ -142,6 +142,9 @@ impl InterCall { return Err(DispatchError::from("EnableCallEVM is false, can't call evm.")); } + let gas_meter = env.ext().gas_meter(); + let gas_limit = + ::GasWeightMapping::weight_to_gas(gas_meter.gas_left()); let caller = env.ext().caller(); let source = C::AccountIdMapping::into_address(caller.account_id()?.clone()); @@ -158,13 +161,14 @@ impl InterCall { }, } + let gas_price = ::FeeCalculator::min_gas_price(); let info = ::Runner::call( source, target, input, U256::default(), - C::GasLimit::get(), - C::GasPrice::get(), + gas_limit, + Some(gas_price.0), None, Some(pallet_evm::Pallet::::account_basic(&source).0.nonce), Vec::new(), @@ -177,14 +181,16 @@ impl InterCall { let output: ResultBox>; match info { - Ok(r) => match r { - ExecutionInfoV2 { exit_reason: success, value: v1, .. } => { - if success.is_succeed() { - output = vm_codec::evm_decode(&input0, &v1, true, ""); - } else { - return Err(DispatchError::from("Call EVM failed ")); - } - }, + Ok(r) => { + match r { + ExecutionInfoV2 { exit_reason: success, value: v1, .. } => { + if success.is_succeed() { + output = vm_codec::evm_decode(&input0, &v1, true, ""); + } else { + return Err(DispatchError::from("Call EVM failed ")); + } + }, + }; }, Err(e) => { return Err(DispatchError::from(e.error.into())); diff --git a/frame/hybrid-vm/src/lib.rs b/frame/hybrid-vm/src/lib.rs index 482f822..8135129 100644 --- a/frame/hybrid-vm/src/lib.rs +++ b/frame/hybrid-vm/src/lib.rs @@ -83,12 +83,6 @@ pub mod pallet { #[pallet::constant] type EnableCallWasmVM: Get; - - #[pallet::constant] - type GasLimit: Get; - - #[pallet::constant] - type GasPrice: Get>; } #[pallet::pallet] diff --git a/frame/hybrid-vm/src/mock.rs b/frame/hybrid-vm/src/mock.rs index d18e0b7..1e393c5 100644 --- a/frame/hybrid-vm/src/mock.rs +++ b/frame/hybrid-vm/src/mock.rs @@ -385,17 +385,9 @@ impl pallet_contracts::Config for Test { type Xcm = (); } -pub struct GasPrice; -impl Get> for GasPrice { - fn get() -> Option { - Some(U256::from(100_000_000_000u64)) - } -} - parameter_types! { pub const EnableCallEVM: bool = true; pub const EnableCallWasmVM: bool = true; - pub const GasLimit: u64 = 10_000_000u64; } impl U256BalanceMapping for Test { @@ -421,8 +413,6 @@ impl pallet_hybrid_vm::Config for Test { type AccountIdMapping = Self; type EnableCallEVM = EnableCallEVM; type EnableCallWasmVM = EnableCallWasmVM; - type GasLimit = GasLimit; - type GasPrice = GasPrice; } const A: [u8; 32] = [ From ecb94f8a44bad7b20a9447678d66c0b7ea7c2d29 Mon Sep 17 00:00:00 2001 From: wd30130 Date: Tue, 20 Aug 2024 12:31:07 +0800 Subject: [PATCH 12/12] feat(*): add custum errors define --- frame/hybrid-vm/src/interoperate/mod.rs | 22 +++++++++++----------- frame/hybrid-vm/src/lib.rs | 8 ++++++++ 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/frame/hybrid-vm/src/interoperate/mod.rs b/frame/hybrid-vm/src/interoperate/mod.rs index bbe40a0..9cdb105 100644 --- a/frame/hybrid-vm/src/interoperate/mod.rs +++ b/frame/hybrid-vm/src/interoperate/mod.rs @@ -82,7 +82,7 @@ impl InterCall { target_gas: Weight, ) -> Result<(Vec, Weight)> { if !T::EnableCallWasmVM::get() { - return Err(DispatchError::from("EnableCallWasmVM is false, can't call wasm VM.")); + return Err(DispatchError::from(Error::::DisableCallWasmVM)); } let input: Vec; @@ -90,14 +90,14 @@ impl InterCall { match vm_codec::wasm_encode(&data[32..].iter().cloned().collect()) { Ok(r) => (input, target) = r, - Err(e) => return Err(DispatchError::from(str2s(e.to_string()))), + Err(_) => return Err(DispatchError::from(Error::::WasmEncodeError)), } let gas_limit: Weight = target_gas; let origin = ensure_signed(origin)?; let target = ::AccountId::decode(&mut target.as_slice()) - .map_err(|e| DispatchError::from(str2s(e.to_string())))?; + .map_err(|_| DispatchError::from(Error::::AccountIdDecodeError))?; let info = pallet_contracts::Pallet::::bare_call( origin, @@ -123,7 +123,7 @@ impl InterCall { "", ); } else { - return Err(DispatchError::from("Call wasm contract failed(REVERT)")); + return Err(DispatchError::from(Error::::WasmContractRevert)); } }, Err(e) => return Err(e), @@ -131,7 +131,7 @@ impl InterCall { match output { Ok(r) => return Ok((r, info.gas_consumed)), - Err(e) => return Err(DispatchError::from(str2s(e.to_string()))), + Err(_) => return Err(DispatchError::from(Error::::WasmDecodeError)), } } } @@ -139,7 +139,7 @@ impl InterCall { impl InterCall { pub fn call_evm>(mut env: Environment) -> Result { if !C::EnableCallEVM::get() { - return Err(DispatchError::from("EnableCallEVM is false, can't call evm.")); + return Err(DispatchError::from(Error::::DisableCallEvm)); } let gas_meter = env.ext().gas_meter(); @@ -156,8 +156,8 @@ impl InterCall { match vm_codec::evm_encode(&input0) { Ok(r) => (input, target) = r, - Err(e) => { - return Err(DispatchError::from(str2s(e.to_string()))); + Err(_) => { + return Err(DispatchError::from(Error::::EvmEncodeError)); }, } @@ -187,7 +187,7 @@ impl InterCall { if success.is_succeed() { output = vm_codec::evm_decode(&input0, &v1, true, ""); } else { - return Err(DispatchError::from("Call EVM failed ")); + return Err(DispatchError::from(Error::::EVMExecuteFailed)); } }, }; @@ -201,13 +201,13 @@ impl InterCall { Ok(r) => { let output = envbuf .write(&r, false, None) - .map_err(|_| DispatchError::from("ChainExtension failed to write result")); + .map_err(|_| DispatchError::from(Error::::ChainExtensionWriteError)); match output { Ok(_) => return Ok(RetVal::Converging(0)), Err(e) => return Err(e), } }, - Err(e) => return Err(DispatchError::from(str2s(e.to_string()))), + Err(_) => return Err(DispatchError::from(Error::::EvmDecodeError)), } } } diff --git a/frame/hybrid-vm/src/lib.rs b/frame/hybrid-vm/src/lib.rs index 8135129..684a279 100644 --- a/frame/hybrid-vm/src/lib.rs +++ b/frame/hybrid-vm/src/lib.rs @@ -119,6 +119,14 @@ pub mod pallet { EvmABIDecodeError, EvmABIError, WasmContractRevert, + DisableCallWasmVM, + DisableCallEvm, + AccountIdDecodeError, + WasmEncodeError, + WasmDecodeError, + EvmEncodeError, + EvmDecodeError, + ChainExtensionWriteError, } #[pallet::hooks]