From 8a0bc02ab49e3ef513c1f5f7dc98fd8d1fc83805 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Tue, 1 Aug 2023 11:11:24 +0200 Subject: [PATCH 01/36] create mock and testing --- runtime/src/precompiles/mock.rs | 153 ++++++++++++++++++ .../{precompiles.rs => precompiles/mod.rs} | 6 + runtime/src/precompiles/test.rs | 8 + 3 files changed, 167 insertions(+) create mode 100644 runtime/src/precompiles/mock.rs rename runtime/src/{precompiles.rs => precompiles/mod.rs} (97%) create mode 100644 runtime/src/precompiles/test.rs diff --git a/runtime/src/precompiles/mock.rs b/runtime/src/precompiles/mock.rs new file mode 100644 index 00000000..8f4c28e1 --- /dev/null +++ b/runtime/src/precompiles/mock.rs @@ -0,0 +1,153 @@ +use frame_support::{ + construct_runtime, parameter_types, sp_io, + traits::{ConstU64, FindAuthor}, + weights::Weight, +}; +use pallet_evm::{Config, EnsureAddressNever, EnsureAddressRoot, FeeCalculator, FixedGasWeightMapping, IdentityAddressMapping, SubstrateBlockHashMapping, runner}; +use sp_core::{H160, H256, U256}; +use sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, IdentityLookup}, ConsensusEngineId, +}; +use sp_std::{boxed::Box, prelude::*, str::FromStr}; + +use super::FrontierPrecompiles; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +// Configure a mock runtime to test the pallet. +construct_runtime!( + pub enum Runtime where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system, + Balances: pallet_balances, + Timestamp: pallet_timestamp, + LivingassetsOwnership: pallet_living_assets_ownership, + EVM: pallet_evm, + } +); + +impl frame_system::Config for Runtime { + type BaseCallFilter = frame_support::traits::Everything; + type BlockWeights = (); + type BlockLength = (); + type DbWeight = (); + type RuntimeOrigin = RuntimeOrigin; + type RuntimeCall = RuntimeCall; + type Index = u64; + type BlockNumber = u64; + type Hash = H256; + type Hashing = BlakeTwo256; + type AccountId = H160; + type Lookup = IdentityLookup; + type Header = Header; + type RuntimeEvent = RuntimeEvent; + type BlockHashCount = ConstU64<250>; + type Version = (); + type PalletInfo = PalletInfo; + type AccountData = pallet_balances::AccountData; + type OnNewAccount = (); + type OnKilledAccount = (); + type SystemWeightInfo = (); + type SS58Prefix = (); + type OnSetCode = (); + type MaxConsumers = frame_support::traits::ConstU32<16>; +} + +parameter_types! { + pub const ExistentialDeposit: u64 = 1; +} + +impl pallet_balances::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type WeightInfo = (); + type Balance = u64; + type DustRemoval = (); + type ExistentialDeposit = ExistentialDeposit; + type AccountStore = System; + type ReserveIdentifier = (); + type HoldIdentifier = (); + type FreezeIdentifier = (); + type MaxLocks = (); + type MaxReserves = (); + type MaxHolds = (); + type MaxFreezes = (); +} + +parameter_types! { + pub const MinimumPeriod: u64 = 1000; +} + +impl pallet_timestamp::Config for Runtime { + type Moment = u64; + type OnTimestampSet = (); + type MinimumPeriod = MinimumPeriod; + type WeightInfo = (); +} + +impl pallet_living_assets_ownership::Config for Runtime { + type RuntimeEvent = RuntimeEvent; + type CollectionId = u64; +} + +pub struct FixedGasPrice; +impl FeeCalculator for FixedGasPrice { + fn min_gas_price() -> (U256, Weight) { + // Return some meaningful gas price and weight + (1_000_000_000u128.into(), Weight::from_parts(7u64, 0)) + } +} +pub struct FindAuthorTruncated; +impl FindAuthor for FindAuthorTruncated { + fn find_author<'a, I>(_digests: I) -> Option + where + I: 'a + IntoIterator, + { + Some(H160::from_str("1234500000000000000000000000000000000000").unwrap()) + } +} + +const BLOCK_GAS_LIMIT: u64 = 150_000_000; +const MAX_POV_SIZE: u64 = 5 * 1024 * 1024; + +parameter_types! { + pub BlockGasLimit: U256 = U256::from(BLOCK_GAS_LIMIT); + pub const GasLimitPovSizeRatio: u64 = BLOCK_GAS_LIMIT.saturating_div(MAX_POV_SIZE); + pub WeightPerGas: Weight = Weight::from_parts(20_000, 0); + pub PrecompilesValue: FrontierPrecompiles = FrontierPrecompiles::<_>::new(); +} + +impl pallet_evm::Config for Runtime { + type FeeCalculator = FixedGasPrice; + type GasWeightMapping = FixedGasWeightMapping; + type WeightPerGas = WeightPerGas; + type BlockHashMapping = SubstrateBlockHashMapping; + type CallOrigin = EnsureAddressRoot; + type WithdrawOrigin = EnsureAddressNever; + type AddressMapping = IdentityAddressMapping; + type Currency = Balances; + type RuntimeEvent = RuntimeEvent; + type PrecompilesType = FrontierPrecompiles; + type PrecompilesValue = PrecompilesValue; + type ChainId = (); + type BlockGasLimit = BlockGasLimit; + type Runner = runner::stack::Runner; + type OnChargeTransaction = (); + type OnCreate = (); + type FindAuthor = FindAuthorTruncated; + type GasLimitPovSizeRatio = GasLimitPovSizeRatio; + type Timestamp = Timestamp; + type WeightInfo = (); +} + +// Build genesis storage according to the mock runtime. +pub fn new_test_ext() -> sp_io::TestExternalities { + frame_system::GenesisConfig::default() + .build_storage::() + .unwrap() + .into() +} diff --git a/runtime/src/precompiles.rs b/runtime/src/precompiles/mod.rs similarity index 97% rename from runtime/src/precompiles.rs rename to runtime/src/precompiles/mod.rs index 8aaa6e01..41683254 100644 --- a/runtime/src/precompiles.rs +++ b/runtime/src/precompiles/mod.rs @@ -65,3 +65,9 @@ where fn hash(a: u64) -> H160 { H160::from_low_u64_be(a) } + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod test; diff --git a/runtime/src/precompiles/test.rs b/runtime/src/precompiles/test.rs new file mode 100644 index 00000000..1ee73185 --- /dev/null +++ b/runtime/src/precompiles/test.rs @@ -0,0 +1,8 @@ +use super::mock::*; + +#[test] +fn check_precompiled() { + new_test_ext().execute_with(|| { + // PrecompilesValue::is_precompile(hash(1), 0); + }) +} From 0fe9a63087649c5d5edb224e5c3cda449ce992fc Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Tue, 1 Aug 2023 11:40:49 +0200 Subject: [PATCH 02/36] first test --- runtime/src/precompiles/mock.rs | 14 +++++++++----- runtime/src/precompiles/test.rs | 14 +++++++++++--- 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/runtime/src/precompiles/mock.rs b/runtime/src/precompiles/mock.rs index 8f4c28e1..7535a986 100644 --- a/runtime/src/precompiles/mock.rs +++ b/runtime/src/precompiles/mock.rs @@ -3,11 +3,15 @@ use frame_support::{ traits::{ConstU64, FindAuthor}, weights::Weight, }; -use pallet_evm::{Config, EnsureAddressNever, EnsureAddressRoot, FeeCalculator, FixedGasWeightMapping, IdentityAddressMapping, SubstrateBlockHashMapping, runner}; +use pallet_evm::{ + runner, EnsureAddressNever, EnsureAddressRoot, FeeCalculator, FixedGasWeightMapping, + IdentityAddressMapping, SubstrateBlockHashMapping, +}; use sp_core::{H160, H256, U256}; use sp_runtime::{ testing::Header, - traits::{BlakeTwo256, IdentityLookup}, ConsensusEngineId, + traits::{BlakeTwo256, IdentityLookup}, + ConsensusEngineId, }; use sp_std::{boxed::Box, prelude::*, str::FromStr}; @@ -26,7 +30,7 @@ construct_runtime!( System: frame_system, Balances: pallet_balances, Timestamp: pallet_timestamp, - LivingassetsOwnership: pallet_living_assets_ownership, + LivingassetsOwnership: pallet_living_assets_ownership, EVM: pallet_evm, } ); @@ -90,8 +94,8 @@ impl pallet_timestamp::Config for Runtime { } impl pallet_living_assets_ownership::Config for Runtime { - type RuntimeEvent = RuntimeEvent; - type CollectionId = u64; + type RuntimeEvent = RuntimeEvent; + type CollectionId = u64; } pub struct FixedGasPrice; diff --git a/runtime/src/precompiles/test.rs b/runtime/src/precompiles/test.rs index 1ee73185..ade8b072 100644 --- a/runtime/src/precompiles/test.rs +++ b/runtime/src/precompiles/test.rs @@ -1,8 +1,16 @@ -use super::mock::*; +use super::{hash, mock::*, FrontierPrecompiles}; +use pallet_evm::{IsPrecompileResult, PrecompileSet}; #[test] fn check_precompiled() { new_test_ext().execute_with(|| { - // PrecompilesValue::is_precompile(hash(1), 0); - }) + let p = FrontierPrecompiles::::new(); + let result = p.is_precompile(hash(4), 0); + if let IsPrecompileResult::Answer { is_precompile, extra_cost } = result { + assert_eq!(is_precompile, true); + assert_eq!(extra_cost, 0); + } else { + panic!("Unexpected result variant"); + } + }) } From 7ebabef2ec68f5360d561c0d48b3b164a4f399ef Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Tue, 1 Aug 2023 11:52:51 +0200 Subject: [PATCH 03/36] testing ethereum reserved addresses --- runtime/src/precompiles/mock.rs | 10 +--------- runtime/src/precompiles/test.rs | 33 ++++++++++++++++++++++----------- 2 files changed, 23 insertions(+), 20 deletions(-) diff --git a/runtime/src/precompiles/mock.rs b/runtime/src/precompiles/mock.rs index 7535a986..d8b58b46 100644 --- a/runtime/src/precompiles/mock.rs +++ b/runtime/src/precompiles/mock.rs @@ -1,5 +1,5 @@ use frame_support::{ - construct_runtime, parameter_types, sp_io, + construct_runtime, parameter_types, traits::{ConstU64, FindAuthor}, weights::Weight, }; @@ -147,11 +147,3 @@ impl pallet_evm::Config for Runtime { type Timestamp = Timestamp; type WeightInfo = (); } - -// Build genesis storage according to the mock runtime. -pub fn new_test_ext() -> sp_io::TestExternalities { - frame_system::GenesisConfig::default() - .build_storage::() - .unwrap() - .into() -} diff --git a/runtime/src/precompiles/test.rs b/runtime/src/precompiles/test.rs index ade8b072..17489f1e 100644 --- a/runtime/src/precompiles/test.rs +++ b/runtime/src/precompiles/test.rs @@ -1,16 +1,27 @@ use super::{hash, mock::*, FrontierPrecompiles}; use pallet_evm::{IsPrecompileResult, PrecompileSet}; +use sp_core::H160; + +fn is_precompile(address: H160) -> bool { + let p = FrontierPrecompiles::::new(); + let result = p.is_precompile(address, 0); + if let IsPrecompileResult::Answer { is_precompile, extra_cost } = result { + is_precompile + } else { + panic!("Unexpected result variant"); + } +} + +#[test] +fn null_address_is_not_precompile() { + assert!(!is_precompile(H160::zero())); +} #[test] -fn check_precompiled() { - new_test_ext().execute_with(|| { - let p = FrontierPrecompiles::::new(); - let result = p.is_precompile(hash(4), 0); - if let IsPrecompileResult::Answer { is_precompile, extra_cost } = result { - assert_eq!(is_precompile, true); - assert_eq!(extra_cost, 0); - } else { - panic!("Unexpected result variant"); - } - }) +fn ethrerum_precompiled_reserved_addresses_are_precompiled() { + assert!(is_precompile(hash(1))); + assert!(is_precompile(hash(2))); + assert!(is_precompile(hash(3))); + assert!(is_precompile(hash(4))); + assert!(is_precompile(hash(5))); } From e964668a1a6122e9c36e7b2578cd6b4b952e4a8e Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Tue, 1 Aug 2023 11:55:24 +0200 Subject: [PATCH 04/36] refactoring --- runtime/src/precompiles/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/precompiles/test.rs b/runtime/src/precompiles/test.rs index 17489f1e..291ae043 100644 --- a/runtime/src/precompiles/test.rs +++ b/runtime/src/precompiles/test.rs @@ -5,7 +5,7 @@ use sp_core::H160; fn is_precompile(address: H160) -> bool { let p = FrontierPrecompiles::::new(); let result = p.is_precompile(address, 0); - if let IsPrecompileResult::Answer { is_precompile, extra_cost } = result { + if let IsPrecompileResult::Answer { is_precompile, extra_cost: _ } = result { is_precompile } else { panic!("Unexpected result variant"); From aba874eed23e098d8d513657bf80e3fc49295226 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Tue, 1 Aug 2023 11:57:47 +0200 Subject: [PATCH 05/36] refactoring --- runtime/src/precompiles/test.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/runtime/src/precompiles/test.rs b/runtime/src/precompiles/test.rs index 291ae043..943bde3f 100644 --- a/runtime/src/precompiles/test.rs +++ b/runtime/src/precompiles/test.rs @@ -2,26 +2,24 @@ use super::{hash, mock::*, FrontierPrecompiles}; use pallet_evm::{IsPrecompileResult, PrecompileSet}; use sp_core::H160; -fn is_precompile(address: H160) -> bool { +fn is_precompile(address: H160) -> Result { let p = FrontierPrecompiles::::new(); - let result = p.is_precompile(address, 0); - if let IsPrecompileResult::Answer { is_precompile, extra_cost: _ } = result { - is_precompile - } else { - panic!("Unexpected result variant"); + match p.is_precompile(address, 0) { + IsPrecompileResult::Answer { is_precompile, extra_cost: _ } => Ok(is_precompile), + _ => Err("Unexpected result variant"), } } #[test] fn null_address_is_not_precompile() { - assert!(!is_precompile(H160::zero())); + assert!(!is_precompile(H160::zero()).unwrap()); } #[test] fn ethrerum_precompiled_reserved_addresses_are_precompiled() { - assert!(is_precompile(hash(1))); - assert!(is_precompile(hash(2))); - assert!(is_precompile(hash(3))); - assert!(is_precompile(hash(4))); - assert!(is_precompile(hash(5))); + assert!(is_precompile(hash(1)).unwrap()); + assert!(is_precompile(hash(2)).unwrap()); + assert!(is_precompile(hash(3)).unwrap()); + assert!(is_precompile(hash(4)).unwrap()); + assert!(is_precompile(hash(5)).unwrap()); } From 80dd172dc442ab0601936be535679dee4b93bcba Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Tue, 1 Aug 2023 11:59:34 +0200 Subject: [PATCH 06/36] refactoring tests --- runtime/src/precompiles/test.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/runtime/src/precompiles/test.rs b/runtime/src/precompiles/test.rs index 943bde3f..9df6d657 100644 --- a/runtime/src/precompiles/test.rs +++ b/runtime/src/precompiles/test.rs @@ -16,7 +16,7 @@ fn null_address_is_not_precompile() { } #[test] -fn ethrerum_precompiled_reserved_addresses_are_precompiled() { +fn ethereum_precompiled_addresses_are_precompile() { assert!(is_precompile(hash(1)).unwrap()); assert!(is_precompile(hash(2)).unwrap()); assert!(is_precompile(hash(3)).unwrap()); From 9604f6c92d88bcec583db83e7929f5993c46362f Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Tue, 1 Aug 2023 12:42:20 +0200 Subject: [PATCH 07/36] fmt --- runtime/src/precompiles/test.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/runtime/src/precompiles/test.rs b/runtime/src/precompiles/test.rs index 9df6d657..f9c475da 100644 --- a/runtime/src/precompiles/test.rs +++ b/runtime/src/precompiles/test.rs @@ -12,14 +12,14 @@ fn is_precompile(address: H160) -> Result { #[test] fn null_address_is_not_precompile() { - assert!(!is_precompile(H160::zero()).unwrap()); + assert!(!is_precompile(H160::zero()).unwrap()); } #[test] fn ethereum_precompiled_addresses_are_precompile() { - assert!(is_precompile(hash(1)).unwrap()); - assert!(is_precompile(hash(2)).unwrap()); - assert!(is_precompile(hash(3)).unwrap()); - assert!(is_precompile(hash(4)).unwrap()); - assert!(is_precompile(hash(5)).unwrap()); + assert!(is_precompile(hash(1)).unwrap()); + assert!(is_precompile(hash(2)).unwrap()); + assert!(is_precompile(hash(3)).unwrap()); + assert!(is_precompile(hash(4)).unwrap()); + assert!(is_precompile(hash(5)).unwrap()); } From 390359baf2eaa196071c84bcbbb0870412cd0465 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Thu, 3 Aug 2023 18:02:43 +0200 Subject: [PATCH 08/36] erc721 starting point --- Cargo.lock | 22 ++++++++++ precompile/erc721/Cargo.toml | 55 +++++++++++++++++++++++++ precompile/erc721/contracts/IERC721.sol | 10 +++++ precompile/erc721/src/lib.rs | 49 ++++++++++++++++++++++ 4 files changed, 136 insertions(+) create mode 100644 precompile/erc721/Cargo.toml create mode 100644 precompile/erc721/contracts/IERC721.sol create mode 100644 precompile/erc721/src/lib.rs diff --git a/Cargo.lock b/Cargo.lock index afac0916..5c5dec34 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8914,6 +8914,28 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" +[[package]] +name = "precompile-erc721" +version = "0.0.1" +dependencies = [ + "evm", + "fp-evm", + "frame-support", + "hex", + "num_enum 0.5.11", + "pallet-evm", + "pallet-evm-test-vector-support", + "pallet-living-assets-ownership", + "parity-scale-codec", + "precompile-utils", + "precompile-utils-macro", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "precompile-utils" version = "0.4.3" diff --git a/precompile/erc721/Cargo.toml b/precompile/erc721/Cargo.toml new file mode 100644 index 00000000..f5d53602 --- /dev/null +++ b/precompile/erc721/Cargo.toml @@ -0,0 +1,55 @@ +[package] +name = "precompile-erc721" +version = "0.0.1" +edition = "2021" + +[dependencies] +parity-scale-codec = { workspace = true, features = [ + "derive", +] } +scale-info = { workspace = true, features = [ + "derive", +] } + +# Frontier +fp-evm = { workspace = true } +pallet-evm = { workspace = true } + +# Substrate +frame-support = { workspace = true } +sp-arithmetic = { workspace = true } +sp-core = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } + +# Local pallet +pallet-living-assets-ownership = { workspace = true } + +# Utils +precompile-utils = { workspace = true } +precompile-utils-macro = { workspace = true } + +num_enum = { workspace = true } + +[dev-dependencies] +pallet-evm-test-vector-support = { workspace = true } +evm = { workspace = true } +hex = { version = "0.4.3" } + +[features] +default = ["std"] +std = [ + # Frontier + "fp-evm/std", + "pallet-evm/std", + "sp-core/std", + "sp-runtime/std", + "sp-std/std", + "pallet-living-assets-ownership/std", + "num_enum/std", + "frame-support/std", + "sp-arithmetic/std", + "precompile-utils/std", + "parity-scale-codec/std", + "scale-info/std", +] diff --git a/precompile/erc721/contracts/IERC721.sol b/precompile/erc721/contracts/IERC721.sol new file mode 100644 index 00000000..a0c3d8ca --- /dev/null +++ b/precompile/erc721/contracts/IERC721.sol @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT +// derived from OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol) +pragma solidity >=0.8.3; + +interface IERC721 { + /** + * @dev See {IERC721Metadata-tokenURI}. + */ + function tokenURI(uint256 tokenId) external view returns (string memory); +} diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs new file mode 100644 index 00000000..11210ffa --- /dev/null +++ b/precompile/erc721/src/lib.rs @@ -0,0 +1,49 @@ +//! Living Assets precompile module. + +#![cfg_attr(not(feature = "std"), no_std)] +#![cfg_attr(test, feature(assert_matches))] +use fp_evm::{ + Precompile, PrecompileHandle, PrecompileOutput, +}; +use parity_scale_codec::Encode; +use precompile_utils::{EvmResult, FunctionModifier, PrecompileHandleExt}; + +use sp_std::{fmt::Debug, marker::PhantomData}; + +#[precompile_utils_macro::generate_function_selector] +#[derive(Debug, PartialEq)] +pub enum Action { + /// Get tocken URI + TockenURI = "tokenURI(uint256)", +} + +/// Wrapper for the precompile function. +pub struct CollectionManagerPrecompile( + PhantomData<(AddressMapping, AccountId)>, +) +where + AddressMapping: pallet_evm::AddressMapping, + AccountId: Encode + Debug; + +impl Precompile + for CollectionManagerPrecompile +where + AddressMapping: pallet_evm::AddressMapping, + AccountId: Encode + Debug, +{ + fn execute(handle: &mut impl PrecompileHandle) -> EvmResult { + let selector = handle.read_selector()?; + + handle.check_function_modifier(match selector { + Action::TockenURI => FunctionModifier::NonPayable, + })?; + + match selector { + Action::TockenURI => { + todo!() + }, + } + } +} + + From 5dafd9f7fbe3147469110a5190bd3eb3e3e2bf07 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Thu, 3 Aug 2023 18:06:30 +0200 Subject: [PATCH 09/36] fmt --- precompile/erc721/src/lib.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs index 11210ffa..c29fabee 100644 --- a/precompile/erc721/src/lib.rs +++ b/precompile/erc721/src/lib.rs @@ -2,9 +2,7 @@ #![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(test, feature(assert_matches))] -use fp_evm::{ - Precompile, PrecompileHandle, PrecompileOutput, -}; +use fp_evm::{Precompile, PrecompileHandle, PrecompileOutput}; use parity_scale_codec::Encode; use precompile_utils::{EvmResult, FunctionModifier, PrecompileHandleExt}; @@ -45,5 +43,3 @@ where } } } - - From e06adce4e29da42cf9378d55cdb7766e08b018b2 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Fri, 4 Aug 2023 15:02:00 +0200 Subject: [PATCH 10/36] compiling --- Cargo.lock | 1 - precompile/erc721/Cargo.toml | 1 - precompile/erc721/contracts/IERC721.sol | 2 ++ precompile/erc721/src/lib.rs | 7 ++++++- 4 files changed, 8 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index a2392e46..222f2646 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -9406,7 +9406,6 @@ dependencies = [ "hex", "num_enum 0.5.11", "pallet-evm", - "pallet-evm-test-vector-support", "pallet-living-assets-ownership", "parity-scale-codec", "precompile-utils", diff --git a/precompile/erc721/Cargo.toml b/precompile/erc721/Cargo.toml index f5d53602..58f587d5 100644 --- a/precompile/erc721/Cargo.toml +++ b/precompile/erc721/Cargo.toml @@ -32,7 +32,6 @@ precompile-utils-macro = { workspace = true } num_enum = { workspace = true } [dev-dependencies] -pallet-evm-test-vector-support = { workspace = true } evm = { workspace = true } hex = { version = "0.4.3" } diff --git a/precompile/erc721/contracts/IERC721.sol b/precompile/erc721/contracts/IERC721.sol index a0c3d8ca..2325486a 100644 --- a/precompile/erc721/contracts/IERC721.sol +++ b/precompile/erc721/contracts/IERC721.sol @@ -7,4 +7,6 @@ interface IERC721 { * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) external view returns (string memory); + + function ownerOf(uint256 _tokenId) external view returns (address); } diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs index c29fabee..7e551b1c 100644 --- a/precompile/erc721/src/lib.rs +++ b/precompile/erc721/src/lib.rs @@ -1,7 +1,6 @@ //! Living Assets precompile module. #![cfg_attr(not(feature = "std"), no_std)] -#![cfg_attr(test, feature(assert_matches))] use fp_evm::{Precompile, PrecompileHandle, PrecompileOutput}; use parity_scale_codec::Encode; use precompile_utils::{EvmResult, FunctionModifier, PrecompileHandleExt}; @@ -13,6 +12,8 @@ use sp_std::{fmt::Debug, marker::PhantomData}; pub enum Action { /// Get tocken URI TockenURI = "tokenURI(uint256)", + /// Owner of + OwnerOf = "ownerOf(uint256)", } /// Wrapper for the precompile function. @@ -34,12 +35,16 @@ where handle.check_function_modifier(match selector { Action::TockenURI => FunctionModifier::NonPayable, + Action::OwnerOf => FunctionModifier::NonPayable, })?; match selector { Action::TockenURI => { todo!() }, + Action::OwnerOf => { + todo!() + }, } } } From 3869690b963e8e17d0800e6d12fe9d96a95b5a33 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Fri, 4 Aug 2023 15:06:38 +0200 Subject: [PATCH 11/36] check selectors --- precompile/erc721/src/lib.rs | 3 +++ precompile/erc721/src/tests.rs | 7 +++++++ 2 files changed, 10 insertions(+) create mode 100644 precompile/erc721/src/tests.rs diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs index 7e551b1c..3436d617 100644 --- a/precompile/erc721/src/lib.rs +++ b/precompile/erc721/src/lib.rs @@ -48,3 +48,6 @@ where } } } + +#[cfg(test)] +mod tests; diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs new file mode 100644 index 00000000..2ac018eb --- /dev/null +++ b/precompile/erc721/src/tests.rs @@ -0,0 +1,7 @@ +use super::*; + +#[test] +fn check_selectors() { + assert_eq!(Action::OwnerOf as u32, 0x6352211E); + assert_eq!(Action::TockenURI as u32, 0xC87B56DD); +} From d514f880923c3900ef0afebdd53f277300243c83 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Fri, 4 Aug 2023 15:09:19 +0200 Subject: [PATCH 12/36] create trait Erc721 --- pallets/living-assets-ownership/Cargo.toml | 1 + pallets/living-assets-ownership/src/traits.rs | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/pallets/living-assets-ownership/Cargo.toml b/pallets/living-assets-ownership/Cargo.toml index d7310f6e..47227a05 100644 --- a/pallets/living-assets-ownership/Cargo.toml +++ b/pallets/living-assets-ownership/Cargo.toml @@ -20,6 +20,7 @@ frame-benchmarking = { workspace = true, optional = true } frame-support = { workspace = true } frame-system = { workspace = true } sp-arithmetic = { workspace = true } +sp-core = { workspace = true } [dev-dependencies] serde = { workspace = true } diff --git a/pallets/living-assets-ownership/src/traits.rs b/pallets/living-assets-ownership/src/traits.rs index 0ad629f3..a9975100 100644 --- a/pallets/living-assets-ownership/src/traits.rs +++ b/pallets/living-assets-ownership/src/traits.rs @@ -1,3 +1,5 @@ +use sp_core::{U256, H160}; + use crate::CollectionId; /// The `CollectionManager` trait provides an interface for managing collections in a @@ -25,3 +27,7 @@ pub trait CollectionManager { /// Create collection fn create_collection(owner: AccountId) -> Result; } + +pub trait Erc721 { + fn owner_of(asset_id: U256) -> Option; +} \ No newline at end of file From 2efff9286becb8310896dd8a850bdab08340297f Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Fri, 4 Aug 2023 15:14:54 +0200 Subject: [PATCH 13/36] Erc721Precompile --- precompile/erc721/src/lib.rs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs index 3436d617..8f4a066c 100644 --- a/precompile/erc721/src/lib.rs +++ b/precompile/erc721/src/lib.rs @@ -17,15 +17,12 @@ pub enum Action { } /// Wrapper for the precompile function. -pub struct CollectionManagerPrecompile( - PhantomData<(AddressMapping, AccountId)>, -) +pub struct Erc721Precompile(PhantomData<(AddressMapping, AccountId)>) where AddressMapping: pallet_evm::AddressMapping, AccountId: Encode + Debug; -impl Precompile - for CollectionManagerPrecompile +impl Precompile for Erc721Precompile where AddressMapping: pallet_evm::AddressMapping, AccountId: Encode + Debug, From 0357938ccdc71ffb41fe8f19f5b5d78404cd841d Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Fri, 4 Aug 2023 15:33:45 +0200 Subject: [PATCH 14/36] set mocks --- precompile/erc721/src/lib.rs | 12 +- precompile/erc721/src/tests.rs | 204 ++++++++++++++++++++++++++ precompile/living-assets/src/tests.rs | 1 - 3 files changed, 213 insertions(+), 4 deletions(-) diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs index 8f4a066c..01560caa 100644 --- a/precompile/erc721/src/lib.rs +++ b/precompile/erc721/src/lib.rs @@ -2,6 +2,7 @@ #![cfg_attr(not(feature = "std"), no_std)] use fp_evm::{Precompile, PrecompileHandle, PrecompileOutput}; +use pallet_living_assets_ownership::traits::Erc721; use parity_scale_codec::Encode; use precompile_utils::{EvmResult, FunctionModifier, PrecompileHandleExt}; @@ -17,15 +18,20 @@ pub enum Action { } /// Wrapper for the precompile function. -pub struct Erc721Precompile(PhantomData<(AddressMapping, AccountId)>) +pub struct Erc721Precompile( + PhantomData<(AddressMapping, AccountId, AssetManager)>, +) where AddressMapping: pallet_evm::AddressMapping, - AccountId: Encode + Debug; + AccountId: Encode + Debug, + AssetManager: Erc721; -impl Precompile for Erc721Precompile +impl Precompile + for Erc721Precompile where AddressMapping: pallet_evm::AddressMapping, AccountId: Encode + Debug, + AssetManager: Erc721, { fn execute(handle: &mut impl PrecompileHandle) -> EvmResult { let selector = handle.read_selector()?; diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs index 2ac018eb..640e8c46 100644 --- a/precompile/erc721/src/tests.rs +++ b/precompile/erc721/src/tests.rs @@ -1,7 +1,211 @@ use super::*; +use helpers::*; +use sp_core::{H160, U256}; + +type AccountId = H160; +type AddressMapping = pallet_evm::IdentityAddressMapping; #[test] fn check_selectors() { assert_eq!(Action::OwnerOf as u32, 0x6352211E); assert_eq!(Action::TockenURI as u32, 0xC87B56DD); } + +#[test] +fn create_collection_should_return_address() { + impl_precompile_mock_simple!(Mock, None); + + let owner_of_1234 = "6352211e00000000000000000000000000000000000000000000000000000000000004d2"; + let mut handle = create_mock_handle_from_input(owner_of_1234); + let result = Mock::execute(&mut handle); + assert!(result.is_ok()); +} + +mod helpers { + use evm::{Context, ExitError, ExitReason, Transfer}; + use fp_evm::{Log, PrecompileHandle}; + use sp_core::{H160, H256}; + + /// Macro to define a precompile mock with custom closures for testing. + /// + /// This macro creates mock implementations of the `Erc721` trait, + /// allowing you to test how your code interacts with the precompiled contracts. + /// You can define custom closures for the create_collection and owner_of_collection functions. + /// + /// # Arguments + /// + /// * `$name`: An identifier to name the precompile mock type. + /// * `$create_collection_result`: A closure that takes `collection_id` and `who` and returns a `DispatchResult`. + /// * `$owner_of_collection_result`: A closure that takes `collection_id` and returns an `Option`. + /// + /// # Example + /// + /// ``` + /// impl_precompile_mock!( + /// MyMock, + /// |who| { Ok(0) }, + /// |collection_id| { Some(H160::zero()) } + /// ); + /// ``` + #[macro_export] + macro_rules! impl_precompile_mock { + ($name:ident, $owner_of_collection:expr) => { + struct Erc721Mock; + + impl pallet_living_assets_ownership::traits::Erc721 for Erc721Mock { + fn owner_of(asset_id: U256) -> Option { + ($owner_of_collection)(asset_id) + } + } + + type $name = Erc721Precompile; + }; + } + + /// Macro to define a precompile mock for testing. + /// + /// This macro creates mock implementations of the `Erc721` trait, + /// allowing you to test how your code interacts with the precompiled contracts. + /// The mock type is named `Mock`, and the implementation uses the provided expressions. + /// + /// # Arguments + /// + /// * `$create_collection_result`: An expression that evaluates to a `DispatchResult`. + /// * `$owner_of_collection_result`: An expression that evaluates to an `Option`. + /// + /// # Example + /// + /// ``` + /// impl_precompile_mock_simple!(Mock, Ok(0), Some(H160::zero())); + /// ``` + #[macro_export] + macro_rules! impl_precompile_mock_simple { + ($name:ident, $owner_of_collection:expr) => { + impl_precompile_mock!($name, |_asset_id| { $owner_of_collection }); + }; + } + + /// Create a mock handle for testing precompiled contracts. + /// + /// This function takes an input string representing the data to be sent to the precompiled contract + /// and a cost value, returning a `MockHandle` that can be used for testing. + /// + /// # Arguments + /// + /// * `input` - The input data as a hexadecimal string. + /// * `cost` - A cost value as u64. + /// * `value` - The amount of coins transferred as u64. + /// + /// # Example + /// + /// ``` + /// let handle = create_mock_handle("68656c6c6f", 0, 0); + /// ``` + pub fn create_mock_handle(input: &str, cost: u64, value: u64, caller: H160) -> MockHandle { + let i: Vec = hex::decode(input).expect("invalid input"); + + let context: Context = + Context { address: Default::default(), caller, apparent_value: From::from(value) }; + + MockHandle::new(i, Some(cost), context) + } + + /// Create a mock handle for testing precompiled contracts without a specific cost or value. + /// + /// This function takes an input string representing the data to be sent to the precompiled contract + /// and returns a `MockHandle` that can be used for testing. + /// + /// # Arguments + /// + /// * `input` - The input data as a hexadecimal string. + /// + /// # Example + /// + /// ``` + /// let handle = create_mock_handle_from_input("68656c6c6f"); + /// ``` + pub fn create_mock_handle_from_input(input: &str) -> MockHandle { + create_mock_handle(input, 0, 0, H160::zero()) + } + + pub struct MockHandle { + pub input: Vec, + pub gas_limit: Option, + pub context: Context, + pub is_static: bool, + pub gas_used: u64, + pub logs: Vec, + } + + impl MockHandle { + pub fn new(input: Vec, gas_limit: Option, context: Context) -> Self { + Self { input, gas_limit, context, is_static: false, gas_used: 0, logs: vec![] } + } + } + + impl PrecompileHandle for MockHandle { + /// Perform subcall in provided context. + /// Precompile specifies in which context the subcall is executed. + fn call( + &mut self, + _: H160, + _: Option, + _: Vec, + _: Option, + _: bool, + _: &Context, + ) -> (ExitReason, Vec) { + unimplemented!() + } + + fn record_cost(&mut self, cost: u64) -> Result<(), ExitError> { + self.gas_used += cost; + Ok(()) + } + + fn record_external_cost( + &mut self, + _: Option, + _: Option, + ) -> Result<(), ExitError> { + Ok(()) + } + + fn refund_external_cost(&mut self, _: Option, _: Option) {} + + fn log( + &mut self, + address: H160, + topics: Vec, + data: Vec, + ) -> Result<(), ExitError> { + let log = Log { address, topics, data }; + self.logs.push(log); + Ok(()) + } + + fn remaining_gas(&self) -> u64 { + unimplemented!() + } + + fn code_address(&self) -> H160 { + unimplemented!() + } + + fn input(&self) -> &[u8] { + &self.input + } + + fn context(&self) -> &Context { + &self.context + } + + fn is_static(&self) -> bool { + self.is_static + } + + fn gas_limit(&self) -> Option { + self.gas_limit + } + } +} diff --git a/precompile/living-assets/src/tests.rs b/precompile/living-assets/src/tests.rs index 8884c218..08171c00 100644 --- a/precompile/living-assets/src/tests.rs +++ b/precompile/living-assets/src/tests.rs @@ -9,7 +9,6 @@ use helpers::*; use sp_core::{H160, H256}; use sp_std::vec::Vec; -type CollectionId = u64; type AccountId = H160; type AddressMapping = pallet_evm::IdentityAddressMapping; From cec3cbf77045abf45a472172ca9804f5f20f7cc8 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Fri, 4 Aug 2023 15:47:04 +0200 Subject: [PATCH 15/36] first implermentation --- precompile/erc721/src/lib.rs | 7 +++---- precompile/erc721/src/tests.rs | 1 + 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs index 01560caa..74a5574d 100644 --- a/precompile/erc721/src/lib.rs +++ b/precompile/erc721/src/lib.rs @@ -4,8 +4,9 @@ use fp_evm::{Precompile, PrecompileHandle, PrecompileOutput}; use pallet_living_assets_ownership::traits::Erc721; use parity_scale_codec::Encode; -use precompile_utils::{EvmResult, FunctionModifier, PrecompileHandleExt}; +use precompile_utils::{succeed, EvmResult, FunctionModifier, PrecompileHandleExt}; +use sp_core::H160; use sp_std::{fmt::Debug, marker::PhantomData}; #[precompile_utils_macro::generate_function_selector] @@ -45,9 +46,7 @@ where Action::TockenURI => { todo!() }, - Action::OwnerOf => { - todo!() - }, + Action::OwnerOf => Ok(succeed(H160::zero().encode())), } } } diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs index 640e8c46..1d796e52 100644 --- a/precompile/erc721/src/tests.rs +++ b/precompile/erc721/src/tests.rs @@ -19,6 +19,7 @@ fn create_collection_should_return_address() { let mut handle = create_mock_handle_from_input(owner_of_1234); let result = Mock::execute(&mut handle); assert!(result.is_ok()); + assert_eq!(result.unwrap().output, H160::zero().encode()); } mod helpers { From b0c10ce2be2a7e0880d3b03153de8c9933149646 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Fri, 4 Aug 2023 16:13:56 +0200 Subject: [PATCH 16/36] first integration of erc721 in the runtime --- Cargo.lock | 43 ++++++++++--------- Cargo.toml | 1 + pallets/living-assets-ownership/src/lib.rs | 7 +++ pallets/living-assets-ownership/src/traits.rs | 4 +- precompile/erc721/Cargo.toml | 2 +- runtime/Cargo.toml | 1 + runtime/src/precompiles.rs | 19 +++++++- 7 files changed, 52 insertions(+), 25 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 222f2646..2b2325d8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5060,6 +5060,7 @@ dependencies = [ "pallet-ethereum", "pallet-evm", "pallet-evm-chain-id", + "pallet-evm-erc721", "pallet-evm-living-assets-ownership", "pallet-evm-precompile-modexp", "pallet-evm-precompile-simple", @@ -7027,6 +7028,27 @@ dependencies = [ "sp-runtime", ] +[[package]] +name = "pallet-evm-erc721" +version = "0.0.1" +dependencies = [ + "evm", + "fp-evm", + "frame-support", + "hex", + "num_enum 0.5.11", + "pallet-evm", + "pallet-living-assets-ownership", + "parity-scale-codec", + "precompile-utils", + "precompile-utils-macro", + "scale-info", + "sp-arithmetic", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-evm-living-assets-ownership" version = "2.0.0-dev" @@ -9396,27 +9418,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5b40af805b3121feab8a3c29f04d8ad262fa8e0561883e7653e024ae4479e6de" -[[package]] -name = "precompile-erc721" -version = "0.0.1" -dependencies = [ - "evm", - "fp-evm", - "frame-support", - "hex", - "num_enum 0.5.11", - "pallet-evm", - "pallet-living-assets-ownership", - "parity-scale-codec", - "precompile-utils", - "precompile-utils-macro", - "scale-info", - "sp-arithmetic", - "sp-core", - "sp-runtime", - "sp-std", -] - [[package]] name = "precompile-utils" version = "0.4.3" diff --git a/Cargo.toml b/Cargo.toml index d73afa85..ac213229 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -222,6 +222,7 @@ pallet-bridge-relayers = { git = "https://github.com/freeverseio/parity-bridges- # LAOS pallets pallet-living-assets-ownership = { path = "./pallets/living-assets-ownership", default-features = false } pallet-evm-living-assets-ownership = { path = "./precompile/living-assets", default-features = false } +pallet-evm-erc721 = { path = "./precompile/erc721", default-features = false } # Utils precompile-utils = { path = "./precompile/utils", default-features = false } diff --git a/pallets/living-assets-ownership/src/lib.rs b/pallets/living-assets-ownership/src/lib.rs index 29ef5d26..154a5f4a 100644 --- a/pallets/living-assets-ownership/src/lib.rs +++ b/pallets/living-assets-ownership/src/lib.rs @@ -13,6 +13,7 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::{OptionQuery, ValueQuery, *}; use frame_system::pallet_prelude::*; + use sp_core::{U256, H160}; /// Collection id type /// TODO: use 256 bits @@ -83,6 +84,12 @@ pub mod pallet { Self::do_create_collection(owner) } } + + impl traits::Erc721 for Pallet { + fn owner_of(_asset_id: U256) -> Option { + Some(H160::zero()) + } + } } #[cfg(test)] diff --git a/pallets/living-assets-ownership/src/traits.rs b/pallets/living-assets-ownership/src/traits.rs index a9975100..69f4c46a 100644 --- a/pallets/living-assets-ownership/src/traits.rs +++ b/pallets/living-assets-ownership/src/traits.rs @@ -1,4 +1,4 @@ -use sp_core::{U256, H160}; +use sp_core::{H160, U256}; use crate::CollectionId; @@ -30,4 +30,4 @@ pub trait CollectionManager { pub trait Erc721 { fn owner_of(asset_id: U256) -> Option; -} \ No newline at end of file +} diff --git a/precompile/erc721/Cargo.toml b/precompile/erc721/Cargo.toml index 58f587d5..47304b70 100644 --- a/precompile/erc721/Cargo.toml +++ b/precompile/erc721/Cargo.toml @@ -1,5 +1,5 @@ [package] -name = "precompile-erc721" +name = "pallet-evm-erc721" version = "0.0.1" edition = "2021" diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index f0039b08..50784833 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -50,6 +50,7 @@ sp-version = { workspace = true } pallet-living-assets-ownership = { workspace = true } pallet-evm-living-assets-ownership = { workspace = true } +pallet-evm-erc721 = { workspace = true } # Polkadot pallet-xcm = { workspace = true } diff --git a/runtime/src/precompiles.rs b/runtime/src/precompiles.rs index 63e6aaa9..8ce48a30 100644 --- a/runtime/src/precompiles.rs +++ b/runtime/src/precompiles.rs @@ -8,6 +8,7 @@ use sp_core::H160; use sp_std::marker::PhantomData; use pallet_evm_living_assets_ownership::CollectionManagerPrecompile; +use pallet_evm_erc721::Erc721Precompile; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; @@ -33,12 +34,28 @@ type LivingAssetsPrecompile = CollectionManagerPrecompile< pallet_living_assets_ownership::Pallet, >; +type Erc721 = Erc721Precompile< + pallet_evm::HashedAddressMapping, + AccountId, + pallet_living_assets_ownership::Pallet, +>; + impl PrecompileSet for FrontierPrecompiles where Runtime: pallet_evm::Config + pallet_living_assets_ownership::Config, { fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { - match handle.code_address() { + let code_address = handle.code_address(); + + // TODO put the following code in the right place, maybe a fuction in the precompile + let first_byte = code_address.0[0]; + // Check if the first bit is set to 1 + if first_byte & 0x80 == 0x80 { + Some(Erc721::execute(handle)); + () + } + + match code_address { // Ethereum precompiles : a if a == hash(1) => Some(ECRecover::execute(handle)), a if a == hash(2) => Some(Sha256::execute(handle)), From 1420c2145e2898ff9806e00d166f91b1368c2ff5 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Fri, 4 Aug 2023 16:16:09 +0200 Subject: [PATCH 17/36] fmt --- pallets/living-assets-ownership/src/lib.rs | 2 +- runtime/src/precompiles.rs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/pallets/living-assets-ownership/src/lib.rs b/pallets/living-assets-ownership/src/lib.rs index 154a5f4a..bc79a627 100644 --- a/pallets/living-assets-ownership/src/lib.rs +++ b/pallets/living-assets-ownership/src/lib.rs @@ -13,7 +13,7 @@ pub mod pallet { use super::*; use frame_support::pallet_prelude::{OptionQuery, ValueQuery, *}; use frame_system::pallet_prelude::*; - use sp_core::{U256, H160}; + use sp_core::{H160, U256}; /// Collection id type /// TODO: use 256 bits diff --git a/runtime/src/precompiles.rs b/runtime/src/precompiles.rs index 8ce48a30..6c2f7b40 100644 --- a/runtime/src/precompiles.rs +++ b/runtime/src/precompiles.rs @@ -7,8 +7,8 @@ use polkadot_primitives::BlakeTwo256; use sp_core::H160; use sp_std::marker::PhantomData; -use pallet_evm_living_assets_ownership::CollectionManagerPrecompile; use pallet_evm_erc721::Erc721Precompile; +use pallet_evm_living_assets_ownership::CollectionManagerPrecompile; use pallet_evm_precompile_modexp::Modexp; use pallet_evm_precompile_simple::{ECRecover, ECRecoverPublicKey, Identity, Ripemd160, Sha256}; @@ -38,7 +38,7 @@ type Erc721 = Erc721Precompile< pallet_evm::HashedAddressMapping, AccountId, pallet_living_assets_ownership::Pallet, ->; +>; impl PrecompileSet for FrontierPrecompiles where From d0c4ce71b6d286c059b8a8ba8f78894dbf401114 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Fri, 4 Aug 2023 16:54:16 +0200 Subject: [PATCH 18/36] check on the collection id --- pallets/living-assets-ownership/src/lib.rs | 7 +++++-- pallets/living-assets-ownership/src/traits.rs | 2 +- precompile/erc721/src/tests.rs | 7 ++++--- 3 files changed, 10 insertions(+), 6 deletions(-) diff --git a/pallets/living-assets-ownership/src/lib.rs b/pallets/living-assets-ownership/src/lib.rs index bc79a627..890d0cdb 100644 --- a/pallets/living-assets-ownership/src/lib.rs +++ b/pallets/living-assets-ownership/src/lib.rs @@ -86,8 +86,11 @@ pub mod pallet { } impl traits::Erc721 for Pallet { - fn owner_of(_asset_id: U256) -> Option { - Some(H160::zero()) + fn owner_of(collection_id: CollectionId, _asset_id: U256) -> Option { + match OwnerOfCollection::::get(collection_id) { + Some(_) => Some(H160::zero()), + None => None, + } } } } diff --git a/pallets/living-assets-ownership/src/traits.rs b/pallets/living-assets-ownership/src/traits.rs index 69f4c46a..500cd5c8 100644 --- a/pallets/living-assets-ownership/src/traits.rs +++ b/pallets/living-assets-ownership/src/traits.rs @@ -29,5 +29,5 @@ pub trait CollectionManager { } pub trait Erc721 { - fn owner_of(asset_id: U256) -> Option; + fn owner_of(collection_id: CollectionId, asset_id: U256) -> Option; } diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs index 1d796e52..16c8a9e6 100644 --- a/precompile/erc721/src/tests.rs +++ b/precompile/erc721/src/tests.rs @@ -1,5 +1,6 @@ use super::*; use helpers::*; +use pallet_living_assets_ownership::CollectionId; use sp_core::{H160, U256}; type AccountId = H160; @@ -54,8 +55,8 @@ mod helpers { struct Erc721Mock; impl pallet_living_assets_ownership::traits::Erc721 for Erc721Mock { - fn owner_of(asset_id: U256) -> Option { - ($owner_of_collection)(asset_id) + fn owner_of(collectio_id: CollectionId, asset_id: U256) -> Option { + ($owner_of_collection)(collectio_id, asset_id) } } @@ -82,7 +83,7 @@ mod helpers { #[macro_export] macro_rules! impl_precompile_mock_simple { ($name:ident, $owner_of_collection:expr) => { - impl_precompile_mock!($name, |_asset_id| { $owner_of_collection }); + impl_precompile_mock!($name, |_asset_id, _collection_id| { $owner_of_collection }); }; } From aa84dde48abdb8900d4860c0d21236a345877586 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Fri, 4 Aug 2023 17:21:00 +0200 Subject: [PATCH 19/36] test on extract owner form asset_id --- .../living-assets-ownership/src/functions.rs | 18 ++++++++++++++++++ pallets/living-assets-ownership/src/lib.rs | 4 ++-- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/pallets/living-assets-ownership/src/functions.rs b/pallets/living-assets-ownership/src/functions.rs index acf3d69e..88eddf39 100644 --- a/pallets/living-assets-ownership/src/functions.rs +++ b/pallets/living-assets-ownership/src/functions.rs @@ -1,6 +1,7 @@ //! Contains helper and utility functions of the pallet use super::*; use frame_support::sp_runtime::traits::One; +use sp_core::{Encode, H160, U256}; impl Pallet { /// See [Self::create_collection] @@ -23,3 +24,20 @@ impl Pallet { Ok(collection_id) } } + +pub fn convert_u256_to_h160(value: U256) -> H160 { + let bytes = value.encode(); + H160::from_slice(&bytes[12..32]) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn check_convert_u256_to_h160() { + let value = U256::from(5); + let expected_address = H160::from_low_u64_be(5); + assert_eq!(convert_u256_to_h160(value), expected_address); + } +} diff --git a/pallets/living-assets-ownership/src/lib.rs b/pallets/living-assets-ownership/src/lib.rs index 890d0cdb..5dc79830 100644 --- a/pallets/living-assets-ownership/src/lib.rs +++ b/pallets/living-assets-ownership/src/lib.rs @@ -86,9 +86,9 @@ pub mod pallet { } impl traits::Erc721 for Pallet { - fn owner_of(collection_id: CollectionId, _asset_id: U256) -> Option { + fn owner_of(collection_id: CollectionId, asset_id: U256) -> Option { match OwnerOfCollection::::get(collection_id) { - Some(_) => Some(H160::zero()), + Some(_) => Some(functions::convert_u256_to_h160(asset_id)), None => None, } } From 0ec72a77f59cae598aaacd8ac8c72cc3ba98dbaa Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Sat, 5 Aug 2023 07:25:10 +0200 Subject: [PATCH 20/36] fix tests --- pallets/living-assets-ownership/src/functions.rs | 14 ++++++++------ pallets/living-assets-ownership/src/lib.rs | 4 +++- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pallets/living-assets-ownership/src/functions.rs b/pallets/living-assets-ownership/src/functions.rs index 88eddf39..abf2b028 100644 --- a/pallets/living-assets-ownership/src/functions.rs +++ b/pallets/living-assets-ownership/src/functions.rs @@ -1,7 +1,7 @@ //! Contains helper and utility functions of the pallet use super::*; use frame_support::sp_runtime::traits::One; -use sp_core::{Encode, H160, U256}; +use sp_core::{H160, U256}; impl Pallet { /// See [Self::create_collection] @@ -25,9 +25,11 @@ impl Pallet { } } -pub fn convert_u256_to_h160(value: U256) -> H160 { - let bytes = value.encode(); - H160::from_slice(&bytes[12..32]) +pub fn convert_asset_id_to_owner(value: U256) -> H160 { + let mut bytes = [0u8; 20]; + let value_bytes: [u8; 32] = value.into(); + bytes.copy_from_slice(&value_bytes[value_bytes.len() - 20..]); + H160::from(bytes) } #[cfg(test)] @@ -35,9 +37,9 @@ mod tests { use super::*; #[test] - fn check_convert_u256_to_h160() { + fn check_convert_asset_id_to_owner() { let value = U256::from(5); let expected_address = H160::from_low_u64_be(5); - assert_eq!(convert_u256_to_h160(value), expected_address); + assert_eq!(convert_asset_id_to_owner(value), expected_address); } } diff --git a/pallets/living-assets-ownership/src/lib.rs b/pallets/living-assets-ownership/src/lib.rs index 5dc79830..1ac933a7 100644 --- a/pallets/living-assets-ownership/src/lib.rs +++ b/pallets/living-assets-ownership/src/lib.rs @@ -10,6 +10,8 @@ pub mod traits; #[frame_support::pallet] pub mod pallet { + use crate::functions::convert_asset_id_to_owner; + use super::*; use frame_support::pallet_prelude::{OptionQuery, ValueQuery, *}; use frame_system::pallet_prelude::*; @@ -88,7 +90,7 @@ pub mod pallet { impl traits::Erc721 for Pallet { fn owner_of(collection_id: CollectionId, asset_id: U256) -> Option { match OwnerOfCollection::::get(collection_id) { - Some(_) => Some(functions::convert_u256_to_h160(asset_id)), + Some(_) => Some(convert_asset_id_to_owner(asset_id)), None => None, } } From 9be1a5b2f4b0ba267706ed3fa292edb29ea80cee Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Sat, 5 Aug 2023 08:27:15 +0200 Subject: [PATCH 21/36] test for erc721 trait --- pallets/living-assets-ownership/src/tests.rs | 26 +++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/pallets/living-assets-ownership/src/tests.rs b/pallets/living-assets-ownership/src/tests.rs index dd37b935..7d663c12 100644 --- a/pallets/living-assets-ownership/src/tests.rs +++ b/pallets/living-assets-ownership/src/tests.rs @@ -1,5 +1,10 @@ -use crate::{mock::*, traits::CollectionManager, Event}; +use crate::{ + mock::*, + traits::{CollectionManager, Erc721}, + Event, +}; use frame_support::assert_ok; +use sp_core::H160; type AccountId = ::AccountId; @@ -107,3 +112,22 @@ fn living_assets_ownership_trait_id_of_new_collection_should_be_consecutive() { ); }); } + +#[test] +fn erc721_owner_of_asset_of_unexistent_collection() { + new_test_ext().execute_with(|| { + assert_eq!(::owner_of(0, 2.into()), None); + }); +} + +#[test] +fn erc721_owner_of_asset_of_collection() { + new_test_ext().execute_with(|| { + let collection_id = + >::create_collection(ALICE).unwrap(); + assert_eq!( + ::owner_of(collection_id, 2.into()).unwrap(), + H160::from_low_u64_be(0x0000000000000002) + ); + }); +} From 4625aad06967473ca4d68638f5268b72b7484506 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Sat, 5 Aug 2023 09:44:45 +0200 Subject: [PATCH 22/36] fix compilation --- Cargo.lock | 365 +++++++++++++++----------------- runtime/src/precompiles/mock.rs | 16 +- 2 files changed, 180 insertions(+), 201 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2b2325d8..369d6c12 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -316,7 +316,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.25", + "time 0.3.23", ] [[package]] @@ -332,7 +332,7 @@ dependencies = [ "num-traits", "rusticata-macros", "thiserror", - "time 0.3.25", + "time 0.3.23", ] [[package]] @@ -424,25 +424,25 @@ checksum = "0e97ce7de6cf12de5d7226c73f5ba9811622f4db3a5b91b55c53e987e5f91cba" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] name = "async-trait" -version = "0.1.72" +version = "0.1.71" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cc6dde6e4ed435a4c1ee4e73592f5ba9da2151af10076cc04858746af9352d09" +checksum = "a564d521dd56509c4c47480d00b80ee55f7e385ae48db5744c67ad50c92d2ebf" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] name = "asynchronous-codec" -version = "0.6.2" +version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4057f2c32adbb2fc158e22fb38433c8e9bbf76b75a4732c7c0cbaf695fb65568" +checksum = "06a0daa378f5fd10634e44b0a29b2a87b890657658e072a30d6f26e57ddee182" dependencies = [ "bytes", "futures-sink", @@ -576,13 +576,13 @@ dependencies = [ "lazy_static", "lazycell", "peeking_take_while", - "prettyplease 0.2.12", + "prettyplease 0.2.10", "proc-macro2", "quote", "regex", "rustc-hash", "shlex", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -733,7 +733,7 @@ dependencies = [ [[package]] name = "bp-beefy" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "binary-merkle-tree", "bp-runtime", @@ -751,7 +751,7 @@ dependencies = [ [[package]] name = "bp-bridge-hub-cumulus" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-messages", "bp-polkadot-core", @@ -766,7 +766,7 @@ dependencies = [ [[package]] name = "bp-evochain" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-beefy", "bp-header-chain", @@ -793,7 +793,7 @@ dependencies = [ [[package]] name = "bp-header-chain" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-runtime", "finality-grandpa", @@ -810,7 +810,7 @@ dependencies = [ [[package]] name = "bp-messages" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-header-chain", "bp-runtime", @@ -826,7 +826,7 @@ dependencies = [ [[package]] name = "bp-ownership-parachain" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-bridge-hub-cumulus", "bp-messages", @@ -843,7 +843,7 @@ dependencies = [ [[package]] name = "bp-parachains" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-header-chain", "bp-polkadot-core", @@ -860,7 +860,7 @@ dependencies = [ [[package]] name = "bp-polkadot-core" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-messages", "bp-runtime", @@ -878,7 +878,7 @@ dependencies = [ [[package]] name = "bp-relayers" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-messages", "bp-runtime", @@ -892,7 +892,7 @@ dependencies = [ [[package]] name = "bp-runtime" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "frame-support", "frame-system", @@ -914,7 +914,7 @@ dependencies = [ [[package]] name = "bp-test-utils" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-header-chain", "bp-parachains", @@ -934,7 +934,7 @@ dependencies = [ [[package]] name = "bridge-runtime-common" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-header-chain", "bp-messages", @@ -1081,12 +1081,11 @@ dependencies = [ [[package]] name = "cc" -version = "1.0.81" +version = "1.0.79" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c6b2562119bf28c3439f7f02db99faf0aa1a8cdfe5772a2ee155d32227239f0" +checksum = "50d30906286121d95be3d479533b458f87493b30a4b5f79a607db8f5d11aa91f" dependencies = [ "jobserver", - "libc", ] [[package]] @@ -1111,9 +1110,9 @@ dependencies = [ [[package]] name = "cfg-expr" -version = "0.15.4" +version = "0.15.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b40ccee03b5175c18cde8f37e7d2a33bcef6f8ec8f7cc0d81090d1bb380949c9" +checksum = "215c0072ecc28f92eeb0eea38ba63ddfcb65c2828c46311d646f1a3ff5f9841c" dependencies = [ "smallvec", ] @@ -1233,9 +1232,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.3.19" +version = "4.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fd304a20bff958a57f04c4e96a2e7594cc4490a0e809cbd48bb6437edaa452d" +checksum = "5b0827b011f6f8ab38590295339817b0d26f344aa4932c3ced71b45b0c54b4a9" dependencies = [ "clap_builder", "clap_derive", @@ -1244,9 +1243,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.3.19" +version = "4.3.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01c6a3f08f1fe5662a35cfe393aec09c4df95f60ee93b7556505260f75eee9e1" +checksum = "9441b403be87be858db6a23edb493e7f694761acdc3343d5a0fcaafd304cbc9e" dependencies = [ "anstream", "anstyle", @@ -1263,7 +1262,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -1989,7 +1988,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -2293,9 +2292,9 @@ dependencies = [ [[package]] name = "cxx" -version = "1.0.102" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f68e12e817cb19eaab81aaec582b4052d07debd3c3c6b083b9d361db47c7dc9d" +checksum = "5032837c1384de3708043de9d4e97bb91290faca6c16529a28aa340592a78166" dependencies = [ "cc", "cxxbridge-flags", @@ -2305,9 +2304,9 @@ dependencies = [ [[package]] name = "cxx-build" -version = "1.0.102" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e789217e4ab7cf8cc9ce82253180a9fe331f35f5d339f0ccfe0270b39433f397" +checksum = "51368b3d0dbf356e10fcbfd455a038503a105ee556f7ee79b6bb8c53a7247456" dependencies = [ "cc", "codespan-reporting", @@ -2315,24 +2314,24 @@ dependencies = [ "proc-macro2", "quote", "scratch", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] name = "cxxbridge-flags" -version = "1.0.102" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78a19f4c80fd9ab6c882286fa865e92e07688f4387370a209508014ead8751d0" +checksum = "0d9062157072e4aafc8e56ceaf8325ce850c5ae37578c852a0d4de2cecdded13" [[package]] name = "cxxbridge-macro" -version = "1.0.102" +version = "1.0.101" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b8fcfa71f66c8563c4fa9dd2bb68368d50267856f831ac5d85367e0805f9606c" +checksum = "cf01e8a540f5a4e0f284595834f81cf88572f244b768f051724537afa99a2545" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -2445,12 +2444,6 @@ dependencies = [ "rusticata-macros", ] -[[package]] -name = "deranged" -version = "0.3.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7684a49fb1af197853ef7b2ee694bc1f5b4179556f1e5710e1760c5db6f5e929" - [[package]] name = "derivative" version = "2.2.0" @@ -2602,7 +2595,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -2626,7 +2619,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.28", + "syn 2.0.26", "termcolor", "walkdir", ] @@ -2684,9 +2677,9 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.16.8" +version = "0.16.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4" +checksum = "0997c976637b606099b9985693efa3581e84e41f5c11ba5255f88711058ad428" dependencies = [ "der 0.7.7", "digest 0.10.7", @@ -2735,9 +2728,9 @@ dependencies = [ [[package]] name = "either" -version = "1.9.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +checksum = "7fcaabb2fef8c910e7f4c7ce9f67a1283a1715879a7c230ca9d6d1ae31f16d91" [[package]] name = "elliptic-curve" @@ -2815,18 +2808,18 @@ checksum = "5e9a1f9f7d83e59740248a6e14ecf93929ade55027844dfcea78beafccc15745" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] name = "enumn" -version = "0.1.11" +version = "0.1.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b893c4eb2dc092c811165f84dc7447fae16fb66521717968c34c509b39b1a5c5" +checksum = "c9838a970f5de399d3070ae1739e131986b2f5dcc223c7423ca0927e3a878522" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -2869,9 +2862,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b30f669a7961ef1631673d2766cc92f52d64f7ef354d4fe0ddfd30ed52f0f4f" +checksum = "4bcfec3a70f97c962c307b2d2c56e358cf1d00b558d74262b5f929ee8cc7e73a" dependencies = [ "errno-dragonfly", "libc", @@ -3040,7 +3033,7 @@ dependencies = [ "fs-err", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -3064,12 +3057,6 @@ dependencies = [ "instant", ] -[[package]] -name = "fastrand" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6999dc1837253364c2ebb0704ba97994bd874e8f195d665c50b7548f6ea92764" - [[package]] name = "fatality" version = "0.0.6" @@ -3580,7 +3567,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -3699,7 +3686,7 @@ dependencies = [ "proc-macro-warning", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -3711,7 +3698,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -3721,7 +3708,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#948 dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -3801,7 +3788,7 @@ version = "0.6.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2eeb4ed9e12f43b7fa0baae3f9cdda28352770132ef2e09a23760c29cae8bd47" dependencies = [ - "rustix 0.38.6", + "rustix 0.38.4", "windows-sys 0.48.0", ] @@ -3866,7 +3853,7 @@ version = "1.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "49a9d51ce47660b1e808d3c990b4709f2f415d928835a17dfd16991515c46bce" dependencies = [ - "fastrand 1.9.0", + "fastrand", "futures-core", "futures-io", "memchr", @@ -3883,7 +3870,7 @@ checksum = "89ca545a94061b6365f2c7355b4b32bd20df3ff95f02da9329b34ccc3bd6ee72" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -4033,9 +4020,9 @@ checksum = "d2fabcfbdc87f4758337ca535fb41a6d701b65693ce38287d856d1674551ec9b" [[package]] name = "globset" -version = "0.4.12" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aca8bbd8e0707c1887a8bbb7e6b40e228f251ff5d62c8220a4a7a53c73aff006" +checksum = "1391ab1f92ffcc08911957149833e682aa3fe252b9f45f966d2ef972274c97df" dependencies = [ "aho-corasick", "bstr 1.6.0", @@ -4267,9 +4254,9 @@ dependencies = [ [[package]] name = "http-range-header" -version = "0.3.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "add0ab9360ddbd88cfeb3bd9574a1d85cfdfa14db10b3e21d3700dbc4328758f" +checksum = "0bfe8eed0a9285ef776bb792479ea3834e8b94e13d615c2f66d03dd50a435a29" [[package]] name = "httparse" @@ -4485,9 +4472,9 @@ dependencies = [ [[package]] name = "indicatif" -version = "0.17.6" +version = "0.17.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b297dc40733f23a0e52728a58fa9489a5b7638a324932de16b41adc3ef80730" +checksum = "8ff8cc23a7393a397ed1d7f56e6365cba772aba9f9912ab968b03043c395d057" dependencies = [ "console", "instant", @@ -4590,7 +4577,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ "hermit-abi 0.3.2", - "rustix 0.38.6", + "rustix 0.38.4", "windows-sys 0.48.0", ] @@ -4778,7 +4765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cadb76004ed8e97623117f3df85b17aaa6626ab0b0831e6573f104df16cd1bcc" dependencies = [ "cfg-if", - "ecdsa 0.16.8", + "ecdsa 0.16.7", "elliptic-curve 0.13.5", "once_cell", "sha2 0.10.7", @@ -5620,9 +5607,9 @@ dependencies = [ [[package]] name = "libz-sys" -version = "1.1.12" +version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d97137b25e321a73eef1418d1d5d2eda4d77e12813f8e6dead84bc52c5870a7b" +checksum = "56ee889ecc9568871456d42f603d6a0ce59ff328d291063a45cbdf0036baf6db" dependencies = [ "cc", "pkg-config", @@ -5676,9 +5663,9 @@ checksum = "ef53942eb7bf7ff43a617b3e2c1c4a5ecf5944a7c1bc12d7ee39bbb15e5c1519" [[package]] name = "linux-raw-sys" -version = "0.4.5" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57bcfdad1b858c2db7c38303a6d2ad4dfaf5eb53dfeb0910128b2c26d6158503" +checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" [[package]] name = "lock_api" @@ -5770,7 +5757,7 @@ dependencies = [ "macro_magic_core", "macro_magic_macros", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -5784,7 +5771,7 @@ dependencies = [ "macro_magic_core_macros", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -5795,7 +5782,7 @@ checksum = "c12469fc165526520dff2807c2975310ab47cf7190a45b99b49a7dc8befab17b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -5806,7 +5793,7 @@ checksum = "b8fb85ec1620619edf2984a7693497d4ec88a9665d8b87e942856884c92dbf2a" dependencies = [ "macro_magic_core", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -6328,9 +6315,9 @@ dependencies = [ [[package]] name = "num-traits" -version = "0.2.16" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f30b0abd723be7e2ffca1272140fac1a2f084c77ec3e123c192b66af1ee9e6c2" +checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" dependencies = [ "autocfg", ] @@ -6384,7 +6371,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -6743,7 +6730,7 @@ dependencies = [ [[package]] name = "pallet-bridge-grandpa" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-header-chain", "bp-runtime", @@ -6764,7 +6751,7 @@ dependencies = [ [[package]] name = "pallet-bridge-messages" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-header-chain", "bp-messages", @@ -6785,7 +6772,7 @@ dependencies = [ [[package]] name = "pallet-bridge-parachains" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-header-chain", "bp-parachains", @@ -6806,7 +6793,7 @@ dependencies = [ [[package]] name = "pallet-bridge-relayers" version = "0.1.0" -source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#79808a3e640f882c49162f5f24c9ea48e7b35a0a" +source = "git+https://github.com/freeverseio/parity-bridges-common.git?branch=polkadot-v1.0.0#60a56bbad7ad646e71a9924a1cfeda61c47c4b2f" dependencies = [ "bp-messages", "bp-relayers", @@ -7562,7 +7549,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -7844,9 +7831,9 @@ dependencies = [ [[package]] name = "parity-db" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78f19d20a0d2cc52327a88d131fa1c4ea81ea4a04714aedcfeca2dd410049cf8" +checksum = "0dab3ac198341b2f0fec6e7f8a6eeed07a41201d98a124260611598c142e76df" dependencies = [ "blake2", "crc32fast", @@ -8046,9 +8033,9 @@ checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" [[package]] name = "pest" -version = "2.7.2" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1acb4a4365a13f749a93f1a094a7805e5cfa0955373a9de860d962eaa3a5fe5a" +checksum = "0d2d1d55045829d65aad9d389139882ad623b33b904e7c9f1b10c5b8927298e5" dependencies = [ "thiserror", "ucd-trie", @@ -8056,9 +8043,9 @@ dependencies = [ [[package]] name = "pest_derive" -version = "2.7.2" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "666d00490d4ac815001da55838c500eafb0320019bbaa44444137c48b443a853" +checksum = "5f94bca7e7a599d89dea5dfa309e217e7906c3c007fb9c3299c40b10d6a315d3" dependencies = [ "pest", "pest_generator", @@ -8066,22 +8053,22 @@ dependencies = [ [[package]] name = "pest_generator" -version = "2.7.2" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "68ca01446f50dbda87c1786af8770d535423fa8a53aec03b8f4e3d7eb10e0929" +checksum = "99d490fe7e8556575ff6911e45567ab95e71617f43781e5c05490dc8d75c965c" dependencies = [ "pest", "pest_meta", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] name = "pest_meta" -version = "2.7.2" +version = "2.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "56af0a30af74d0445c0bf6d9d051c979b516a1a5af790d251daee76005420a48" +checksum = "2674c66ebb4b4d9036012091b537aae5878970d6999f81a265034d85b136b341" dependencies = [ "once_cell", "pest", @@ -8115,7 +8102,7 @@ checksum = "ec2e072ecce94ec471b13398d5402c188e76ac03cf74dd1a975161b23a3f6d9c" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -9408,9 +9395,9 @@ dependencies = [ [[package]] name = "portable-atomic" -version = "1.4.2" +version = "1.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f32154ba0af3a075eefa1eda8bb414ee928f62303a54ea85b8d6638ff1a6ee9e" +checksum = "edc55135a600d700580e406b4de0d59cb9ad25e344a3a091a97ded2622ec4ec6" [[package]] name = "ppv-lite86" @@ -9495,12 +9482,12 @@ dependencies = [ [[package]] name = "prettyplease" -version = "0.2.12" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c64d9ba0963cdcea2e1b2230fbae2bab30eb25a174be395c41e764bfb65dd62" +checksum = "92139198957b410250d43fad93e630d956499a625c527eda65175c8680f83387" dependencies = [ "proc-macro2", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -9581,7 +9568,7 @@ checksum = "70550716265d1ec349c41f70dd4f964b4fd88394efe4405f0c1da679c4799a07" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -9734,9 +9721,9 @@ dependencies = [ [[package]] name = "quinn-proto" -version = "0.9.4" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31999cfc7927c4e212e60fd50934ab40e8e8bfd2d493d6095d2d306bc0764d9" +checksum = "67c10f662eee9c94ddd7135043e544f3c82fa839a1e7b865911331961b53186c" dependencies = [ "bytes", "rand 0.8.5", @@ -9752,9 +9739,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.32" +version = "1.0.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50f3b39ccfb720540debaa0164757101c08ecb8d326b15358ce76a62c7e85965" +checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" dependencies = [ "proc-macro2", ] @@ -9881,7 +9868,7 @@ checksum = "6413f3de1edee53342e6138e75b56d32e7bc6e332b3bd62d497b1929d4cfbcdd" dependencies = [ "pem", "ring", - "time 0.3.25", + "time 0.3.23", "x509-parser 0.13.2", "yasna", ] @@ -9894,7 +9881,7 @@ checksum = "ffbe84efe2f38dea12e9bfc1f65377fdf03e53a18cb3b995faedf7934c7e785b" dependencies = [ "pem", "ring", - "time 0.3.25", + "time 0.3.23", "yasna", ] @@ -9942,22 +9929,22 @@ dependencies = [ [[package]] name = "ref-cast" -version = "1.0.19" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61ef7e18e8841942ddb1cf845054f8008410030a3997875d9e49b7a363063df1" +checksum = "1641819477c319ef452a075ac34a4be92eb9ba09f6841f62d594d50fdcf0bf6b" dependencies = [ "ref-cast-impl", ] [[package]] name = "ref-cast-impl" -version = "1.0.19" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dfaf0c85b766276c797f3791f5bc6d5bd116b41d53049af2789666b0c0bc9fa" +checksum = "68bf53dad9b6086826722cdc99140793afd9f62faa14a1ad07eb4f955e7a7216" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -9980,7 +9967,7 @@ checksum = "b2eae68fc220f7cf2532e4494aded17545fce192d59cd996e0fe7887f4ceb575" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.3.4", + "regex-automata 0.3.3", "regex-syntax 0.7.4", ] @@ -9995,9 +9982,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.4" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7b6d6190b7594385f61bd3911cd1be99dfddcfc365a4160cc2ab5bff4aed294" +checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" dependencies = [ "aho-corasick", "memchr", @@ -10331,14 +10318,14 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.6" +version = "0.38.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ee020b1716f0a80e2ace9b03441a749e402e86712f15f16fe8a8f75afac732f" +checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" dependencies = [ "bitflags 2.3.3", "errno", "libc", - "linux-raw-sys 0.4.5", + "linux-raw-sys 0.4.3", "windows-sys 0.48.0", ] @@ -10555,7 +10542,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -11478,7 +11465,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -11703,9 +11690,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "2.9.2" +version = "2.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05b64fb303737d99b81884b2c63433e9ae28abebe5eb5045dcdd175dc2ecf4de" +checksum = "1fc758eb7bffce5b308734e9b0c1468893cae9ff70ebf13e7090be8dcbcc83a8" dependencies = [ "bitflags 1.3.2", "core-foundation", @@ -11716,9 +11703,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.9.1" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e932934257d3b408ed8f30db49d85ea163bfe74961f017f405b025af298f0c7a" +checksum = "f51d0c0d83bec45f16480d0ce0058397a69e48fcdc52d1dc8855fb68acbd31a7" dependencies = [ "core-foundation-sys", "libc", @@ -11750,29 +11737,29 @@ checksum = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3" [[package]] name = "serde" -version = "1.0.181" +version = "1.0.173" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6d3e73c93c3240c0bda063c239298e633114c69a888c3e37ca8bb33f343e9890" +checksum = "e91f70896d6720bc714a4a57d22fc91f1db634680e65c8efe13323f1fa38d53f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.181" +version = "1.0.173" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be02f6cb0cd3a5ec20bbcfbcbd749f57daddb1a0882dc2e46a6c236c90b977ed" +checksum = "a6250dde8342e0232232be9ca3db7aa40aceb5a3e5dd9bddbc00d99a007cde49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] name = "serde_json" -version = "1.0.104" +version = "1.0.103" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076066c5f1078eac5b722a31827a8832fe108bed65dfa75e233c89f8206e976c" +checksum = "d03b412469450d4404fe8499a268edd7f8b79fecb074b0d812ad64ca21f4031b" dependencies = [ "itoa", "ryu", @@ -12075,7 +12062,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -12312,7 +12299,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#948 dependencies = [ "quote", "sp-core-hashing", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -12331,7 +12318,7 @@ source = "git+https://github.com/paritytech/substrate?branch=polkadot-v1.0.0#948 dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -12538,7 +12525,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -12723,7 +12710,7 @@ dependencies = [ "parity-scale-codec", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -13043,9 +13030,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.28" +version = "2.0.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "04361975b3f5e348b2189d8dc55bc942f278b2d482a6a0365de5bdd62d351567" +checksum = "45c3457aacde3c65315de5031ec191ce46604304d2446e803d71ade03308d970" dependencies = [ "proc-macro2", "quote", @@ -13093,20 +13080,21 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "target-lexicon" -version = "0.12.11" +version = "0.12.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d0e916b1148c8e263850e1ebcbd046f333e0683c724876bb0da63ea4373dc8a" +checksum = "1d2faeef5759ab89935255b1a4cd98e0baf99d1085e37d36599c625dac49ae8e" [[package]] name = "tempfile" -version = "3.7.0" +version = "3.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5486094ee78b2e5038a6382ed7645bc084dc2ec433426ca4c3cb61e2007b8998" +checksum = "31c0432476357e58790aaa47a8efb0c5138f137343f3b5f23bd36a27e3b0a6d6" dependencies = [ + "autocfg", "cfg-if", - "fastrand 2.0.0", + "fastrand", "redox_syscall 0.3.5", - "rustix 0.38.6", + "rustix 0.37.23", "windows-sys 0.48.0", ] @@ -13127,22 +13115,22 @@ checksum = "3369f5ac52d5eb6ab48c6b4ffdc8efbcad6b89c765749064ba298f2c68a16a76" [[package]] name = "thiserror" -version = "1.0.44" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "611040a08a0439f8248d1990b111c95baa9c704c805fa1f62104b39655fd7f90" +checksum = "a35fc5b8971143ca348fa6df4f024d4d55264f3468c71ad1c2f365b0a4d58c42" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.44" +version = "1.0.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "090198534930841fab3a5d1bb637cde49e339654e606195f8d9c76eeb081dc96" +checksum = "463fe12d7993d3b327787537ce8dd4dfa058de32fc2b195ef3cde03dc4771e8f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -13185,9 +13173,9 @@ dependencies = [ [[package]] name = "tikv-jemalloc-ctl" -version = "0.5.4" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "619bfed27d807b54f7f776b9430d4f8060e66ee138a28632ca898584d462c31c" +checksum = "e37706572f4b151dff7a0146e040804e9c26fe3a3118591112f05cf12a4216c1" dependencies = [ "libc", "paste", @@ -13196,9 +13184,9 @@ dependencies = [ [[package]] name = "tikv-jemalloc-sys" -version = "0.5.4+5.3.0-patched" +version = "0.5.3+5.3.0-patched" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9402443cb8fd499b6f327e40565234ff34dbda27460c5b47db0db77443dd85d1" +checksum = "a678df20055b43e57ef8cddde41cdfda9a3c1a060b67f4c5836dfb1d78543ba8" dependencies = [ "cc", "libc", @@ -13217,11 +13205,10 @@ dependencies = [ [[package]] name = "time" -version = "0.3.25" +version = "0.3.23" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b0fdd63d58b18d663fbdf70e049f00a22c8e42be082203be7f26589213cd75ea" +checksum = "59e399c068f43a5d116fedaf73b203fa4f9c519f17e2b34f63221d3792f81446" dependencies = [ - "deranged", "itoa", "serde", "time-core", @@ -13236,9 +13223,9 @@ checksum = "7300fbefb4dadc1af235a9cef3737cea692a9d97e1b9cbcd4ebdae6f8868e6fb" [[package]] name = "time-macros" -version = "0.2.11" +version = "0.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eb71511c991639bb078fd5bf97757e03914361c48100d52878b8e52b46fb92cd" +checksum = "96ba15a897f3c86766b757e5ac7221554c6750054d74d5b28844fce5fb36a6c4" dependencies = [ "time-core", ] @@ -13324,7 +13311,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -13442,9 +13429,9 @@ dependencies = [ [[package]] name = "tower-http" -version = "0.4.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "55ae70283aba8d2a8b411c695c437fe25b8b5e44e23e780662002fc72fb47a82" +checksum = "7ac8060a61f8758a61562f6fb53ba3cbe1ca906f001df2e53cccddcdbee91e7c" dependencies = [ "bitflags 2.3.3", "bytes", @@ -13491,7 +13478,7 @@ checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -13534,7 +13521,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -13962,7 +13949,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", "wasm-bindgen-shared", ] @@ -13996,7 +13983,7 @@ checksum = "54681b18a46765f095758388f2d0cf16eb8d4169b639ab575a8f5693af210c7b" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -14341,7 +14328,7 @@ dependencies = [ "sha2 0.10.7", "stun", "thiserror", - "time 0.3.25", + "time 0.3.23", "tokio", "turn", "url", @@ -14875,9 +14862,9 @@ checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" [[package]] name = "winnow" -version = "0.5.3" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46aab759304e4d7b2075a9aecba26228bb073ee8c50db796b2c72c676b5d807" +checksum = "81fac9742fd1ad1bd9643b991319f72dd031016d44b77039a26977eb667141e7" dependencies = [ "memchr", ] @@ -14939,7 +14926,7 @@ dependencies = [ "ring", "rusticata-macros", "thiserror", - "time 0.3.25", + "time 0.3.23", ] [[package]] @@ -14957,7 +14944,7 @@ dependencies = [ "oid-registry 0.6.1", "rusticata-macros", "thiserror", - "time 0.3.25", + "time 0.3.23", ] [[package]] @@ -15026,7 +15013,7 @@ dependencies = [ "Inflector", "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] @@ -15049,7 +15036,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" dependencies = [ - "time 0.3.25", + "time 0.3.23", ] [[package]] @@ -15069,7 +15056,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.28", + "syn 2.0.26", ] [[package]] diff --git a/runtime/src/precompiles/mock.rs b/runtime/src/precompiles/mock.rs index d8b58b46..bf680f02 100644 --- a/runtime/src/precompiles/mock.rs +++ b/runtime/src/precompiles/mock.rs @@ -9,7 +9,6 @@ use pallet_evm::{ }; use sp_core::{H160, H256, U256}; use sp_runtime::{ - testing::Header, traits::{BlakeTwo256, IdentityLookup}, ConsensusEngineId, }; @@ -17,16 +16,11 @@ use sp_std::{boxed::Box, prelude::*, str::FromStr}; use super::FrontierPrecompiles; -type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; type Block = frame_system::mocking::MockBlock; // Configure a mock runtime to test the pallet. construct_runtime!( - pub enum Runtime where - Block = Block, - NodeBlock = Block, - UncheckedExtrinsic = UncheckedExtrinsic, - { + pub enum Runtime { System: frame_system, Balances: pallet_balances, Timestamp: pallet_timestamp, @@ -42,13 +36,10 @@ impl frame_system::Config for Runtime { type DbWeight = (); type RuntimeOrigin = RuntimeOrigin; type RuntimeCall = RuntimeCall; - type Index = u64; - type BlockNumber = u64; type Hash = H256; type Hashing = BlakeTwo256; type AccountId = H160; type Lookup = IdentityLookup; - type Header = Header; type RuntimeEvent = RuntimeEvent; type BlockHashCount = ConstU64<250>; type Version = (); @@ -60,6 +51,8 @@ impl frame_system::Config for Runtime { type SS58Prefix = (); type OnSetCode = (); type MaxConsumers = frame_support::traits::ConstU32<16>; + type Nonce = u64; + type Block = Block; } parameter_types! { @@ -74,12 +67,12 @@ impl pallet_balances::Config for Runtime { type ExistentialDeposit = ExistentialDeposit; type AccountStore = System; type ReserveIdentifier = (); - type HoldIdentifier = (); type FreezeIdentifier = (); type MaxLocks = (); type MaxReserves = (); type MaxHolds = (); type MaxFreezes = (); + type RuntimeHoldReason = (); } parameter_types! { @@ -95,7 +88,6 @@ impl pallet_timestamp::Config for Runtime { impl pallet_living_assets_ownership::Config for Runtime { type RuntimeEvent = RuntimeEvent; - type CollectionId = u64; } pub struct FixedGasPrice; From d858bf01881a1c5c6417b190232f4a8c7b8c484e Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Sat, 5 Aug 2023 15:03:58 +0200 Subject: [PATCH 23/36] refactoring --- runtime/src/precompiles.rs | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/runtime/src/precompiles.rs b/runtime/src/precompiles.rs index 6c2f7b40..14acb723 100644 --- a/runtime/src/precompiles.rs +++ b/runtime/src/precompiles.rs @@ -40,22 +40,20 @@ type Erc721 = Erc721Precompile< pallet_living_assets_ownership::Pallet, >; +impl FrontierPrecompiles { + fn is_erc721_address(&self, address: H160) -> bool { + let first_byte = address.0[0]; + // Check if the first bit is set to 1 + first_byte & 0x80 == 0x80 + } +} + impl PrecompileSet for FrontierPrecompiles where Runtime: pallet_evm::Config + pallet_living_assets_ownership::Config, { fn execute(&self, handle: &mut impl PrecompileHandle) -> Option { - let code_address = handle.code_address(); - - // TODO put the following code in the right place, maybe a fuction in the precompile - let first_byte = code_address.0[0]; - // Check if the first bit is set to 1 - if first_byte & 0x80 == 0x80 { - Some(Erc721::execute(handle)); - () - } - - match code_address { + match handle.code_address() { // Ethereum precompiles : a if a == hash(1) => Some(ECRecover::execute(handle)), a if a == hash(2) => Some(Sha256::execute(handle)), @@ -66,11 +64,16 @@ where // a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), a if a == hash(1026) => Some(LivingAssetsPrecompile::execute(handle)), + a if self.is_erc721_address(a) => Some(Erc721::execute(handle)), _ => None, } } fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { + if self.is_erc721_address(address) { + return IsPrecompileResult::Answer { is_precompile: true, extra_cost: 0 }; + } + IsPrecompileResult::Answer { is_precompile: Self::used_addresses().contains(&address), extra_cost: 0, From 6c65ddde881ba138a8bbf7b59eb66533b52db361 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Sun, 6 Aug 2023 06:19:02 +0200 Subject: [PATCH 24/36] returning address --- precompile/erc721/src/lib.rs | 10 ++++++++-- precompile/erc721/src/tests.rs | 20 +++++++++++++++++--- 2 files changed, 25 insertions(+), 5 deletions(-) diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs index 74a5574d..74fc1aa9 100644 --- a/precompile/erc721/src/lib.rs +++ b/precompile/erc721/src/lib.rs @@ -4,7 +4,9 @@ use fp_evm::{Precompile, PrecompileHandle, PrecompileOutput}; use pallet_living_assets_ownership::traits::Erc721; use parity_scale_codec::Encode; -use precompile_utils::{succeed, EvmResult, FunctionModifier, PrecompileHandleExt}; +use precompile_utils::{ + succeed, Address, EvmDataWriter, EvmResult, FunctionModifier, PrecompileHandleExt, +}; use sp_core::H160; use sp_std::{fmt::Debug, marker::PhantomData}; @@ -46,7 +48,11 @@ where Action::TockenURI => { todo!() }, - Action::OwnerOf => Ok(succeed(H160::zero().encode())), + Action::OwnerOf => { + let byte20 = H160::zero(); + let address = Address::from(byte20); + Ok(succeed(EvmDataWriter::new().write(address).build())) + }, } } } diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs index 16c8a9e6..06e78cd2 100644 --- a/precompile/erc721/src/tests.rs +++ b/precompile/erc721/src/tests.rs @@ -13,16 +13,30 @@ fn check_selectors() { } #[test] -fn create_collection_should_return_address() { +fn owner_of_unexistent_should_return_null_address() { impl_precompile_mock_simple!(Mock, None); - let owner_of_1234 = "6352211e00000000000000000000000000000000000000000000000000000000000004d2"; + let owner_of_1234 = "6352211e0000000000000000000000000000000000000000000000000000000000000004"; let mut handle = create_mock_handle_from_input(owner_of_1234); let result = Mock::execute(&mut handle); assert!(result.is_ok()); - assert_eq!(result.unwrap().output, H160::zero().encode()); + assert_eq!(result.unwrap().output, vec![0u8; 32]); } +// #[test] +// fn owner_of() { +// impl_precompile_mock!(Mock, |collection_id, asset_id| { +// assert_eq!(collection_id, 0); +// assert_eq!(asset_id, U256::from("0x1234")); +// Some(H160::from(2)) +// }); + +// let owner_of_1234 = "6352211e0000000000000000000000000000000000000000000000000000000000001234"; +// let mut handle = create_mock_handle_from_input(owner_of_1234); +// let result = Mock::execute(&mut handle); +// assert!(result.is_ok()); +// assert_eq!(result.unwrap().output, H160::zero().encode()); +// } mod helpers { use evm::{Context, ExitError, ExitReason, Transfer}; use fp_evm::{Log, PrecompileHandle}; From 1c9e12a64770b9a589810f02e75480ba9d498bd3 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 11:13:46 +0200 Subject: [PATCH 25/36] return value is correctly encoded as a n Address --- precompile/living-assets/src/lib.rs | 5 +++-- precompile/living-assets/src/tests.rs | 15 ++++++--------- 2 files changed, 9 insertions(+), 11 deletions(-) diff --git a/precompile/living-assets/src/lib.rs b/precompile/living-assets/src/lib.rs index 1ee99544..ec9e1ffc 100644 --- a/precompile/living-assets/src/lib.rs +++ b/precompile/living-assets/src/lib.rs @@ -5,7 +5,8 @@ use fp_evm::{ExitError, Precompile, PrecompileFailure, PrecompileHandle, Precomp use pallet_living_assets_ownership::{traits::CollectionManager, CollectionId}; use parity_scale_codec::Encode; use precompile_utils::{ - keccak256, succeed, EvmResult, FunctionModifier, LogExt, LogsBuilder, PrecompileHandleExt, + keccak256, succeed, Address, EvmDataWriter, EvmResult, FunctionModifier, LogExt, LogsBuilder, + PrecompileHandleExt, }; use sp_runtime::SaturatedConversion; @@ -60,7 +61,7 @@ where .log2(SELECTOR_LOG_CREATE_COLLECTION, collection_address, Vec::new()) .record(handle)?; - Ok(succeed(collection_address.encode())) + Ok(succeed(EvmDataWriter::new().write(Address(collection_address)).build())) }, Err(err) => Err(PrecompileFailure::Error { exit_status: ExitError::Other(sp_std::borrow::Cow::Borrowed(err)), diff --git a/precompile/living-assets/src/tests.rs b/precompile/living-assets/src/tests.rs index 73ca99f4..ff2e058b 100644 --- a/precompile/living-assets/src/tests.rs +++ b/precompile/living-assets/src/tests.rs @@ -6,7 +6,7 @@ use super::*; use evm::ExitRevert; use helpers::*; -use sp_core::{H160, H256}; +use sp_core::H160; use sp_std::vec::Vec; type CollectionId = u64; @@ -60,14 +60,14 @@ fn create_collection_should_return_address() { assert!(result.is_ok()); // check that the output is the collection id 0 assert_eq!( - result.unwrap().output, - hex::decode("8000000000000000000000000000000000000005").unwrap() + hex::encode(result.unwrap().output), + "0000000000000000000000008000000000000000000000000000000000000005" ); } #[test] fn create_collection_should_generate_log() { - impl_precompile_mock_simple!(Mock, Ok(5), Some(H160::zero())); + impl_precompile_mock_simple!(Mock, Ok(0xffff), Some(H160::zero())); let mut handle = create_mock_handle_from_input(CREATE_COLLECTION); let result = Mock::execute(&mut handle); @@ -78,11 +78,8 @@ fn create_collection_should_generate_log() { assert_eq!(logs[0].topics.len(), 2); assert_eq!(logs[0].topics[0], SELECTOR_LOG_CREATE_COLLECTION.into()); assert_eq!( - logs[0].topics[1], - H256::from_slice( - &hex::decode("0000000000000000000000008000000000000000000000000000000000000005") - .unwrap() - ) + hex::encode(logs[0].topics[1]), + "000000000000000000000000800000000000000000000000000000000000ffff" ); assert_eq!(logs[0].data, Vec::::new()); } From 9dc0c14d28bf329dad6015f0889151a7cf6590a1 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 12:08:26 +0200 Subject: [PATCH 26/36] is_erc721_contract is not member of PrecompoileSet --- runtime/src/precompiles/mod.rs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/runtime/src/precompiles/mod.rs b/runtime/src/precompiles/mod.rs index 9f43ab66..3266b603 100644 --- a/runtime/src/precompiles/mod.rs +++ b/runtime/src/precompiles/mod.rs @@ -40,14 +40,6 @@ type Erc721 = Erc721Precompile< pallet_living_assets_ownership::Pallet, >; -impl FrontierPrecompiles { - fn is_erc721_address(&self, address: H160) -> bool { - let first_byte = address.0[0]; - // Check if the first bit is set to 1 - first_byte & 0x80 == 0x80 - } -} - impl PrecompileSet for FrontierPrecompiles where Runtime: pallet_evm::Config + pallet_living_assets_ownership::Config, @@ -64,13 +56,13 @@ where // a if a == hash(1024) => Some(Sha3FIPS256::execute(handle)), a if a == hash(1025) => Some(ECRecoverPublicKey::execute(handle)), a if a == hash(1026) => Some(LivingAssetsPrecompile::execute(handle)), - a if self.is_erc721_address(a) => Some(Erc721::execute(handle)), + a if is_erc721_address(a) => Some(Erc721::execute(handle)), _ => None, } } fn is_precompile(&self, address: H160, _gas: u64) -> IsPrecompileResult { - if self.is_erc721_address(address) { + if is_erc721_address(address) { return IsPrecompileResult::Answer { is_precompile: true, extra_cost: 0 }; } @@ -85,6 +77,12 @@ fn hash(a: u64) -> H160 { H160::from_low_u64_be(a) } +fn is_erc721_address(address: H160) -> bool { + let first_byte = address.0[0]; + // Check if the first bit is set to 1 + first_byte & 0x80 == 0x80 +} + #[cfg(test)] mod mock; From b9bba2dfde9f3f6e193e153f761374529afab738 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 12:46:14 +0200 Subject: [PATCH 27/36] test on precompiled contracts --- runtime/src/precompiles/test.rs | 34 ++++++++++++++++++++++++++++++++- 1 file changed, 33 insertions(+), 1 deletion(-) diff --git a/runtime/src/precompiles/test.rs b/runtime/src/precompiles/test.rs index f9c475da..83698b01 100644 --- a/runtime/src/precompiles/test.rs +++ b/runtime/src/precompiles/test.rs @@ -1,4 +1,5 @@ -use super::{hash, mock::*, FrontierPrecompiles}; +use super::{hash, is_erc721_address, mock::*, FrontierPrecompiles}; +use core::str::FromStr; use pallet_evm::{IsPrecompileResult, PrecompileSet}; use sp_core::H160; @@ -22,4 +23,35 @@ fn ethereum_precompiled_addresses_are_precompile() { assert!(is_precompile(hash(3)).unwrap()); assert!(is_precompile(hash(4)).unwrap()); assert!(is_precompile(hash(5)).unwrap()); + assert!(is_precompile(hash(1026)).unwrap()); + assert!(is_precompile(H160::from_str("0x8000000000000000000000000000000000000001").unwrap()) + .unwrap()); +} + +#[test] +fn check_for_erc721_addresses() { + assert!(!is_erc721_address( + H160::from_str("0x1000000000000000000000000000000000000001").unwrap() + )); + assert!(is_erc721_address( + H160::from_str("0x8000000000000000000000000000000000000000").unwrap() + )); + assert!(is_erc721_address( + H160::from_str("0x8000000000000000000000000000000000000001").unwrap() + )); + assert!(is_erc721_address( + H160::from_str("0x8000000000000000000000000000000000000002").unwrap() + )); + assert!(is_erc721_address( + H160::from_str("0x8000000000000000000000000000000000000003").unwrap() + )); + assert!(is_erc721_address( + H160::from_str("0x80000000000000000000000000000000ffffffff").unwrap() + )); + assert!(!is_erc721_address( + H160::from_str("0x7fffffffffffffffffffffffffffffffffffffff").unwrap() + )); + assert!(is_erc721_address( + H160::from_str("0xffffffffffffffffffffffffffffffffffffffff").unwrap() + )); } From a39432cc875890da4e151e9445b560ee26e7eddb Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 12:51:29 +0200 Subject: [PATCH 28/36] erc721 returns hardcoded address --- precompile/erc721/src/lib.rs | 7 ++++--- precompile/erc721/src/tests.rs | 5 ++++- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs index 74fc1aa9..65168177 100644 --- a/precompile/erc721/src/lib.rs +++ b/precompile/erc721/src/lib.rs @@ -1,6 +1,8 @@ //! Living Assets precompile module. #![cfg_attr(not(feature = "std"), no_std)] +use core::str::FromStr; + use fp_evm::{Precompile, PrecompileHandle, PrecompileOutput}; use pallet_living_assets_ownership::traits::Erc721; use parity_scale_codec::Encode; @@ -49,9 +51,8 @@ where todo!() }, Action::OwnerOf => { - let byte20 = H160::zero(); - let address = Address::from(byte20); - Ok(succeed(EvmDataWriter::new().write(address).build())) + let address = H160::from_str("0x0000000000000000000000000000000012345678").unwrap(); + Ok(succeed(EvmDataWriter::new().write(Address(address)).build())) }, } } diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs index 06e78cd2..f519e102 100644 --- a/precompile/erc721/src/tests.rs +++ b/precompile/erc721/src/tests.rs @@ -20,7 +20,10 @@ fn owner_of_unexistent_should_return_null_address() { let mut handle = create_mock_handle_from_input(owner_of_1234); let result = Mock::execute(&mut handle); assert!(result.is_ok()); - assert_eq!(result.unwrap().output, vec![0u8; 32]); + assert_eq!( + hex::encode(result.unwrap().output), + "0000000000000000000000000000000000000000000000000000000012345678" + ); } // #[test] From c4cd42f1ac747c9aba56491750f394df5b338b38 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 15:40:28 +0200 Subject: [PATCH 29/36] refactoring --- Cargo.lock | 2 ++ pallets/living-assets-ownership/Cargo.toml | 2 ++ pallets/living-assets-ownership/src/lib.rs | 13 +++++++++++++ pallets/living-assets-ownership/src/tests.rs | 17 +++++++++++++++++ precompile/living-assets/src/lib.rs | 16 +++------------- precompile/living-assets/src/tests.rs | 9 --------- 6 files changed, 37 insertions(+), 22 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 369d6c12..c99b7a51 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7178,6 +7178,8 @@ dependencies = [ "frame-benchmarking", "frame-support", "frame-system", + "hex", + "hex-literal 0.4.1", "parity-scale-codec", "scale-info", "serde", diff --git a/pallets/living-assets-ownership/Cargo.toml b/pallets/living-assets-ownership/Cargo.toml index 47227a05..ce931860 100644 --- a/pallets/living-assets-ownership/Cargo.toml +++ b/pallets/living-assets-ownership/Cargo.toml @@ -12,6 +12,7 @@ edition = "2021" targets = ["x86_64-unknown-linux-gnu"] [dependencies] +hex-literal = { workspace = true, optional = true} parity-scale-codec = { workspace = true, features = ["derive"] } scale-info = { workspace = true, features = ["derive"] } @@ -24,6 +25,7 @@ sp-core = { workspace = true } [dev-dependencies] serde = { workspace = true } +hex = { version = "0.4.3" } # Substrate sp-core = { workspace = true } diff --git a/pallets/living-assets-ownership/src/lib.rs b/pallets/living-assets-ownership/src/lib.rs index 1ac933a7..a7ebdce0 100644 --- a/pallets/living-assets-ownership/src/lib.rs +++ b/pallets/living-assets-ownership/src/lib.rs @@ -4,6 +4,7 @@ /// Learn more about FRAME and the core library of Substrate FRAME pallets: /// pub use pallet::*; +use sp_core::H160; mod functions; pub mod traits; @@ -97,6 +98,18 @@ pub mod pallet { } } +pub fn collection_id_to_address(collection_id: CollectionId) -> H160 { + let mut address = H160::from_low_u64_be(collection_id); + address.0[0] |= 0x80; // Set the first bit to 1 + address +} + +pub fn address_to_collection_id(address: H160) -> CollectionId { + let bytes: [u8; 20] = address.into(); + let id_bytes: [u8; 8] = bytes[12..20].try_into().expect("Slice length doesn't match"); + CollectionId::from_be_bytes(id_bytes) +} + #[cfg(test)] mod mock; diff --git a/pallets/living-assets-ownership/src/tests.rs b/pallets/living-assets-ownership/src/tests.rs index 7d663c12..603fe1d6 100644 --- a/pallets/living-assets-ownership/src/tests.rs +++ b/pallets/living-assets-ownership/src/tests.rs @@ -1,4 +1,7 @@ +use core::str::FromStr; + use crate::{ + address_to_collection_id, collection_id_to_address, mock::*, traits::{CollectionManager, Erc721}, Event, @@ -131,3 +134,17 @@ fn erc721_owner_of_asset_of_collection() { ); }); } + +#[test] +fn test_collection_id_to_address() { + let collection_id: u64 = 5; + let expected_address = H160::from_str("8000000000000000000000000000000000000005").unwrap(); + assert_eq!(collection_id_to_address(collection_id), expected_address); +} + +#[test] +fn test_address_to_collection_id() { + let address = H160::from_str("8000000000000000000000000000000000000005").unwrap(); + let collection_it = address_to_collection_id(address); + assert_eq!(collection_it, 5); +} diff --git a/precompile/living-assets/src/lib.rs b/precompile/living-assets/src/lib.rs index ec9e1ffc..da770c8c 100644 --- a/precompile/living-assets/src/lib.rs +++ b/precompile/living-assets/src/lib.rs @@ -2,7 +2,9 @@ #![cfg_attr(not(feature = "std"), no_std)] use fp_evm::{ExitError, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput}; -use pallet_living_assets_ownership::{traits::CollectionManager, CollectionId}; +use pallet_living_assets_ownership::{ + collection_id_to_address, traits::CollectionManager, CollectionId, +}; use parity_scale_codec::Encode; use precompile_utils::{ keccak256, succeed, Address, EvmDataWriter, EvmResult, FunctionModifier, LogExt, LogsBuilder, @@ -72,17 +74,5 @@ where } } -/// Converts a `u64` collection ID to an `H160` address. -/// -/// This function takes a `u64` collection ID and converts it into an `H160` address by using the -/// `from_low_u64_be` method to convert the `u64` value into the lower 64 bits of the `H160`. -/// Additionally, the function sets the first bit of the resulting `H160` to 1, which can be used to -/// distinguish addresses created by this function from other addresses. -fn collection_id_to_address(collection_id: CollectionId) -> H160 { - let mut address = H160::from_low_u64_be(collection_id); - address.0[0] |= 0x80; // Set the first bit to 1 - address -} - #[cfg(test)] mod tests; diff --git a/precompile/living-assets/src/tests.rs b/precompile/living-assets/src/tests.rs index 16f83ac1..6c52a568 100644 --- a/precompile/living-assets/src/tests.rs +++ b/precompile/living-assets/src/tests.rs @@ -27,15 +27,6 @@ fn check_log_selectors() { ); } -#[test] -fn test_collection_id_to_address() { - let collection_id: u64 = 5; - let hex_value = "8000000000000000000000000000000000000005"; - let bytes = hex::decode(hex_value).expect("Decoding failed"); - let expected_address = H160::from_slice(&bytes); - assert_eq!(collection_id_to_address(collection_id), expected_address); -} - #[test] fn failing_create_collection_should_return_error() { impl_precompile_mock_simple!(Mock, Err("spaghetti code"), Some(H160::zero())); From 89af0a0088a8584b94dcbb993365b05e96faa38d Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 16:03:17 +0200 Subject: [PATCH 30/36] testing return of asset ownership --- precompile/erc721/src/lib.rs | 17 +++++++++++------ precompile/erc721/src/tests.rs | 29 ++++++++++++++++++++++------- 2 files changed, 33 insertions(+), 13 deletions(-) diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs index 65168177..669d6f51 100644 --- a/precompile/erc721/src/lib.rs +++ b/precompile/erc721/src/lib.rs @@ -1,16 +1,14 @@ //! Living Assets precompile module. #![cfg_attr(not(feature = "std"), no_std)] -use core::str::FromStr; - use fp_evm::{Precompile, PrecompileHandle, PrecompileOutput}; -use pallet_living_assets_ownership::traits::Erc721; +use pallet_living_assets_ownership::{address_to_collection_id, traits::Erc721}; use parity_scale_codec::Encode; use precompile_utils::{ succeed, Address, EvmDataWriter, EvmResult, FunctionModifier, PrecompileHandleExt, }; -use sp_core::H160; +use sp_core::U256; use sp_std::{fmt::Debug, marker::PhantomData}; #[precompile_utils_macro::generate_function_selector] @@ -51,8 +49,15 @@ where todo!() }, Action::OwnerOf => { - let address = H160::from_str("0x0000000000000000000000000000000012345678").unwrap(); - Ok(succeed(EvmDataWriter::new().write(Address(address)).build())) + let mut input = handle.read_input()?; + input.expect_arguments(1)?; + + let asset_id: U256 = input.read()?; + + // collection id is encoded into the contract address + let collection_id = address_to_collection_id(handle.code_address()); + let owner = AssetManager::owner_of(collection_id, asset_id).unwrap(); + Ok(succeed(EvmDataWriter::new().write(Address(owner)).build())) }, } } diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs index f519e102..5d385e7a 100644 --- a/precompile/erc721/src/tests.rs +++ b/precompile/erc721/src/tests.rs @@ -1,3 +1,5 @@ +use core::str::FromStr; + use super::*; use helpers::*; use pallet_living_assets_ownership::CollectionId; @@ -13,16 +15,20 @@ fn check_selectors() { } #[test] -fn owner_of_unexistent_should_return_null_address() { - impl_precompile_mock_simple!(Mock, None); +fn owner_of_asset_should_return_an_address() { + impl_precompile_mock_simple!( + Mock, + Some(H160::from_str("ff00000000000000000000000000000012345678").unwrap()) + ); - let owner_of_1234 = "6352211e0000000000000000000000000000000000000000000000000000000000000004"; - let mut handle = create_mock_handle_from_input(owner_of_1234); + let owner_of_asset_4 = + "6352211e0000000000000000000000000000000000000000000000000000000000000004"; + let mut handle = create_mock_handle_from_input(owner_of_asset_4); let result = Mock::execute(&mut handle); assert!(result.is_ok()); assert_eq!( hex::encode(result.unwrap().output), - "0000000000000000000000000000000000000000000000000000000012345678" + "000000000000000000000000ff00000000000000000000000000000012345678", ); } @@ -154,11 +160,20 @@ mod helpers { pub is_static: bool, pub gas_used: u64, pub logs: Vec, + pub code_address: H160, } impl MockHandle { pub fn new(input: Vec, gas_limit: Option, context: Context) -> Self { - Self { input, gas_limit, context, is_static: false, gas_used: 0, logs: vec![] } + Self { + input, + gas_limit, + context, + is_static: false, + gas_used: 0, + logs: vec![], + code_address: H160::zero(), + } } } @@ -208,7 +223,7 @@ mod helpers { } fn code_address(&self) -> H160 { - unimplemented!() + self.code_address } fn input(&self) -> &[u8] { From c6c78102ac29e4ef4315895c0cbf9c396bcf8750 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 16:18:55 +0200 Subject: [PATCH 31/36] fix errors --- pallets/living-assets-ownership/src/lib.rs | 6 ++--- pallets/living-assets-ownership/src/tests.rs | 5 +++- pallets/living-assets-ownership/src/traits.rs | 2 +- precompile/erc721/src/lib.rs | 10 ++++--- precompile/erc721/src/tests.rs | 26 +++++++++++++++++-- 5 files changed, 39 insertions(+), 10 deletions(-) diff --git a/pallets/living-assets-ownership/src/lib.rs b/pallets/living-assets-ownership/src/lib.rs index a7ebdce0..9cfe5ced 100644 --- a/pallets/living-assets-ownership/src/lib.rs +++ b/pallets/living-assets-ownership/src/lib.rs @@ -89,10 +89,10 @@ pub mod pallet { } impl traits::Erc721 for Pallet { - fn owner_of(collection_id: CollectionId, asset_id: U256) -> Option { + fn owner_of(collection_id: CollectionId, asset_id: U256) -> Result { match OwnerOfCollection::::get(collection_id) { - Some(_) => Some(convert_asset_id_to_owner(asset_id)), - None => None, + Some(_) => Ok(convert_asset_id_to_owner(asset_id)), + None => Err("Collection does not exist"), } } } diff --git a/pallets/living-assets-ownership/src/tests.rs b/pallets/living-assets-ownership/src/tests.rs index 603fe1d6..91f1bb91 100644 --- a/pallets/living-assets-ownership/src/tests.rs +++ b/pallets/living-assets-ownership/src/tests.rs @@ -119,7 +119,10 @@ fn living_assets_ownership_trait_id_of_new_collection_should_be_consecutive() { #[test] fn erc721_owner_of_asset_of_unexistent_collection() { new_test_ext().execute_with(|| { - assert_eq!(::owner_of(0, 2.into()), None); + assert_eq!( + ::owner_of(0, 2.into()), + Err("Collection does not exist") + ); }); } diff --git a/pallets/living-assets-ownership/src/traits.rs b/pallets/living-assets-ownership/src/traits.rs index 500cd5c8..2e1e8d86 100644 --- a/pallets/living-assets-ownership/src/traits.rs +++ b/pallets/living-assets-ownership/src/traits.rs @@ -29,5 +29,5 @@ pub trait CollectionManager { } pub trait Erc721 { - fn owner_of(collection_id: CollectionId, asset_id: U256) -> Option; + fn owner_of(collection_id: CollectionId, asset_id: U256) -> Result; } diff --git a/precompile/erc721/src/lib.rs b/precompile/erc721/src/lib.rs index 669d6f51..928fb02e 100644 --- a/precompile/erc721/src/lib.rs +++ b/precompile/erc721/src/lib.rs @@ -1,7 +1,7 @@ //! Living Assets precompile module. #![cfg_attr(not(feature = "std"), no_std)] -use fp_evm::{Precompile, PrecompileHandle, PrecompileOutput}; +use fp_evm::{ExitError, Precompile, PrecompileFailure, PrecompileHandle, PrecompileOutput}; use pallet_living_assets_ownership::{address_to_collection_id, traits::Erc721}; use parity_scale_codec::Encode; use precompile_utils::{ @@ -56,8 +56,12 @@ where // collection id is encoded into the contract address let collection_id = address_to_collection_id(handle.code_address()); - let owner = AssetManager::owner_of(collection_id, asset_id).unwrap(); - Ok(succeed(EvmDataWriter::new().write(Address(owner)).build())) + match AssetManager::owner_of(collection_id, asset_id) { + Ok(owner) => Ok(succeed(EvmDataWriter::new().write(Address(owner)).build())), + Err(err) => Err(PrecompileFailure::Error { + exit_status: ExitError::Other(sp_std::borrow::Cow::Borrowed(err)), + }), + } }, } } diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs index 5d385e7a..a9744889 100644 --- a/precompile/erc721/src/tests.rs +++ b/precompile/erc721/src/tests.rs @@ -1,6 +1,8 @@ use core::str::FromStr; use super::*; +use evm::ExitError; +use fp_evm::PrecompileFailure; use helpers::*; use pallet_living_assets_ownership::CollectionId; use sp_core::{H160, U256}; @@ -18,7 +20,7 @@ fn check_selectors() { fn owner_of_asset_should_return_an_address() { impl_precompile_mock_simple!( Mock, - Some(H160::from_str("ff00000000000000000000000000000012345678").unwrap()) + Ok(H160::from_str("ff00000000000000000000000000000012345678").unwrap()) ); let owner_of_asset_4 = @@ -32,6 +34,23 @@ fn owner_of_asset_should_return_an_address() { ); } +#[test] +fn owner_of_if_fails_returns_error() { + impl_precompile_mock_simple!(Mock, Err("spaghetti error")); + + let owner_of_asset_4 = + "6352211e0000000000000000000000000000000000000000000000000000000000000004"; + let mut handle = create_mock_handle_from_input(owner_of_asset_4); + let result = Mock::execute(&mut handle); + assert!(result.is_err()); + assert_eq!( + result.unwrap_err(), + PrecompileFailure::Error { + exit_status: ExitError::Other(sp_std::borrow::Cow::Borrowed("spaghetti error")) + } + ); +} + // #[test] // fn owner_of() { // impl_precompile_mock!(Mock, |collection_id, asset_id| { @@ -78,7 +97,10 @@ mod helpers { struct Erc721Mock; impl pallet_living_assets_ownership::traits::Erc721 for Erc721Mock { - fn owner_of(collectio_id: CollectionId, asset_id: U256) -> Option { + fn owner_of( + collectio_id: CollectionId, + asset_id: U256, + ) -> Result { ($owner_of_collection)(collectio_id, asset_id) } } From 5cfb2b54fd85543850780c8ba6e7c9d37a99fc82 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 16:21:27 +0200 Subject: [PATCH 32/36] remove unused use --- precompile/living-assets/src/lib.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/precompile/living-assets/src/lib.rs b/precompile/living-assets/src/lib.rs index da770c8c..a7956049 100644 --- a/precompile/living-assets/src/lib.rs +++ b/precompile/living-assets/src/lib.rs @@ -12,7 +12,6 @@ use precompile_utils::{ }; use sp_runtime::SaturatedConversion; -use sp_core::H160; use sp_std::{fmt::Debug, marker::PhantomData, vec::Vec}; /// Solidity selector of the CreateCollection log, which is the Keccak of the Log signature. From 0568c47c1554fc5715a05c2cfc06cb9e373373de Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 20:54:19 +0200 Subject: [PATCH 33/36] refactoring --- precompile/erc721/Cargo.toml | 1 + precompile/erc721/src/tests.rs | 96 +-------------------------- precompile/living-assets/Cargo.toml | 1 + precompile/living-assets/src/tests.rs | 87 +----------------------- precompile/utils/src/lib.rs | 2 + precompile/utils/src/mock.rs | 83 +++++++++++++++++++++++ precompile/utils/src/testing.rs | 12 ++++ 7 files changed, 105 insertions(+), 177 deletions(-) create mode 100644 precompile/utils/src/mock.rs diff --git a/precompile/erc721/Cargo.toml b/precompile/erc721/Cargo.toml index 47304b70..04d19196 100644 --- a/precompile/erc721/Cargo.toml +++ b/precompile/erc721/Cargo.toml @@ -34,6 +34,7 @@ num_enum = { workspace = true } [dev-dependencies] evm = { workspace = true } hex = { version = "0.4.3" } +precompile-utils = { workspace = true, features = ["testing"]} [features] default = ["std"] diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs index a9744889..b28a3201 100644 --- a/precompile/erc721/src/tests.rs +++ b/precompile/erc721/src/tests.rs @@ -66,9 +66,9 @@ fn owner_of_if_fails_returns_error() { // assert_eq!(result.unwrap().output, H160::zero().encode()); // } mod helpers { - use evm::{Context, ExitError, ExitReason, Transfer}; - use fp_evm::{Log, PrecompileHandle}; - use sp_core::{H160, H256}; + use evm::Context; + use precompile_utils::mock::MockHandle; + use sp_core::H160; /// Macro to define a precompile mock with custom closures for testing. /// @@ -174,94 +174,4 @@ mod helpers { pub fn create_mock_handle_from_input(input: &str) -> MockHandle { create_mock_handle(input, 0, 0, H160::zero()) } - - pub struct MockHandle { - pub input: Vec, - pub gas_limit: Option, - pub context: Context, - pub is_static: bool, - pub gas_used: u64, - pub logs: Vec, - pub code_address: H160, - } - - impl MockHandle { - pub fn new(input: Vec, gas_limit: Option, context: Context) -> Self { - Self { - input, - gas_limit, - context, - is_static: false, - gas_used: 0, - logs: vec![], - code_address: H160::zero(), - } - } - } - - impl PrecompileHandle for MockHandle { - /// Perform subcall in provided context. - /// Precompile specifies in which context the subcall is executed. - fn call( - &mut self, - _: H160, - _: Option, - _: Vec, - _: Option, - _: bool, - _: &Context, - ) -> (ExitReason, Vec) { - unimplemented!() - } - - fn record_cost(&mut self, cost: u64) -> Result<(), ExitError> { - self.gas_used += cost; - Ok(()) - } - - fn record_external_cost( - &mut self, - _: Option, - _: Option, - ) -> Result<(), ExitError> { - Ok(()) - } - - fn refund_external_cost(&mut self, _: Option, _: Option) {} - - fn log( - &mut self, - address: H160, - topics: Vec, - data: Vec, - ) -> Result<(), ExitError> { - let log = Log { address, topics, data }; - self.logs.push(log); - Ok(()) - } - - fn remaining_gas(&self) -> u64 { - unimplemented!() - } - - fn code_address(&self) -> H160 { - self.code_address - } - - fn input(&self) -> &[u8] { - &self.input - } - - fn context(&self) -> &Context { - &self.context - } - - fn is_static(&self) -> bool { - self.is_static - } - - fn gas_limit(&self) -> Option { - self.gas_limit - } - } } diff --git a/precompile/living-assets/Cargo.toml b/precompile/living-assets/Cargo.toml index 9edd2bdc..57d0c67c 100644 --- a/precompile/living-assets/Cargo.toml +++ b/precompile/living-assets/Cargo.toml @@ -38,6 +38,7 @@ num_enum = { workspace = true } [dev-dependencies] evm = { workspace = true } hex = { version = "0.4.3" } +precompile-utils = { workspace = true, features = ["testing"]} [features] default = ["std"] diff --git a/precompile/living-assets/src/tests.rs b/precompile/living-assets/src/tests.rs index 5a212fb9..e372311b 100644 --- a/precompile/living-assets/src/tests.rs +++ b/precompile/living-assets/src/tests.rs @@ -123,9 +123,9 @@ fn call_unexistent_selector_should_fail() { } mod helpers { - use evm::{Context, ExitError, ExitReason, Transfer}; - use fp_evm::{Log, PrecompileHandle}; - use sp_core::{H160, H256}; + use evm::Context; + use precompile_utils::mock::MockHandle; + use sp_core::H160; /// Macro to define a precompile mock for testing. /// @@ -235,85 +235,4 @@ mod helpers { pub fn create_mock_handle_from_input(input: &str) -> MockHandle { create_mock_handle(input, 0, 0, H160::zero()) } - - pub struct MockHandle { - pub input: Vec, - pub gas_limit: Option, - pub context: Context, - pub is_static: bool, - pub gas_used: u64, - pub logs: Vec, - } - - impl MockHandle { - pub fn new(input: Vec, gas_limit: Option, context: Context) -> Self { - Self { input, gas_limit, context, is_static: false, gas_used: 0, logs: vec![] } - } - } - - impl PrecompileHandle for MockHandle { - /// Perform subcall in provided context. - /// Precompile specifies in which context the subcall is executed. - fn call( - &mut self, - _: H160, - _: Option, - _: Vec, - _: Option, - _: bool, - _: &Context, - ) -> (ExitReason, Vec) { - unimplemented!() - } - - fn record_cost(&mut self, cost: u64) -> Result<(), ExitError> { - self.gas_used += cost; - Ok(()) - } - - fn record_external_cost( - &mut self, - _: Option, - _: Option, - ) -> Result<(), ExitError> { - Ok(()) - } - - fn refund_external_cost(&mut self, _: Option, _: Option) {} - - fn log( - &mut self, - address: H160, - topics: Vec, - data: Vec, - ) -> Result<(), ExitError> { - let log = Log { address, topics, data }; - self.logs.push(log); - Ok(()) - } - - fn remaining_gas(&self) -> u64 { - unimplemented!() - } - - fn code_address(&self) -> H160 { - unimplemented!() - } - - fn input(&self) -> &[u8] { - &self.input - } - - fn context(&self) -> &Context { - &self.context - } - - fn is_static(&self) -> bool { - self.is_static - } - - fn gas_limit(&self) -> Option { - self.gas_limit - } - } } diff --git a/precompile/utils/src/lib.rs b/precompile/utils/src/lib.rs index 9f23028e..15880bcc 100644 --- a/precompile/utils/src/lib.rs +++ b/precompile/utils/src/lib.rs @@ -40,6 +40,8 @@ mod data; pub use data::{Address, Bytes, EvmData, EvmDataReader, EvmDataWriter}; pub use precompile_utils_macro::{generate_function_selector, keccak256}; +#[cfg(feature = "testing")] +pub mod mock; #[cfg(feature = "testing")] pub mod testing; #[cfg(test)] diff --git a/precompile/utils/src/mock.rs b/precompile/utils/src/mock.rs new file mode 100644 index 00000000..d1ef955d --- /dev/null +++ b/precompile/utils/src/mock.rs @@ -0,0 +1,83 @@ +use super::*; +use fp_evm::{ExitReason, Transfer}; + +pub struct MockHandle { + pub input: Vec, + pub gas_limit: Option, + pub context: Context, + pub is_static: bool, + pub gas_used: u64, + pub logs: Vec, + pub code_address: H160, +} + +impl MockHandle { + pub fn new(input: Vec, gas_limit: Option, context: Context) -> Self { + Self { + input, + gas_limit, + context, + is_static: false, + gas_used: 0, + logs: vec![], + code_address: H160::zero(), + } + } +} + +impl PrecompileHandle for MockHandle { + /// Perform subcall in provided context. + /// Precompile specifies in which context the subcall is executed. + fn call( + &mut self, + _: H160, + _: Option, + _: Vec, + _: Option, + _: bool, + _: &Context, + ) -> (ExitReason, Vec) { + unimplemented!() + } + + fn record_cost(&mut self, cost: u64) -> Result<(), ExitError> { + self.gas_used += cost; + Ok(()) + } + + fn record_external_cost(&mut self, _: Option, _: Option) -> Result<(), ExitError> { + Ok(()) + } + + fn refund_external_cost(&mut self, _: Option, _: Option) {} + + fn log(&mut self, address: H160, topics: Vec, data: Vec) -> Result<(), ExitError> { + let log = Log { address, topics, data }; + self.logs.push(log); + Ok(()) + } + + fn remaining_gas(&self) -> u64 { + unimplemented!() + } + + fn code_address(&self) -> H160 { + self.code_address + } + + fn input(&self) -> &[u8] { + &self.input + } + + fn context(&self) -> &Context { + &self.context + } + + fn is_static(&self) -> bool { + self.is_static + } + + fn gas_limit(&self) -> Option { + self.gas_limit + } +} diff --git a/precompile/utils/src/testing.rs b/precompile/utils/src/testing.rs index 8733bbd7..c96ec567 100644 --- a/precompile/utils/src/testing.rs +++ b/precompile/utils/src/testing.rs @@ -224,6 +224,18 @@ impl PrecompileHandle for MockHandle { fn gas_limit(&self) -> Option { Some(self.gas_limit) } + + fn record_external_cost( + &mut self, + _ref_time: Option, + _proof_size: Option, + ) -> Result<(), ExitError> { + todo!() + } + + fn refund_external_cost(&mut self, _ref_time: Option, _proof_size: Option) { + todo!() + } } pub struct PrecompilesTester<'p, P> { From b31f1db259e19cc9f2c435494a3a82a0d09fbcc2 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 20:58:24 +0200 Subject: [PATCH 34/36] rewriting testing mod --- precompile/erc721/src/tests.rs | 2 +- precompile/living-assets/src/tests.rs | 2 +- precompile/utils/src/lib.rs | 2 - precompile/utils/src/mock.rs | 83 ------ precompile/utils/src/testing.rs | 399 ++------------------------ 5 files changed, 32 insertions(+), 456 deletions(-) delete mode 100644 precompile/utils/src/mock.rs diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs index b28a3201..10e425d2 100644 --- a/precompile/erc721/src/tests.rs +++ b/precompile/erc721/src/tests.rs @@ -67,7 +67,7 @@ fn owner_of_if_fails_returns_error() { // } mod helpers { use evm::Context; - use precompile_utils::mock::MockHandle; + use precompile_utils::testing::MockHandle; use sp_core::H160; /// Macro to define a precompile mock with custom closures for testing. diff --git a/precompile/living-assets/src/tests.rs b/precompile/living-assets/src/tests.rs index e372311b..f7c77907 100644 --- a/precompile/living-assets/src/tests.rs +++ b/precompile/living-assets/src/tests.rs @@ -124,7 +124,7 @@ fn call_unexistent_selector_should_fail() { mod helpers { use evm::Context; - use precompile_utils::mock::MockHandle; + use precompile_utils::testing::MockHandle; use sp_core::H160; /// Macro to define a precompile mock for testing. diff --git a/precompile/utils/src/lib.rs b/precompile/utils/src/lib.rs index 15880bcc..9f23028e 100644 --- a/precompile/utils/src/lib.rs +++ b/precompile/utils/src/lib.rs @@ -40,8 +40,6 @@ mod data; pub use data::{Address, Bytes, EvmData, EvmDataReader, EvmDataWriter}; pub use precompile_utils_macro::{generate_function_selector, keccak256}; -#[cfg(feature = "testing")] -pub mod mock; #[cfg(feature = "testing")] pub mod testing; #[cfg(test)] diff --git a/precompile/utils/src/mock.rs b/precompile/utils/src/mock.rs deleted file mode 100644 index d1ef955d..00000000 --- a/precompile/utils/src/mock.rs +++ /dev/null @@ -1,83 +0,0 @@ -use super::*; -use fp_evm::{ExitReason, Transfer}; - -pub struct MockHandle { - pub input: Vec, - pub gas_limit: Option, - pub context: Context, - pub is_static: bool, - pub gas_used: u64, - pub logs: Vec, - pub code_address: H160, -} - -impl MockHandle { - pub fn new(input: Vec, gas_limit: Option, context: Context) -> Self { - Self { - input, - gas_limit, - context, - is_static: false, - gas_used: 0, - logs: vec![], - code_address: H160::zero(), - } - } -} - -impl PrecompileHandle for MockHandle { - /// Perform subcall in provided context. - /// Precompile specifies in which context the subcall is executed. - fn call( - &mut self, - _: H160, - _: Option, - _: Vec, - _: Option, - _: bool, - _: &Context, - ) -> (ExitReason, Vec) { - unimplemented!() - } - - fn record_cost(&mut self, cost: u64) -> Result<(), ExitError> { - self.gas_used += cost; - Ok(()) - } - - fn record_external_cost(&mut self, _: Option, _: Option) -> Result<(), ExitError> { - Ok(()) - } - - fn refund_external_cost(&mut self, _: Option, _: Option) {} - - fn log(&mut self, address: H160, topics: Vec, data: Vec) -> Result<(), ExitError> { - let log = Log { address, topics, data }; - self.logs.push(log); - Ok(()) - } - - fn remaining_gas(&self) -> u64 { - unimplemented!() - } - - fn code_address(&self) -> H160 { - self.code_address - } - - fn input(&self) -> &[u8] { - &self.input - } - - fn context(&self) -> &Context { - &self.context - } - - fn is_static(&self) -> bool { - self.is_static - } - - fn gas_limit(&self) -> Option { - self.gas_limit - } -} diff --git a/precompile/utils/src/testing.rs b/precompile/utils/src/testing.rs index c96ec567..d1ef955d 100644 --- a/precompile/utils/src/testing.rs +++ b/precompile/utils/src/testing.rs @@ -1,422 +1,83 @@ -// This file is part of Astar. - -// Copyright 2019-2022 PureStake Inc. -// Copyright (C) 2022-2023 Stake Technologies Pte.Ltd. -// SPDX-License-Identifier: GPL-3.0-or-later -// -// This file is part of Utils package, originally developed by Purestake Inc. -// Utils package used in Astar Network in terms of GPLv3. -// -// Utils is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. - -// Utils is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. - -// You should have received a copy of the GNU General Public License -// along with Utils. If not, see . use super::*; -use assert_matches::assert_matches; -use fp_evm::{ - ExitReason, ExitSucceed, PrecompileOutput, PrecompileResult, PrecompileSet, Transfer, -}; -use sp_std::boxed::Box; - -pub struct Subcall { - pub address: H160, - pub transfer: Option, - pub input: Vec, - pub target_gas: Option, - pub is_static: bool, - pub context: Context, -} +use fp_evm::{ExitReason, Transfer}; -pub struct SubcallOutput { - pub reason: ExitReason, - pub output: Vec, - pub cost: u64, - pub logs: Vec, -} - -pub trait SubcallTrait: FnMut(Subcall) -> SubcallOutput + 'static {} - -impl SubcallOutput + 'static> SubcallTrait for T {} - -pub type SubcallHandle = Box; - -/// Mock handle to write tests for precompiles. pub struct MockHandle { - pub gas_limit: u64, - pub gas_used: u64, - pub logs: Vec, - pub subcall_handle: Option, - pub code_address: H160, pub input: Vec, + pub gas_limit: Option, pub context: Context, pub is_static: bool, + pub gas_used: u64, + pub logs: Vec, + pub code_address: H160, } impl MockHandle { - pub fn new(code_address: H160, context: Context) -> Self { + pub fn new(input: Vec, gas_limit: Option, context: Context) -> Self { Self { - gas_limit: u64::MAX, - gas_used: 0, - logs: vec![], - subcall_handle: None, - code_address, - input: Vec::new(), + input, + gas_limit, context, is_static: false, + gas_used: 0, + logs: vec![], + code_address: H160::zero(), } } } -// Compute the cost of doing a subcall. -// Some parameters cannot be known in advance, so we estimate the worst possible cost. -pub fn call_cost(value: U256, config: &evm::Config) -> u64 { - // Copied from EVM code since not public. - pub const G_CALLVALUE: u64 = 9000; - pub const G_NEWACCOUNT: u64 = 25000; - - fn address_access_cost(is_cold: bool, regular_value: u64, config: &evm::Config) -> u64 { - if config.increase_state_access_gas { - if is_cold { - config.gas_account_access_cold - } else { - config.gas_storage_read_warm - } - } else { - regular_value - } - } - - fn xfer_cost(is_call_or_callcode: bool, transfers_value: bool) -> u64 { - if is_call_or_callcode && transfers_value { - G_CALLVALUE - } else { - 0 - } - } - - fn new_cost( - is_call_or_staticcall: bool, - new_account: bool, - transfers_value: bool, - config: &evm::Config, - ) -> u64 { - let eip161 = !config.empty_considered_exists; - if is_call_or_staticcall { - if eip161 { - if transfers_value && new_account { - G_NEWACCOUNT - } else { - 0 - } - } else if new_account { - G_NEWACCOUNT - } else { - 0 - } - } else { - 0 - } - } - - let transfers_value = value != U256::default(); - let is_cold = true; - let is_call_or_callcode = true; - let is_call_or_staticcall = true; - let new_account = true; - - address_access_cost(is_cold, config.gas_call, config) - + xfer_cost(is_call_or_callcode, transfers_value) - + new_cost(is_call_or_staticcall, new_account, transfers_value, config) -} - impl PrecompileHandle for MockHandle { /// Perform subcall in provided context. /// Precompile specifies in which context the subcall is executed. fn call( &mut self, - address: H160, - transfer: Option, - input: Vec, - target_gas: Option, - is_static: bool, - context: &Context, + _: H160, + _: Option, + _: Vec, + _: Option, + _: bool, + _: &Context, ) -> (ExitReason, Vec) { - if self - .record_cost(call_cost(context.apparent_value, &evm::Config::london())) - .is_err() - { - return (ExitReason::Error(ExitError::OutOfGas), vec![]); - } - - match &mut self.subcall_handle { - Some(handle) => { - let SubcallOutput { reason, output, cost, logs } = handle(Subcall { - address, - transfer, - input, - target_gas, - is_static, - context: context.clone(), - }); - - if self.record_cost(cost).is_err() { - return (ExitReason::Error(ExitError::OutOfGas), vec![]); - } - - for log in logs { - self.log(log.address, log.topics, log.data).expect("cannot fail"); - } - - (reason, output) - }, - None => panic!("no subcall handle registered"), - } + unimplemented!() } fn record_cost(&mut self, cost: u64) -> Result<(), ExitError> { self.gas_used += cost; - - if self.gas_used > self.gas_limit { - Err(ExitError::OutOfGas) - } else { - Ok(()) - } + Ok(()) } - fn remaining_gas(&self) -> u64 { - self.gas_limit - self.gas_used + fn record_external_cost(&mut self, _: Option, _: Option) -> Result<(), ExitError> { + Ok(()) } + fn refund_external_cost(&mut self, _: Option, _: Option) {} + fn log(&mut self, address: H160, topics: Vec, data: Vec) -> Result<(), ExitError> { - self.logs.push(PrettyLog(Log { address, topics, data })); + let log = Log { address, topics, data }; + self.logs.push(log); Ok(()) } - /// Retreive the code address (what is the address of the precompile being called). + fn remaining_gas(&self) -> u64 { + unimplemented!() + } + fn code_address(&self) -> H160 { self.code_address } - /// Retreive the input data the precompile is called with. fn input(&self) -> &[u8] { &self.input } - /// Retreive the context in which the precompile is executed. fn context(&self) -> &Context { &self.context } - /// Is the precompile call is done statically. fn is_static(&self) -> bool { self.is_static } - /// Retreive the gas limit of this call. fn gas_limit(&self) -> Option { - Some(self.gas_limit) - } - - fn record_external_cost( - &mut self, - _ref_time: Option, - _proof_size: Option, - ) -> Result<(), ExitError> { - todo!() - } - - fn refund_external_cost(&mut self, _ref_time: Option, _proof_size: Option) { - todo!() - } -} - -pub struct PrecompilesTester<'p, P> { - precompiles: &'p P, - handle: MockHandle, - - target_gas: Option, - subcall_handle: Option, - - expected_cost: Option, - expected_logs: Option>, -} - -impl<'p, P: PrecompileSet> PrecompilesTester<'p, P> { - pub fn new( - precompiles: &'p P, - from: impl Into, - to: impl Into, - data: Vec, - ) -> Self { - let to = to.into(); - let mut handle = MockHandle::new( - to, - Context { address: to, caller: from.into(), apparent_value: U256::zero() }, - ); - - handle.input = data; - - Self { - precompiles, - handle, - - target_gas: None, - subcall_handle: None, - - expected_cost: None, - expected_logs: None, - } - } - - pub fn with_value(mut self, value: impl Into) -> Self { - self.handle.context.apparent_value = value.into(); - self - } - - pub fn with_subcall_handle(mut self, subcall_handle: impl SubcallTrait) -> Self { - self.subcall_handle = Some(Box::new(subcall_handle)); - self - } - - pub fn with_target_gas(mut self, target_gas: Option) -> Self { - self.target_gas = target_gas; - self - } - - pub fn expect_cost(mut self, cost: u64) -> Self { - self.expected_cost = Some(cost); - self - } - - pub fn expect_no_logs(mut self) -> Self { - self.expected_logs = Some(vec![]); - self - } - - pub fn expect_log(mut self, log: Log) -> Self { - self.expected_logs = Some({ - let mut logs = self.expected_logs.unwrap_or_default(); - logs.push(PrettyLog(log)); - logs - }); - self - } - - fn assert_optionals(&self) { - if let Some(cost) = &self.expected_cost { - assert_eq!(&self.handle.gas_used, cost); - } - - if let Some(logs) = &self.expected_logs { - similar_asserts::assert_eq!(&self.handle.logs, logs); - } - } - - fn execute(&mut self) -> Option { - let handle = &mut self.handle; - handle.subcall_handle = self.subcall_handle.take(); - - if let Some(gas_limit) = self.target_gas { - handle.gas_limit = gas_limit; - } - - let res = self.precompiles.execute(handle); - - self.subcall_handle = handle.subcall_handle.take(); - - res - } - - /// Execute the precompile set and expect some precompile to have been executed, regardless of the - /// result. - pub fn execute_some(mut self) { - let res = self.execute(); - assert!(res.is_some()); - self.assert_optionals(); - } - - /// Execute the precompile set and expect no precompile to have been executed. - pub fn execute_none(mut self) { - let res = self.execute(); - assert!(res.is_none()); - self.assert_optionals(); - } - - /// Execute the precompile set and check it returns provided output. - pub fn execute_returns(mut self, output: Vec) { - let res = self.execute(); - assert_eq!(res, Some(Ok(PrecompileOutput { exit_status: ExitSucceed::Returned, output }))); - self.assert_optionals(); - } - - /// Execute the precompile set and check if it reverts. - /// Take a closure allowing to perform custom matching on the output. - pub fn execute_reverts(mut self, check: impl Fn(&[u8]) -> bool) { - let res = self.execute(); - assert_matches!( - res, - Some(Err(PrecompileFailure::Revert { output, ..})) - if check(&output) - ); - self.assert_optionals(); - } - - /// Execute the precompile set and check it returns provided output. - pub fn execute_error(mut self, error: ExitError) { - let res = self.execute(); - assert_eq!(res, Some(Err(PrecompileFailure::Error { exit_status: error }))); - self.assert_optionals(); - } -} - -pub trait PrecompileTesterExt: PrecompileSet + Sized { - fn prepare_test( - &self, - from: impl Into, - to: impl Into, - data: Vec, - ) -> PrecompilesTester; -} - -impl PrecompileTesterExt for T { - fn prepare_test( - &self, - from: impl Into, - to: impl Into, - data: Vec, - ) -> PrecompilesTester { - PrecompilesTester::new(self, from, to, data) - } -} - -#[derive(Clone, PartialEq, Eq)] -pub struct PrettyLog(Log); - -impl core::fmt::Debug for PrettyLog { - fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> Result<(), core::fmt::Error> { - let bytes = self - .0 - .data - .iter() - .map(|b| format!("{:02X}", b)) - .collect::>() - .join(""); - - let message = String::from_utf8(self.0.data.clone()).ok(); - - f.debug_struct("Log") - .field("address", &self.0.address) - .field("topics", &self.0.topics) - .field("data", &bytes) - .field("data_utf8", &message) - .finish() + self.gas_limit } } From 9a4f1006ef6f4f531459a5aa1233affaa8f794c5 Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Mon, 7 Aug 2023 21:09:15 +0200 Subject: [PATCH 35/36] refactoring --- precompile/erc721/src/tests.rs | 55 ++------------------- precompile/living-assets/src/tests.rs | 69 ++++++--------------------- precompile/utils/src/testing.rs | 41 ++++++++++++++++ 3 files changed, 61 insertions(+), 104 deletions(-) diff --git a/precompile/erc721/src/tests.rs b/precompile/erc721/src/tests.rs index 10e425d2..79d07ab9 100644 --- a/precompile/erc721/src/tests.rs +++ b/precompile/erc721/src/tests.rs @@ -3,8 +3,8 @@ use core::str::FromStr; use super::*; use evm::ExitError; use fp_evm::PrecompileFailure; -use helpers::*; use pallet_living_assets_ownership::CollectionId; +use precompile_utils::testing::create_mock_handle_from_input; use sp_core::{H160, U256}; type AccountId = H160; @@ -24,7 +24,8 @@ fn owner_of_asset_should_return_an_address() { ); let owner_of_asset_4 = - "6352211e0000000000000000000000000000000000000000000000000000000000000004"; + hex::decode("6352211e0000000000000000000000000000000000000000000000000000000000000004") + .unwrap(); let mut handle = create_mock_handle_from_input(owner_of_asset_4); let result = Mock::execute(&mut handle); assert!(result.is_ok()); @@ -39,7 +40,8 @@ fn owner_of_if_fails_returns_error() { impl_precompile_mock_simple!(Mock, Err("spaghetti error")); let owner_of_asset_4 = - "6352211e0000000000000000000000000000000000000000000000000000000000000004"; + hex::decode("6352211e0000000000000000000000000000000000000000000000000000000000000004") + .unwrap(); let mut handle = create_mock_handle_from_input(owner_of_asset_4); let result = Mock::execute(&mut handle); assert!(result.is_err()); @@ -66,10 +68,6 @@ fn owner_of_if_fails_returns_error() { // assert_eq!(result.unwrap().output, H160::zero().encode()); // } mod helpers { - use evm::Context; - use precompile_utils::testing::MockHandle; - use sp_core::H160; - /// Macro to define a precompile mock with custom closures for testing. /// /// This macro creates mock implementations of the `Erc721` trait, @@ -131,47 +129,4 @@ mod helpers { impl_precompile_mock!($name, |_asset_id, _collection_id| { $owner_of_collection }); }; } - - /// Create a mock handle for testing precompiled contracts. - /// - /// This function takes an input string representing the data to be sent to the precompiled contract - /// and a cost value, returning a `MockHandle` that can be used for testing. - /// - /// # Arguments - /// - /// * `input` - The input data as a hexadecimal string. - /// * `cost` - A cost value as u64. - /// * `value` - The amount of coins transferred as u64. - /// - /// # Example - /// - /// ``` - /// let handle = create_mock_handle("68656c6c6f", 0, 0); - /// ``` - pub fn create_mock_handle(input: &str, cost: u64, value: u64, caller: H160) -> MockHandle { - let i: Vec = hex::decode(input).expect("invalid input"); - - let context: Context = - Context { address: Default::default(), caller, apparent_value: From::from(value) }; - - MockHandle::new(i, Some(cost), context) - } - - /// Create a mock handle for testing precompiled contracts without a specific cost or value. - /// - /// This function takes an input string representing the data to be sent to the precompiled contract - /// and returns a `MockHandle` that can be used for testing. - /// - /// # Arguments - /// - /// * `input` - The input data as a hexadecimal string. - /// - /// # Example - /// - /// ``` - /// let handle = create_mock_handle_from_input("68656c6c6f"); - /// ``` - pub fn create_mock_handle_from_input(input: &str) -> MockHandle { - create_mock_handle(input, 0, 0, H160::zero()) - } } diff --git a/precompile/living-assets/src/tests.rs b/precompile/living-assets/src/tests.rs index f7c77907..cd16203a 100644 --- a/precompile/living-assets/src/tests.rs +++ b/precompile/living-assets/src/tests.rs @@ -5,7 +5,7 @@ use super::*; use evm::ExitRevert; -use helpers::*; +use precompile_utils::testing::{create_mock_handle, create_mock_handle_from_input}; use sp_core::H160; use sp_std::vec::Vec; @@ -31,7 +31,7 @@ fn check_log_selectors() { fn failing_create_collection_should_return_error() { impl_precompile_mock_simple!(Mock, Err("spaghetti code"), Some(H160::zero())); - let mut handle = create_mock_handle_from_input(CREATE_COLLECTION); + let mut handle = create_mock_handle_from_input(hex::decode(CREATE_COLLECTION).unwrap()); let result = Mock::execute(&mut handle); assert_eq!( result.unwrap_err(), @@ -45,7 +45,7 @@ fn failing_create_collection_should_return_error() { fn create_collection_should_return_address() { impl_precompile_mock_simple!(Mock, Ok(5), Some(H160::zero())); - let mut handle = create_mock_handle_from_input(CREATE_COLLECTION); + let mut handle = create_mock_handle_from_input(hex::decode(CREATE_COLLECTION).unwrap()); let result = Mock::execute(&mut handle); assert!(result.is_ok()); assert_eq!( @@ -58,7 +58,7 @@ fn create_collection_should_return_address() { fn create_collection_should_generate_log() { impl_precompile_mock_simple!(Mock, Ok(0xffff), Some(H160::zero())); - let mut handle = create_mock_handle_from_input(CREATE_COLLECTION); + let mut handle = create_mock_handle_from_input(hex::decode(CREATE_COLLECTION).unwrap()); let result = Mock::execute(&mut handle); assert!(result.is_ok()); let logs = handle.logs; @@ -76,7 +76,8 @@ fn create_collection_should_generate_log() { #[test] fn create_collection_on_mock_with_nonzero_value_fails() { impl_precompile_mock_simple!(Mock, Ok(5), Some(H160::zero())); - let mut handle = create_mock_handle(CREATE_COLLECTION, 0, 1, H160::zero()); + let mut handle = + create_mock_handle(hex::decode(CREATE_COLLECTION).unwrap(), 0, 1, H160::zero()); let result = Mock::execute(&mut handle); assert!(result.is_err()); assert_eq!( @@ -99,7 +100,12 @@ fn create_collection_assign_collection_to_caller() { |_| { Some(H160::zero()) } // Closure for owner_of_collection result ); - let mut handle = create_mock_handle(CREATE_COLLECTION, 0, 0, H160::from_low_u64_be(0x1234)); + let mut handle = create_mock_handle( + hex::decode(CREATE_COLLECTION).unwrap(), + 0, + 0, + H160::from_low_u64_be(0x1234), + ); let result = Mock::execute(&mut handle); assert!(result.is_ok()); } @@ -109,7 +115,9 @@ fn call_unexistent_selector_should_fail() { impl_precompile_mock_simple!(Mock, Ok(0), Some(H160::from_low_u64_be(0x1234))); // unexistent selector - let input = "fb24ae530000000000000000000000000000000000000000000000000000000000000000"; + let input = + hex::decode("fb24ae530000000000000000000000000000000000000000000000000000000000000000") + .unwrap(); let mut handle = create_mock_handle_from_input(input); let result = Mock::execute(&mut handle); assert_eq!( @@ -123,10 +131,6 @@ fn call_unexistent_selector_should_fail() { } mod helpers { - use evm::Context; - use precompile_utils::testing::MockHandle; - use sp_core::H160; - /// Macro to define a precompile mock for testing. /// /// This macro creates mock implementations of the `CollectionManager` trait, @@ -192,47 +196,4 @@ mod helpers { ); }; } - - /// Create a mock handle for testing precompiled contracts. - /// - /// This function takes an input string representing the data to be sent to the precompiled contract - /// and a cost value, returning a `MockHandle` that can be used for testing. - /// - /// # Arguments - /// - /// * `input` - The input data as a hexadecimal string. - /// * `cost` - A cost value as u64. - /// * `value` - The amount of coins transferred as u64. - /// - /// # Example - /// - /// ``` - /// let handle = create_mock_handle("68656c6c6f", 0, 0); - /// ``` - pub fn create_mock_handle(input: &str, cost: u64, value: u64, caller: H160) -> MockHandle { - let i: Vec = hex::decode(input).expect("invalid input"); - - let context: Context = - Context { address: Default::default(), caller, apparent_value: From::from(value) }; - - MockHandle::new(i, Some(cost), context) - } - - /// Create a mock handle for testing precompiled contracts without a specific cost or value. - /// - /// This function takes an input string representing the data to be sent to the precompiled contract - /// and returns a `MockHandle` that can be used for testing. - /// - /// # Arguments - /// - /// * `input` - The input data as a hexadecimal string. - /// - /// # Example - /// - /// ``` - /// let handle = create_mock_handle_from_input("68656c6c6f"); - /// ``` - pub fn create_mock_handle_from_input(input: &str) -> MockHandle { - create_mock_handle(input, 0, 0, H160::zero()) - } } diff --git a/precompile/utils/src/testing.rs b/precompile/utils/src/testing.rs index d1ef955d..1905d300 100644 --- a/precompile/utils/src/testing.rs +++ b/precompile/utils/src/testing.rs @@ -81,3 +81,44 @@ impl PrecompileHandle for MockHandle { self.gas_limit } } + +/// Create a mock handle for testing precompiled contracts. +/// +/// This function takes an input string representing the data to be sent to the precompiled contract +/// and a cost value, returning a `MockHandle` that can be used for testing. +/// +/// # Arguments +/// +/// * `input` - The input data as a hexadecimal string. +/// * `cost` - A cost value as u64. +/// * `value` - The amount of coins transferred as u64. +/// +/// # Example +/// +/// ``` +/// let handle = create_mock_handle("68656c6c6f", 0, 0); +/// ``` +pub fn create_mock_handle(input: Vec, cost: u64, value: u64, caller: H160) -> MockHandle { + let context: Context = + Context { address: Default::default(), caller, apparent_value: From::from(value) }; + + MockHandle::new(input, Some(cost), context) +} + +/// Create a mock handle for testing precompiled contracts without a specific cost or value. +/// +/// This function takes an input string representing the data to be sent to the precompiled contract +/// and returns a `MockHandle` that can be used for testing. +/// +/// # Arguments +/// +/// * `input` - The input data as a hexadecimal string. +/// +/// # Example +/// +/// ``` +/// let handle = create_mock_handle_from_input("68656c6c6f"); +/// ``` +pub fn create_mock_handle_from_input(input: Vec) -> MockHandle { + create_mock_handle(input, 0, 0, H160::zero()) +} From af90eda839d88b7dbc0769ade61b2ded7363e36e Mon Sep 17 00:00:00 2001 From: Alessandro Siniscalchi Date: Tue, 8 Aug 2023 10:02:35 +0200 Subject: [PATCH 36/36] first try --- Cargo.lock | 24 ++++++++++-- precompile/precompileset/Cargo.toml | 39 +++++++++++++++++++ .../precompileset/src/lib.rs | 8 ++-- .../precompileset/src}/mock.rs | 0 .../precompileset/src}/test.rs | 0 runtime/Cargo.toml | 7 ---- 6 files changed, 63 insertions(+), 15 deletions(-) create mode 100644 precompile/precompileset/Cargo.toml rename runtime/src/precompiles/mod.rs => precompile/precompileset/src/lib.rs (92%) rename {runtime/src/precompiles => precompile/precompileset/src}/mock.rs (100%) rename {runtime/src/precompiles => precompile/precompileset/src}/test.rs (100%) diff --git a/Cargo.lock b/Cargo.lock index c99b7a51..873e338c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -5047,10 +5047,6 @@ dependencies = [ "pallet-ethereum", "pallet-evm", "pallet-evm-chain-id", - "pallet-evm-erc721", - "pallet-evm-living-assets-ownership", - "pallet-evm-precompile-modexp", - "pallet-evm-precompile-simple", "pallet-living-assets-ownership", "pallet-session", "pallet-sudo", @@ -7076,6 +7072,26 @@ dependencies = [ "sp-io", ] +[[package]] +name = "pallet-evm-precompileset" +version = "0.1.0" +dependencies = [ + "frame-support", + "frame-system", + "pallet-balances", + "pallet-evm", + "pallet-evm-erc721", + "pallet-evm-living-assets-ownership", + "pallet-evm-precompile-modexp", + "pallet-evm-precompile-simple", + "pallet-living-assets-ownership", + "pallet-timestamp", + "polkadot-primitives", + "sp-core", + "sp-runtime", + "sp-std", +] + [[package]] name = "pallet-fast-unstake" version = "4.0.0-dev" diff --git a/precompile/precompileset/Cargo.toml b/precompile/precompileset/Cargo.toml new file mode 100644 index 00000000..45ee7af4 --- /dev/null +++ b/precompile/precompileset/Cargo.toml @@ -0,0 +1,39 @@ +[package] +name = "pallet-evm-precompileset" +version = "0.1.0" +edition = "2021" + +[dependencies] +pallet-evm = { workspace = true } +pallet-evm-precompile-modexp = { workspace = true } +pallet-evm-precompile-simple = { workspace = true } +pallet-evm-living-assets-ownership = { workspace = true } +pallet-evm-erc721 = { workspace = true } +pallet-living-assets-ownership = { workspace = true } +pallet-balances = { workspace = true } +pallet-timestamp = { workspace = true } +frame-system = { workspace = true } +frame-support = { workspace = true } +sp-core = { workspace = true } +sp-runtime = { workspace = true } +sp-std = { workspace = true } +polkadot-primitives = { workspace = true } + +[features] +default = [ + "std", +] +std = [ + "pallet-evm/std", + "pallet-evm-precompile-modexp/std", + "pallet-evm-precompile-simple/std", + "pallet-evm-living-assets-ownership/std", + "pallet-balances/std", + "pallet-timestamp/std", + "frame-system/std", + "frame-support/std", + "sp-core/std", + "sp-runtime/std", + "sp-std/std", + "polkadot-primitives/std" +] \ No newline at end of file diff --git a/runtime/src/precompiles/mod.rs b/precompile/precompileset/src/lib.rs similarity index 92% rename from runtime/src/precompiles/mod.rs rename to precompile/precompileset/src/lib.rs index 3266b603..74d1c3ff 100644 --- a/runtime/src/precompiles/mod.rs +++ b/precompile/precompileset/src/lib.rs @@ -28,16 +28,16 @@ where } } -type LivingAssetsPrecompile = CollectionManagerPrecompile< +type LivingAssetsPrecompile = CollectionManagerPrecompile< pallet_evm::HashedAddressMapping, AccountId, - pallet_living_assets_ownership::Pallet, + pallet_living_assets_ownership::Pallet, >; -type Erc721 = Erc721Precompile< +type Erc721 = Erc721Precompile< pallet_evm::HashedAddressMapping, AccountId, - pallet_living_assets_ownership::Pallet, + pallet_living_assets_ownership::Pallet, >; impl PrecompileSet for FrontierPrecompiles diff --git a/runtime/src/precompiles/mock.rs b/precompile/precompileset/src/mock.rs similarity index 100% rename from runtime/src/precompiles/mock.rs rename to precompile/precompileset/src/mock.rs diff --git a/runtime/src/precompiles/test.rs b/precompile/precompileset/src/test.rs similarity index 100% rename from runtime/src/precompiles/test.rs rename to precompile/precompileset/src/test.rs diff --git a/runtime/Cargo.toml b/runtime/Cargo.toml index 50784833..67330b92 100644 --- a/runtime/Cargo.toml +++ b/runtime/Cargo.toml @@ -49,8 +49,6 @@ sp-transaction-pool = { workspace = true } sp-version = { workspace = true } pallet-living-assets-ownership = { workspace = true } -pallet-evm-living-assets-ownership = { workspace = true } -pallet-evm-erc721 = { workspace = true } # Polkadot pallet-xcm = { workspace = true } @@ -84,8 +82,6 @@ pallet-base-fee = { workspace = true } pallet-evm = { workspace = true } pallet-ethereum = { workspace = true } pallet-evm-chain-id = { workspace = true } -pallet-evm-precompile-modexp = { workspace = true } -pallet-evm-precompile-simple = { workspace = true } # Bridge dependencies bp-header-chain = { workspace = true } @@ -157,13 +153,10 @@ std = [ "pallet-ethereum/std", "pallet-evm/std", "pallet-evm-chain-id/std", - "pallet-evm-precompile-modexp/std", - "pallet-evm-precompile-simple/std", "cumulus-pallet-session-benchmarking/std", "frame-benchmarking", "frame-system-benchmarking", "frame-try-runtime", - "pallet-evm-living-assets-ownership/std", # Bridge deps, "bp-evochain/std", "bp-header-chain/std",