diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..41ef9e536f --- /dev/null +++ b/.gitmodules @@ -0,0 +1,8 @@ +[submodule "runtime/integration-tests/submodules/liquidity-pools"] + path = runtime/integration-tests/submodules/liquidity-pools + url = git@github.com:centrifuge/liquidity-pools.git + branch = origin/feat/forwarder +[submodule "runtime/integration-tests/submodules/axelar-cgp-solidity"] + path = runtime/integration-tests/submodules/axelar-cgp-solidity + url = git@github.com:axelarnetwork/axelar-cgp-solidity.git + branch = origin/releases/4.3.x diff --git a/Cargo.lock b/Cargo.lock index eb459a289e..e8bf85b662 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1548,7 +1548,7 @@ version = "4.3.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54a9bb5758fc5dfe728d1019941681eccaf0cf8a4189b692a0ee2f2ecf90a050" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "syn 2.0.29", @@ -3025,7 +3025,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9720bba047d567ffc8a3cba48bf19126600e249ab7f128e9233e6376976a116" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "syn 1.0.109", @@ -3140,6 +3140,8 @@ checksum = "a4c98847055d934070b90e806e12d3936b787d0a115068981c1d8dfd5dfef5a5" dependencies = [ "ethereum-types 0.12.1", "hex", + "serde", + "serde_json", "sha3 0.9.1", "thiserror", "uint", @@ -3159,6 +3161,25 @@ dependencies = [ "uint", ] +[[package]] +name = "ethabi-contract" +version = "16.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4632b1b766fbf59872eb7a41e7ebaa10727b7f7000aef5bb626b87e472041c83" + +[[package]] +name = "ethabi-derive" +version = "16.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6766474553be4cd1042a20e5c67bb067846c7796975e67fc59147faf1020f467" +dependencies = [ + "ethabi 16.0.0", + "heck 0.3.3", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ethbloom" version = "0.11.1" @@ -3167,6 +3188,8 @@ checksum = "bfb684ac8fa8f6c5759f788862bb22ec6fe3cb392f6bfd08e3c64b603661e3f8" dependencies = [ "crunchy", "fixed-hash 0.7.0", + "impl-rlp", + "impl-serde 0.3.2", "tiny-keccak", ] @@ -3180,7 +3203,7 @@ dependencies = [ "fixed-hash 0.8.0", "impl-codec 0.6.0", "impl-rlp", - "impl-serde", + "impl-serde 0.4.0", "scale-info", "tiny-keccak", ] @@ -3211,6 +3234,8 @@ checksum = "05136f7057fe789f06e6d41d07b34e6f70d8c86e5693b60f97aaa6553553bdaf" dependencies = [ "ethbloom 0.11.1", "fixed-hash 0.7.0", + "impl-rlp", + "impl-serde 0.3.2", "primitive-types 0.10.1", "uint", ] @@ -3225,7 +3250,7 @@ dependencies = [ "fixed-hash 0.8.0", "impl-codec 0.6.0", "impl-rlp", - "impl-serde", + "impl-serde 0.4.0", "primitive-types 0.12.1", "scale-info", "uint", @@ -4434,6 +4459,15 @@ version = "0.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2c6201b9ff9fd90a5a3bac2e56a830d0caa509576f0e503818ee82c181b3437a" +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "heck" version = "0.4.1" @@ -4724,6 +4758,15 @@ dependencies = [ "rlp", ] +[[package]] +name = "impl-serde" +version = "0.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4551f042f3438e64dbd6226b20527fc84a6e1fe65688b58746a2f53623f25f5c" +dependencies = [ + "serde", +] + [[package]] name = "impl-serde" version = "0.4.0" @@ -4971,7 +5014,7 @@ version = "0.16.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baa6da1e4199c10d7b1d0a6e5e8bd8e55f351163b6f4b3cbb044672a69bd4c1c" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro-crate", "proc-macro2", "quote", @@ -5563,7 +5606,7 @@ version = "0.31.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d527d5827582abd44a6d80c07ff8b50b4ee238a8979e05998474179e79dc400" dependencies = [ - "heck", + "heck 0.4.1", "quote", "syn 1.0.109", ] @@ -10233,6 +10276,8 @@ checksum = "05e4722c697a58a99d5d06a08c30821d7c082a4632198de1eaa5a6c22ef42373" dependencies = [ "fixed-hash 0.7.0", "impl-codec 0.5.1", + "impl-rlp", + "impl-serde 0.3.2", "uint", ] @@ -10245,7 +10290,7 @@ dependencies = [ "fixed-hash 0.8.0", "impl-codec 0.6.0", "impl-rlp", - "impl-serde", + "impl-serde 0.4.0", "scale-info", "uint", ] @@ -10373,7 +10418,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "119533552c9a7ffacc21e099c24a0ac8bb19c2a2a3f363de84cd9b844feab270" dependencies = [ "bytes", - "heck", + "heck 0.4.1", "itertools", "lazy_static", "log", @@ -11072,6 +11117,8 @@ dependencies = [ "cumulus-primitives-core", "development-runtime", "ethabi 16.0.0", + "ethabi-contract", + "ethabi-derive", "ethereum", "frame-benchmarking", "frame-support", @@ -11127,6 +11174,7 @@ dependencies = [ "sc-executor", "sc-service", "serde", + "serde_json", "sp-api", "sp-consensus-aura", "sp-consensus-babe", @@ -12648,9 +12696,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.105" +version = "1.0.107" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "693151e1ac27563d6dbcec9dee9fbd5da8539b20fa14ad3752b2e6d363ace360" +checksum = "6b420ce6e3d8bd882e9b243c6eed35dbc9a6110c9769e74b584e0d68d1f20c65" dependencies = [ "itoa", "ryu", @@ -13108,7 +13156,7 @@ dependencies = [ "futures", "hash-db", "hash256-std-hasher", - "impl-serde", + "impl-serde 0.4.0", "lazy_static", "libsecp256k1", "log", @@ -13455,7 +13503,7 @@ name = "sp-storage" version = "7.0.0" source = "git+https://github.com/paritytech//substrate?rev=bcff60a227d455d95b4712b6cb356ce56b1ff672#bcff60a227d455d95b4712b6cb356ce56b1ff672" dependencies = [ - "impl-serde", + "impl-serde 0.4.0", "parity-scale-codec 3.6.4", "ref-cast", "serde", @@ -13543,7 +13591,7 @@ name = "sp-version" version = "5.0.0" source = "git+https://github.com/paritytech//substrate?rev=bcff60a227d455d95b4712b6cb356ce56b1ff672#bcff60a227d455d95b4712b6cb356ce56b1ff672" dependencies = [ - "impl-serde", + "impl-serde 0.4.0", "parity-scale-codec 3.6.4", "parity-wasm", "scale-info", @@ -13724,7 +13772,7 @@ version = "0.24.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1e385be0d24f186b4ce2f9982191e7101bb737312ad61c1f2f984f34bcf85d59" dependencies = [ - "heck", + "heck 0.4.1", "proc-macro2", "quote", "rustversion", @@ -14682,6 +14730,12 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + [[package]] name = "unicode-width" version = "0.1.10" diff --git a/pallets/liquidity-pools-gateway/axelar-gateway-precompile/src/lib.rs b/pallets/liquidity-pools-gateway/axelar-gateway-precompile/src/lib.rs index 7ce1889882..efed6c9e21 100644 --- a/pallets/liquidity-pools-gateway/axelar-gateway-precompile/src/lib.rs +++ b/pallets/liquidity-pools-gateway/axelar-gateway-precompile/src/lib.rs @@ -287,16 +287,12 @@ where exit_status: ExitError::Other("account bytes mismatch for domain".into()), })?; - match pallet_liquidity_pools_gateway::Pallet::::process_msg( + pallet_liquidity_pools_gateway::Pallet::::process_msg( pallet_liquidity_pools_gateway::GatewayOrigin::Domain(domain_address).into(), msg, ) - .map(|_| ()) .map_err(TryDispatchError::Substrate) - { - Err(e) => Err(e.into()), - Ok(()) => Ok(()), - } + .map_err(Into::into) } // Mimics: diff --git a/runtime/common/Cargo.toml b/runtime/common/Cargo.toml index 8e64162621..c5305bfdac 100644 --- a/runtime/common/Cargo.toml +++ b/runtime/common/Cargo.toml @@ -10,6 +10,7 @@ repository = "https://github.com/centrifuge/centrifuge-chain" [dependencies] serde = { version = "1.0.119" } smallvec = "1.6.1" +hex-literal = { version = "0.3.4", default-features = false } # Substrate dependencies codec = { package = "parity-scale-codec", version = "3.0.0", default-features = false, features = ["derive"] } @@ -76,7 +77,6 @@ sp-io = { git = "https://github.com/paritytech/substrate", default-features = fa [dev-dependencies] cfg-mocks = { path = "../../libs/mocks", features = ["runtime-benchmarks", "std"] } -hex-literal = "0.3.4" pallet-collective = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sp-io = { git = "https://github.com/paritytech/substrate", default-features = true, branch = "polkadot-v0.9.38" } diff --git a/runtime/common/src/evm/mod.rs b/runtime/common/src/evm/mod.rs index 0e4c31c296..ae8ffacf3a 100644 --- a/runtime/common/src/evm/mod.rs +++ b/runtime/common/src/evm/mod.rs @@ -11,11 +11,19 @@ // GNU General Public License for more details. use frame_support::weights::constants::WEIGHT_REF_TIME_PER_SECOND; +use hex_literal::hex; use pallet_ethereum::{Transaction, TransactionAction}; use sp_runtime::Permill; pub mod precompile; +/// `pallet_evm::AccountCodes` must be populated for precompiles as +/// otherwise `OPCODE::EXTCODESIZE` will make the EVM error upon calling an +/// precompile. +/// +/// The following bytes represent: `PUSH1 00`, `PUSH1 00`, `REVERT`. +pub const PRECOMPILE_CODE_STORAGE: [u8; 5] = hex!("60006000fd"); + // From Moonbeam: // // Current approximation of the gas per second consumption considering diff --git a/runtime/common/src/evm/precompile.rs b/runtime/common/src/evm/precompile.rs index c204976fb6..3f2277ceeb 100644 --- a/runtime/common/src/evm/precompile.rs +++ b/runtime/common/src/evm/precompile.rs @@ -143,13 +143,13 @@ where // H160 cannot be used in a match statement due to its hand-rolled // PartialEq implementation. This just gives a nice name to the // internal array of bytes that an H160 wraps. -type Addr = [u8; 20]; +pub type Addr = [u8; 20]; // This is a reimplementation of the upstream u64->H160 conversion // function, made `const` to make our precompile address `const`s a // bit cleaner. It can be removed when upstream has a const conversion // function. -const fn addr(a: u64) -> Addr { +pub const fn addr(a: u64) -> Addr { let b = a.to_be_bytes(); [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], diff --git a/runtime/development/src/liquidity_pools.rs b/runtime/development/src/liquidity_pools.rs index c9dc2b9ff9..0a34fda4e7 100644 --- a/runtime/development/src/liquidity_pools.rs +++ b/runtime/development/src/liquidity_pools.rs @@ -11,8 +11,12 @@ // GNU General Public License for more details. use cfg_primitives::{AccountId, Balance, PoolId, TrancheId}; -use cfg_types::{domain_address::Domain, fixed_point::Quantity}; -use frame_support::parameter_types; +use cfg_traits::liquidity_pools::InboundQueue; +use cfg_types::{ + domain_address::{Domain, DomainAddress}, + fixed_point::Quantity, +}; +use frame_support::{dispatch::DispatchResult, parameter_types}; use frame_system::EnsureRoot; use runtime_common::gateway::GatewayAccountProvider; diff --git a/runtime/integration-tests/Cargo.toml b/runtime/integration-tests/Cargo.toml index 6ec4036e5c..7724946ca6 100644 --- a/runtime/integration-tests/Cargo.toml +++ b/runtime/integration-tests/Cargo.toml @@ -4,6 +4,7 @@ version = "0.1.0" authors = ["Centrifuge "] edition = "2021" license = "LGPL-3.0" +build = "build.rs" homepage = "https://centrifuge.io/" repository = "https://github.com/centrifuge/centrifuge-chain" @@ -14,6 +15,7 @@ lazy_static = "1.4.0" serde = { version = "1.0.119" } tokio = { version = "1.15", features = ["macros"] } tracing-subscriber = "0.2" +serde_json = "1.0.107" # Substrate ## Substrate-Frame @@ -34,7 +36,7 @@ sp-api = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v sp-consensus-aura = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sp-consensus-babe = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sp-consensus-slots = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } -sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } +sp-core = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" , features = ["full_crypto", "default"]} sp-inherents = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sp-runtime = { git = "https://github.com/paritytech/substrate", default-features = false, branch = "polkadot-v0.9.38" } @@ -80,16 +82,16 @@ cfg-traits = { path = "../../libs/traits" } development-runtime = { path = "../development" } runtime-common = { path = "../common" } -[dev-dependencies] getrandom = { version = "0.2", features = ["js"] } -hex = { version = "0.4.3", default_features = false } +hex = { version = "0.4.3" } -cfg-traits = { path = "../../libs/traits" } cfg-types = { path = "../../libs/types" } cfg-utils = { path = "../../libs/utils" } -ethabi = { version = "16.0", default-features = false } -ethereum = { version = "0.14.0", default-features = false } +ethabi = { version = "16.0" } +ethabi-contract = { version = "16.0" } +ethabi-derive = { version = "16.0" } +ethereum = { version = "0.14.0" } pallet-ethereum = { git = "https://github.com/PureStake/frontier", default-features = false, branch = "moonbeam-polkadot-v0.9.38" } pallet-evm = { git = "https://github.com/PureStake/frontier", default-features = false, branch = "moonbeam-polkadot-v0.9.38" } @@ -112,7 +114,6 @@ pallet-rewards = { path = "../../pallets/rewards" } pallet-session = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } pallet-xcm-transactor = { git = "https://github.com/PureStake/moonbeam", default-features = false, rev = "00b3e3d97806e889b02e1bcb4b69e65433dd805d" } -sp-io = { git = "https://github.com/paritytech/substrate", branch = "polkadot-v0.9.38" } sp-std = { git = "https://github.com/paritytech/substrate", default-features = true, branch = "polkadot-v0.9.38" } xcm-executor = { git = "https://github.com/paritytech/polkadot", default-features = true, branch = "release-v0.9.38" } diff --git a/runtime/integration-tests/build.rs b/runtime/integration-tests/build.rs new file mode 100644 index 0000000000..2f9c348e4a --- /dev/null +++ b/runtime/integration-tests/build.rs @@ -0,0 +1,114 @@ +// Copyright 2021 Centrifuge Foundation (centrifuge.io). +// +// This file is part of the Centrifuge chain project. +// Centrifuge 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 (see http://www.gnu.org/licenses). +// Centrifuge 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. +use std::{env, fs, path::PathBuf, process::Command}; + +const LP_SOL_SOURCES: &str = "LP_SOL_SOURCES"; +const AXELAR_SOL_SOURCES: &str = "AXELAR_SOL_SOURCES"; + +// TODO: Panic if build fails? +fn main() { + let paths = fs::read_dir("./submodules/") + .expect("Submodules directory must exist for integration-tests"); + let out_dir = env::var("OUT_DIR").expect("Cargo sets OUT_DIR environment variable. qed."); + + match Command::new("git") + .args(&["fetch", "--all", "--recurse-submodules=yes"]) + .output() + { + Ok(o) if o.status.success() => {} + Ok(o) => { + println!( + "cargo:warning=Git fetch failed with: \n - status: {}\n -stderr: {}", + o.status, + String::from_utf8(o.stderr).expect("stderr is utf-8 encoded. qed.") + ); + } + Err(err) => { + println!("cargo:warning=Failed to execute git command: {}", err); + } + } + + let mut verified_dir = Vec::new(); + for path in paths { + if let Ok(dir_entry) = path.as_ref() { + if dir_entry + .metadata() + .map(|meta| meta.is_dir()) + .unwrap_or(false) + { + verified_dir.push( + fs::canonicalize(dir_entry.path()).expect("Failed to find absolute path."), + ); + } + } + } + + for path in verified_dir { + env::set_current_dir(&path).unwrap(); + let mut out_dir_build = PathBuf::from(out_dir.clone()); + + let parent = path + .components() + .last() + .expect("Repository itself has components. qed") + .as_os_str() + .to_str() + .expect("OsStr is utf-8. qed"); + + out_dir_build.push(parent); + let out_dir_build = out_dir_build + .as_os_str() + .to_str() + .expect("OsStr is utf-8. qed"); + + match Command::new("forge") + .args(&[ + "build", + "--extra-output-files", + "abi", + "--out", + out_dir_build, + ]) + .output() + { + Ok(o) if o.status.success() => { + let source = match parent { + "liquidity-pools" => LP_SOL_SOURCES, + "axelar-cgp-solidity" => AXELAR_SOL_SOURCES, + _ => { + println!( + "cargo:warning=Unknown solidity source build. Name: {}", + parent + ); + println!( + "cargo:warning=No environment variable for sources set. Artifacts stored under: {}", + out_dir_build + ); + continue; + } + }; + + println!("cargo:rustc-env={}={}", source, out_dir_build); + } + Ok(o) => { + println!( + "cargo:warning=forge build failed with: \n - status: {}\n -stderr: {}", + o.status, + String::from_utf8(o.stderr).expect("stderr is utf-8 encoded. qed.") + ); + } + Err(err) => { + println!("cargo:warning=Failed to execute git command: {}", err); + } + } + } +} diff --git a/runtime/integration-tests/src/evm/precompile.rs b/runtime/integration-tests/src/evm/precompile.rs index 9a58b61e3d..a0cc1df87c 100644 --- a/runtime/integration-tests/src/evm/precompile.rs +++ b/runtime/integration-tests/src/evm/precompile.rs @@ -17,40 +17,62 @@ use cfg_primitives::{Balance, PoolId, TrancheId, CFG}; use cfg_traits::{ethereum::EthereumTransactor, liquidity_pools::Codec}; use cfg_types::{ domain_address::{Domain, DomainAddress}, - fixed_point::Rate, + fixed_point::{Quantity, Rate}, tokens::{CurrencyId, CustomMetadata, GeneralCurrencyIndex}, }; use codec::Encode; use ethabi::{Contract, Function, Param, ParamType, Token}; use ethereum::{LegacyTransaction, TransactionAction, TransactionSignature, TransactionV2}; -use frame_support::{assert_err, assert_ok, dispatch::RawOrigin}; +use frame_support::{assert_err, assert_ok, dispatch::RawOrigin, traits::GenesisBuild}; use fudge::primitives::Chain; use hex::ToHex; use orml_traits::{asset_registry::AssetMetadata, MultiCurrency}; use pallet_evm::{AddressMapping, FeeCalculator}; use pallet_liquidity_pools::Message; use runtime_common::{account_conversion::AccountConverter, evm::precompile::LP_AXELAR_GATEWAY}; -use sp_core::{Get, H160, H256, U256}; +use sp_core::{storage::Storage, Get, H160, H256, U256}; use sp_runtime::traits::{BlakeTwo256, Hash}; use tokio::runtime::Handle; use xcm::{v3::MultiLocation, VersionedMultiLocation}; use crate::{ - chain::centrifuge::{ - AccountId, CouncilCollective, FastTrackVotingPeriod, MinimumDeposit, Runtime, RuntimeCall, - RuntimeEvent, RuntimeOrigin, PARA_ID, + chain::{ + centrifuge, + centrifuge::{ + AccountId, CouncilCollective, FastTrackVotingPeriod, MinimumDeposit, Runtime, + RuntimeCall, RuntimeEvent, RuntimeOrigin, CHAIN_ID, PARA_ID, + }, }, evm::ethereum_transaction::TEST_CONTRACT_CODE, utils::{ + accounts::{Ecdsa, Keyring}, env, env::{ChainState, EventRange, TestEnv}, - evm::{deploy_contract, mint_balance_into_derived_account}, + evm, + evm::{deploy_contract, mint_balance_into_derived_account, prepare_full_evm}, + genesis, ESSENTIAL, }, }; #[tokio::test] async fn axelar_precompile_execute() { - let mut env = env::test_env_default(Handle::current()); + let mut env = { + let mut genesis = Storage::default(); + genesis::default_balances::(&mut genesis); + genesis::register_default_asset::(&mut genesis); + >::assimilate_storage( + &pallet_evm_chain_id::GenesisConfig { chain_id: CHAIN_ID }, + &mut genesis, + ) + .expect("ESSENTIAL: Genesisbuild is not allowed to fail."); + env::test_env_with_centrifuge_storage(Handle::current(), genesis) + }; + + let chain_id = env + .with_state(Chain::Para(PARA_ID), || { + pallet_evm_chain_id::Pallet::::get() + }) + .unwrap(); env.evolve().unwrap(); @@ -231,3 +253,78 @@ async fn axelar_precompile_execute() { }) .unwrap(); } + +#[tokio::test] +async fn axelar_precompile_execute_2() { + let mut env = { + let mut genesis = Storage::default(); + genesis::default_balances::(&mut genesis); + genesis::register_default_asset::(&mut genesis); + >::assimilate_storage( + &pallet_evm_chain_id::GenesisConfig { chain_id: CHAIN_ID }, + &mut genesis, + ) + .expect("ESSENTIAL: Genesisbuild is not allowed to fail."); + env::test_env_with_centrifuge_storage(Handle::current(), genesis) + }; + + prepare_full_evm(&mut env); + + let source = Keyring::::Alice.to_h160(); + let (forwarder, forwarder_contract) = env.try_get_contract("forwarder").expect(ESSENTIAL); + + env.with_mut_state(Chain::Para(PARA_ID), || { + axelar_gateway_precompile::Pallet::::set_gateway( + centrifuge::RuntimeOrigin::root(), + forwarder, + //source, + ) + .unwrap(); + + axelar_gateway_precompile::Pallet::::set_converter( + centrifuge::RuntimeOrigin::root(), + BlakeTwo256::hash("ethereum-2".as_bytes()), + SourceConverter { + domain: Domain::EVM(5), + }, + ) + .unwrap(); + + pallet_liquidity_pools_gateway::Pallet::::add_instance( + centrifuge::RuntimeOrigin::root(), + DomainAddress::EVM(5, source.0), + ) + .unwrap(); + }); + + let prec = LP_AXELAR_GATEWAY; + + let info = evm::call_from_source( + &mut env, + source, + forwarder, + //LP_AXELAR_GATEWAY.into(), + &forwarder_contract, + "execute", + &[ + Token::FixedBytes(H256::from_low_u64_be(5678).0.to_vec()), + Token::String("ethereum-2".to_string()), + Token::String(format!("0x{}", hex::encode(source.0))), + Token::Bytes( + pallet_liquidity_pools::Message::::Transfer { + currency: 1, + sender: [0u8; 32], + receiver: [0u8; 32], + amount: 0, + } + .serialize(), + ), + ], + ); + + panic!("{:?}", info); +} diff --git a/runtime/integration-tests/src/lib.rs b/runtime/integration-tests/src/lib.rs index 25636495d4..bea24c96f5 100644 --- a/runtime/integration-tests/src/lib.rs +++ b/runtime/integration-tests/src/lib.rs @@ -37,18 +37,21 @@ mod chain { pub mod centrifuge { pub use centrifuge_runtime::*; pub const PARA_ID: u32 = 2031; + pub const CHAIN_ID: u64 = 2023; } #[cfg(feature = "runtime-altair")] pub mod altair { pub use altair_runtime::*; pub const PARA_ID: u32 = 2088; + pub const CHAIN_ID: u64 = 2088; } #[cfg(feature = "runtime-development")] pub mod development { pub use development_runtime::*; pub const PARA_ID: u32 = 2000; + pub const CHAIN_ID: u64 = 2000; } } diff --git a/runtime/integration-tests/src/liquidity_pools/gateway.rs b/runtime/integration-tests/src/liquidity_pools/gateway.rs index 3b61179791..e6fe7bbb73 100644 --- a/runtime/integration-tests/src/liquidity_pools/gateway.rs +++ b/runtime/integration-tests/src/liquidity_pools/gateway.rs @@ -48,7 +48,7 @@ use crate::{ RuntimeEvent, PARA_ID, }, utils::{ - accounts::Keyring, + accounts::{Keyring, Sr25519}, collective::{collective_close, collective_propose, collective_vote}, democracy::{democracy_vote, execute_via_democracy, external_propose_majority, fast_track}, env::{ChainState, EventRange}, @@ -61,7 +61,11 @@ use crate::{ }; pub(crate) fn get_council_members() -> Vec { - vec![Keyring::Alice, Keyring::Bob, Keyring::Charlie] + vec![ + Keyring::::Alice, + Keyring::::Bob, + Keyring::::Charlie, + ] } #[tokio::test] diff --git a/runtime/integration-tests/src/liquidity_pools/pallet/development/tests/routers/axelar_evm.rs b/runtime/integration-tests/src/liquidity_pools/pallet/development/tests/routers/axelar_evm.rs index 356cc62cfd..46275eab18 100644 --- a/runtime/integration-tests/src/liquidity_pools/pallet/development/tests/routers/axelar_evm.rs +++ b/runtime/integration-tests/src/liquidity_pools/pallet/development/tests/routers/axelar_evm.rs @@ -36,7 +36,7 @@ use crate::{ }, liquidity_pools::gateway::get_council_members, utils::{ - accounts::Keyring, + accounts::{Keyring, Sr25519}, democracy::execute_via_democracy, env, env::{ChainState, EventRange, TestEnv}, @@ -129,7 +129,7 @@ async fn submit() { }) if [*domain == test_domain && *router == test_router], ); - let sender = Keyring::Alice.to_account_id(); + let sender = Keyring::::Alice.to_account_id(); let gateway_sender = env .with_state(Chain::Para(PARA_ID), || { ::Sender::get() @@ -146,8 +146,8 @@ async fn submit() { let msg = Message::::Transfer { currency: 0, - sender: Keyring::Alice.to_account_id().into(), - receiver: Keyring::Bob.to_account_id().into(), + sender: Keyring::::Alice.to_account_id().into(), + receiver: Keyring::::Bob.to_account_id().into(), amount: 1_000u128, }; diff --git a/runtime/integration-tests/src/pools/env.rs b/runtime/integration-tests/src/pools/env.rs index 0f97ffcea2..f9ca95e28b 100644 --- a/runtime/integration-tests/src/pools/env.rs +++ b/runtime/integration-tests/src/pools/env.rs @@ -22,7 +22,7 @@ use crate::{ centrifuge::{Runtime, PARA_ID}, }, utils::{ - accounts::Keyring, + accounts::{Keyring, Sr25519}, extrinsics::{nonce_centrifuge, xt_centrifuge}, *, }, @@ -61,11 +61,11 @@ async fn extrinsics_works() { genesis::default_balances::(&mut genesis); let mut env = env::test_env_with_centrifuge_storage(Handle::current(), genesis); - let to: cfg_primitives::Address = Keyring::Bob.into(); + let to: cfg_primitives::Address = Keyring::::Bob.into(); let xt = xt_centrifuge( &env, - Keyring::Alice, - nonce_centrifuge(&env, Keyring::Alice), + Keyring::::Alice, + nonce_centrifuge(&env, Keyring::::Alice), centrifuge::RuntimeCall::Balances(BalancesCall::transfer { dest: to, value: 100 * cfg_primitives::constants::CFG, @@ -78,8 +78,8 @@ async fn extrinsics_works() { let (alice_before, bob_before) = env .with_state(Chain::Para(PARA_ID), || { ( - frame_system::Pallet::::account(Keyring::Alice.to_account_id()), - frame_system::Pallet::::account(Keyring::Bob.to_account_id()), + frame_system::Pallet::::account(Keyring::::Alice.to_account_id()), + frame_system::Pallet::::account(Keyring::::Bob.to_account_id()), ) }) .unwrap(); @@ -89,8 +89,8 @@ async fn extrinsics_works() { let (alice_after, bob_after) = env .with_state(Chain::Para(PARA_ID), || { ( - frame_system::Pallet::::account(Keyring::Alice.to_account_id()), - frame_system::Pallet::::account(Keyring::Bob.to_account_id()), + frame_system::Pallet::::account(Keyring::::Alice.to_account_id()), + frame_system::Pallet::::account(Keyring::::Bob.to_account_id()), ) }) .unwrap(); @@ -107,8 +107,8 @@ async fn extrinsics_works() { let (alice_after, bob_after) = env .with_state(Chain::Para(PARA_ID), || { ( - frame_system::Pallet::::account(Keyring::Alice.to_account_id()), - frame_system::Pallet::::account(Keyring::Bob.to_account_id()), + frame_system::Pallet::::account(Keyring::::Alice.to_account_id()), + frame_system::Pallet::::account(Keyring::::Bob.to_account_id()), ) }) .unwrap(); diff --git a/runtime/integration-tests/src/pools/pool_starts.rs b/runtime/integration-tests/src/pools/pool_starts.rs index 48b9326bd0..ea50c9b5c6 100644 --- a/runtime/integration-tests/src/pools/pool_starts.rs +++ b/runtime/integration-tests/src/pools/pool_starts.rs @@ -18,7 +18,7 @@ use tokio::runtime::Handle; use crate::{ chain::centrifuge::{Runtime, RuntimeCall, RuntimeEvent, PARA_ID}, utils::{ - accounts::Keyring, + accounts::{Keyring, Sr25519}, env::{ChainState, EventRange}, loans::{borrow_call, issue_default_loan, NftManager}, pools::{default_pool_calls, permission_call}, @@ -47,9 +47,9 @@ async fn create_loan() { Chain::Para(PARA_ID), RuntimeCall, ChainState::PoolEmpty, - Keyring::Admin => default_pool_calls(Keyring::Admin.into(), pool_id, &mut nft_manager), + Keyring::::Admin => default_pool_calls(Keyring::::Admin.into(), pool_id, &mut nft_manager), issue_default_loan( - Keyring::Admin.into(), + Keyring::::Admin.into(), pool_id, loan_amount, maturity, diff --git a/runtime/integration-tests/src/rewards/block/env.rs b/runtime/integration-tests/src/rewards/block/env.rs index ef367bb3c7..9e863618e5 100644 --- a/runtime/integration-tests/src/rewards/block/env.rs +++ b/runtime/integration-tests/src/rewards/block/env.rs @@ -19,7 +19,7 @@ use crate::{ chain::centrifuge::{CollatorSelection, Runtime, PARA_ID}, rewards::block::invariants::assert_all_staked, utils::{ - accounts::Keyring, + accounts::{Keyring, Sr25519}, env::test_env_with_centrifuge_storage, genesis::{ admin_collator, admin_invulnerable, default_native_balances, default_session_keys, @@ -29,12 +29,12 @@ use crate::{ pub(crate) fn default_collators() -> Vec { vec![ - Keyring::Alice, - Keyring::Bob, - Keyring::Charlie, - Keyring::Dave, - Keyring::Eve, - Keyring::Ferdie, + Keyring::::Alice, + Keyring::::Bob, + Keyring::::Charlie, + Keyring::::Dave, + Keyring::::Eve, + Keyring::::Ferdie, ] } @@ -76,6 +76,6 @@ async fn genesis_collators_are_staked() { // Ensure default collators are neither candidates nor invulnerables env.with_state(Chain::Para(PARA_ID), || { - assert_all_staked(&[Keyring::Admin.to_account_id()]); + assert_all_staked(&[Keyring::::Admin.to_account_id()]); }); } diff --git a/runtime/integration-tests/src/runtime_apis/rewards.rs b/runtime/integration-tests/src/runtime_apis/rewards.rs index 22c23f8c56..80ac78cf36 100644 --- a/runtime/integration-tests/src/runtime_apis/rewards.rs +++ b/runtime/integration-tests/src/runtime_apis/rewards.rs @@ -21,7 +21,7 @@ use sp_runtime::traits::IdentifyAccount; use tokio::runtime::Handle; use super::ApiEnv; -use crate::utils::accounts::Keyring; +use crate::utils::accounts::{Keyring, Sr25519}; #[tokio::test] async fn liquidity_rewards_runtime_api_works() { @@ -43,7 +43,7 @@ where + DistributedRewards + GroupRewards, { - let staker = Keyring::Alice.to_account_id(); + let staker = Keyring::::Alice.to_account_id(); let expected_reward = 200 * CFG; ApiEnv::new(Handle::current()) .startup(|| { diff --git a/runtime/integration-tests/src/utils/accounts.rs b/runtime/integration-tests/src/utils/accounts.rs index ae61b304d6..f20686d2de 100644 --- a/runtime/integration-tests/src/utils/accounts.rs +++ b/runtime/integration-tests/src/utils/accounts.rs @@ -12,17 +12,17 @@ // NOTE: Taken mostly from paritytech-substrate -use std::collections::HashMap; +use std::{collections::HashMap, marker::PhantomData}; -use cfg_primitives::Index; +use cfg_primitives::{AccountId, Index}; +use frame_support::Never; use fudge::primitives::Chain; use node_primitives::{AccountId as RelayAccountId, Index as RelayIndex}; -pub use sp_core::sr25519; use sp_core::{ sr25519::{Pair, Public, Signature}, Pair as PairT, }; -use sp_runtime::AccountId32; +use sp_runtime::{traits::Hash, AccountId32}; use crate::{ chain::{centrifuge, centrifuge::PARA_ID, relay}, @@ -137,7 +137,11 @@ where /// Set of test accounts. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum Keyring { +pub enum Keyring { + __Ignore( + frame_support::sp_std::marker::PhantomData<(T)>, + crate::utils::Never, + ), Admin, TrancheInvestor(u32), Alice, @@ -149,340 +153,1128 @@ pub enum Keyring { Custom(&'static str), } -impl Keyring { - pub fn to_account_id(self) -> AccountId32 { - self.public().0.into() +pub use sr25519::Sr25519; +pub mod sr25519 { + use sp_core::{ + crypto::AccountId32, + sr25519::{Pair, Public, Signature}, + Pair as PairT, + }; + + use crate::utils::accounts::{Crypto, Keyring}; + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub struct Sr25519; + + impl Crypto for Sr25519 {} + + impl Keyring { + pub fn to_account_id(self) -> AccountId32 { + self.public().0.into() + } + + pub fn sign(self, msg: &[u8]) -> Signature { + Pair::from(self).sign(msg) + } + + pub fn pair(self) -> Pair { + let path = match self { + Keyring::Admin => "Admin".to_owned(), + Keyring::TrancheInvestor(tranche_index) => format!("Tranche{tranche_index}"), + Keyring::Alice => "Alice".to_owned(), + Keyring::Bob => "Bob".to_owned(), + Keyring::Charlie => "Charlie".to_owned(), + Keyring::Dave => "Dave".to_owned(), + Keyring::Eve => "Eve".to_owned(), + Keyring::Ferdie => "Ferdie".to_owned(), + Keyring::Custom(derivation_path) => derivation_path.to_owned(), + Keyring::__Ignore(..) => unreachable!("Variant can not be instantiated. qed."), + }; + + Pair::from_string(&format!("//{}", path.as_str()), None) + .expect("static values are known good; qed") + } + + pub fn public(self) -> Public { + self.pair().public() + } + + pub fn to_seed(self) -> String { + let path = match self { + Keyring::Admin => "Admin".to_owned(), + Keyring::TrancheInvestor(tranche_index) => format!("Tranche{tranche_index}"), + Keyring::Alice => "Alice".to_owned(), + Keyring::Bob => "Bob".to_owned(), + Keyring::Charlie => "Charlie".to_owned(), + Keyring::Dave => "Dave".to_owned(), + Keyring::Eve => "Eve".to_owned(), + Keyring::Ferdie => "Ferdie".to_owned(), + Keyring::Custom(derivation_path) => derivation_path.to_owned(), + Keyring::__Ignore(..) => unreachable!("Variant can not be instantiated. qed."), + }; + format!("//{}", path.as_str()) + } + + /// Create a crypto `Pair` from a numeric value. + pub fn numeric(idx: usize) -> Pair { + Pair::from_string(&format!("//{}", idx), None) + .expect("numeric values are known good; qed") + } + + /// Get account id of a `numeric` account. + pub fn numeric_id(idx: usize) -> AccountId32 { + (*Self::numeric(idx).public().as_array_ref()).into() + } } - pub fn sign(self, msg: &[u8]) -> Signature { - Pair::from(self).sign(msg) + impl From> for sp_runtime::MultiSigner { + fn from(x: Keyring) -> Self { + sp_runtime::MultiSigner::Sr25519(x.into()) + } + } + + impl From> for sp_runtime::MultiAddress { + fn from(x: Keyring) -> Self { + sp_runtime::MultiAddress::Id(x.into()) + } } - pub fn pair(self) -> Pair { - let path = match self { - Keyring::Admin => "Admin".to_owned(), - Keyring::TrancheInvestor(tranche_index) => format!("Tranche{tranche_index}"), - Keyring::Alice => "Alice".to_owned(), - Keyring::Bob => "Bob".to_owned(), - Keyring::Charlie => "Charlie".to_owned(), - Keyring::Dave => "Dave".to_owned(), - Keyring::Eve => "Eve".to_owned(), - Keyring::Ferdie => "Ferdie".to_owned(), - Keyring::Custom(derivation_path) => derivation_path.to_owned(), - }; + #[derive(Debug)] + pub struct ParseKeyringError; - Pair::from_string(&format!("//{}", path.as_str()), None) - .expect("static values are known good; qed") + impl std::fmt::Display for ParseKeyringError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "ParseKeyringError") + } } - pub fn public(self) -> Public { - self.pair().public() + impl std::str::FromStr for Keyring { + type Err = ParseKeyringError; + + fn from_str(s: &str) -> Result::Err> { + match s { + "alice" => Ok(Keyring::Alice), + "bob" => Ok(Keyring::Bob), + "charlie" => Ok(Keyring::Charlie), + "dave" => Ok(Keyring::Dave), + "eve" => Ok(Keyring::Eve), + "ferdie" => Ok(Keyring::Ferdie), + "admin" => Ok(Keyring::Admin), + _ => Err(ParseKeyringError), + } + } } - pub fn to_seed(self) -> String { - let path = match self { - Keyring::Admin => "Admin".to_owned(), - Keyring::TrancheInvestor(tranche_index) => format!("Tranche{tranche_index}"), - Keyring::Alice => "Alice".to_owned(), - Keyring::Bob => "Bob".to_owned(), - Keyring::Charlie => "Charlie".to_owned(), - Keyring::Dave => "Dave".to_owned(), - Keyring::Eve => "Eve".to_owned(), - Keyring::Ferdie => "Ferdie".to_owned(), - Keyring::Custom(derivation_path) => derivation_path.to_owned(), - }; - format!("//{}", path.as_str()) + /// Returns a Vector of default accounts + /// + /// Accounts: + /// * Keyring::Admin + /// * Keyring::Alice + /// * Keyring::Bob + /// * Keyring::Ferdie + /// * Keyring::Charlie + /// * Keyring::Dave + /// * Keyring::Eve + pub fn default_accounts() -> Vec> { + vec![ + Keyring::Admin, + Keyring::Alice, + Keyring::Bob, + Keyring::Ferdie, + Keyring::Charlie, + Keyring::Dave, + Keyring::Eve, + ] } - /// Create a crypto `Pair` from a numeric value. - pub fn numeric(idx: usize) -> Pair { - Pair::from_string(&format!("//{}", idx), None).expect("numeric values are known good; qed") + /// Accounts: + /// * Keyring::Admin + /// * Keyring::Alice + /// * Keyring::Bob + /// * Keyring::Ferdie + /// * Keyring::Charlie + /// * Keyring::Dave + /// * Keyring::Eve + /// * Keyring::TrancheInvestor(1) + /// * Keyring::TrancheInvestor(2) + /// * Keyring::TrancheInvestor(3) + /// * Keyring::TrancheInvestor(4) + /// * Keyring::TrancheInvestor(5) + /// * Keyring::TrancheInvestor(6) + /// * Keyring::TrancheInvestor(7) + /// * Keyring::TrancheInvestor(8) + /// * Keyring::TrancheInvestor(9) + /// * Keyring::TrancheInvestor(10) + /// * Keyring::TrancheInvestor(11) + /// * Keyring::TrancheInvestor(12) + /// * Keyring::TrancheInvestor(13) + /// * Keyring::TrancheInvestor(14) + /// * Keyring::TrancheInvestor(15) + /// * Keyring::TrancheInvestor(16) + /// * Keyring::TrancheInvestor(17) + /// * Keyring::TrancheInvestor(18) + /// * Keyring::TrancheInvestor(19) + /// * Keyring::TrancheInvestor(20) + /// * Keyring::TrancheInvestor(21) + /// * Keyring::TrancheInvestor(22) + /// * Keyring::TrancheInvestor(23) + /// * Keyring::TrancheInvestor(24) + /// * Keyring::TrancheInvestor(25) + /// * Keyring::TrancheInvestor(26) + /// * Keyring::TrancheInvestor(27) + /// * Keyring::TrancheInvestor(28) + /// * Keyring::TrancheInvestor(29) + /// * Keyring::TrancheInvestor(30) + /// * Keyring::TrancheInvestor(31) + /// * Keyring::TrancheInvestor(32) + /// * Keyring::TrancheInvestor(33) + /// * Keyring::TrancheInvestor(34) + /// * Keyring::TrancheInvestor(35) + /// * Keyring::TrancheInvestor(36) + /// * Keyring::TrancheInvestor(37) + /// * Keyring::TrancheInvestor(38) + /// * Keyring::TrancheInvestor(39) + /// * Keyring::TrancheInvestor(40) + /// * Keyring::TrancheInvestor(41) + /// * Keyring::TrancheInvestor(42) + /// * Keyring::TrancheInvestor(43) + /// * Keyring::TrancheInvestor(44) + /// * Keyring::TrancheInvestor(45) + /// * Keyring::TrancheInvestor(46) + /// * Keyring::TrancheInvestor(47) + /// * Keyring::TrancheInvestor(48) + /// * Keyring::TrancheInvestor(49) + /// * Keyring::TrancheInvestor(50) + pub fn full_accounts() -> Vec> { + let mut accounts = default_accounts(); + accounts.extend(default_investors()); + accounts } - /// Get account id of a `numeric` account. - pub fn numeric_id(idx: usize) -> AccountId32 { - (*Self::numeric(idx).public().as_array_ref()).into() + /// Returns a Vector of default investor accounts + /// + /// Accounts: + /// * Keyring::TrancheInvestor(1) + /// * Keyring::TrancheInvestor(2) + /// * Keyring::TrancheInvestor(3) + /// * Keyring::TrancheInvestor(4) + /// * Keyring::TrancheInvestor(5) + /// * Keyring::TrancheInvestor(6) + /// * Keyring::TrancheInvestor(7) + /// * Keyring::TrancheInvestor(8) + /// * Keyring::TrancheInvestor(9) + /// * Keyring::TrancheInvestor(10) + /// * Keyring::TrancheInvestor(11) + /// * Keyring::TrancheInvestor(12) + /// * Keyring::TrancheInvestor(13) + /// * Keyring::TrancheInvestor(14) + /// * Keyring::TrancheInvestor(15) + /// * Keyring::TrancheInvestor(16) + /// * Keyring::TrancheInvestor(17) + /// * Keyring::TrancheInvestor(18) + /// * Keyring::TrancheInvestor(19) + /// * Keyring::TrancheInvestor(20) + /// * Keyring::TrancheInvestor(21) + /// * Keyring::TrancheInvestor(22) + /// * Keyring::TrancheInvestor(23) + /// * Keyring::TrancheInvestor(24) + /// * Keyring::TrancheInvestor(25) + /// * Keyring::TrancheInvestor(26) + /// * Keyring::TrancheInvestor(27) + /// * Keyring::TrancheInvestor(28) + /// * Keyring::TrancheInvestor(29) + /// * Keyring::TrancheInvestor(30) + /// * Keyring::TrancheInvestor(31) + /// * Keyring::TrancheInvestor(32) + /// * Keyring::TrancheInvestor(33) + /// * Keyring::TrancheInvestor(34) + /// * Keyring::TrancheInvestor(35) + /// * Keyring::TrancheInvestor(36) + /// * Keyring::TrancheInvestor(37) + /// * Keyring::TrancheInvestor(38) + /// * Keyring::TrancheInvestor(39) + /// * Keyring::TrancheInvestor(40) + /// * Keyring::TrancheInvestor(41) + /// * Keyring::TrancheInvestor(42) + /// * Keyring::TrancheInvestor(43) + /// * Keyring::TrancheInvestor(44) + /// * Keyring::TrancheInvestor(45) + /// * Keyring::TrancheInvestor(46) + /// * Keyring::TrancheInvestor(47) + /// * Keyring::TrancheInvestor(48) + /// * Keyring::TrancheInvestor(49) + /// * Keyring::TrancheInvestor(50) + pub fn default_investors() -> Vec> { + vec![ + Keyring::TrancheInvestor(1), + Keyring::TrancheInvestor(2), + Keyring::TrancheInvestor(3), + Keyring::TrancheInvestor(4), + Keyring::TrancheInvestor(5), + Keyring::TrancheInvestor(6), + Keyring::TrancheInvestor(7), + Keyring::TrancheInvestor(8), + Keyring::TrancheInvestor(9), + Keyring::TrancheInvestor(10), + Keyring::TrancheInvestor(11), + Keyring::TrancheInvestor(12), + Keyring::TrancheInvestor(13), + Keyring::TrancheInvestor(14), + Keyring::TrancheInvestor(15), + Keyring::TrancheInvestor(16), + Keyring::TrancheInvestor(17), + Keyring::TrancheInvestor(18), + Keyring::TrancheInvestor(19), + Keyring::TrancheInvestor(20), + Keyring::TrancheInvestor(21), + Keyring::TrancheInvestor(22), + Keyring::TrancheInvestor(23), + Keyring::TrancheInvestor(24), + Keyring::TrancheInvestor(25), + Keyring::TrancheInvestor(26), + Keyring::TrancheInvestor(27), + Keyring::TrancheInvestor(28), + Keyring::TrancheInvestor(29), + Keyring::TrancheInvestor(30), + Keyring::TrancheInvestor(31), + Keyring::TrancheInvestor(32), + Keyring::TrancheInvestor(33), + Keyring::TrancheInvestor(34), + Keyring::TrancheInvestor(35), + Keyring::TrancheInvestor(36), + Keyring::TrancheInvestor(37), + Keyring::TrancheInvestor(38), + Keyring::TrancheInvestor(39), + Keyring::TrancheInvestor(40), + Keyring::TrancheInvestor(41), + Keyring::TrancheInvestor(42), + Keyring::TrancheInvestor(43), + Keyring::TrancheInvestor(44), + Keyring::TrancheInvestor(45), + Keyring::TrancheInvestor(46), + Keyring::TrancheInvestor(47), + Keyring::TrancheInvestor(48), + Keyring::TrancheInvestor(49), + Keyring::TrancheInvestor(50), + ] } -} -impl From for sp_runtime::MultiSigner { - fn from(x: Keyring) -> Self { - sp_runtime::MultiSigner::Sr25519(x.into()) + impl From> for AccountId32 { + fn from(k: Keyring) -> Self { + k.to_account_id() + } } -} -impl From for sp_runtime::MultiAddress { - fn from(x: Keyring) -> Self { - sp_runtime::MultiAddress::Id(x.into()) + impl From> for Public { + fn from(k: Keyring) -> Self { + k.pair().public() + } } -} -#[derive(Debug)] -pub struct ParseKeyringError; + impl From> for Pair { + fn from(k: Keyring) -> Self { + k.pair() + } + } -impl std::fmt::Display for ParseKeyringError { - fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "ParseKeyringError") + impl From> for [u8; 32] { + fn from(k: Keyring) -> Self { + k.pair().public().0 + } } -} -impl std::str::FromStr for Keyring { - type Err = ParseKeyringError; + impl From> for crate::chain::centrifuge::RuntimeOrigin { + fn from(account: Keyring) -> Self { + crate::chain::centrifuge::RuntimeOrigin::signed(AccountId32::from(account)) + } + } - fn from_str(s: &str) -> Result::Err> { - match s { - "alice" => Ok(Keyring::Alice), - "bob" => Ok(Keyring::Bob), - "charlie" => Ok(Keyring::Charlie), - "dave" => Ok(Keyring::Dave), - "eve" => Ok(Keyring::Eve), - "ferdie" => Ok(Keyring::Ferdie), - "admin" => Ok(Keyring::Admin), - _ => Err(ParseKeyringError), + impl From> for crate::chain::relay::RuntimeOrigin { + fn from(account: Keyring) -> Self { + crate::chain::relay::RuntimeOrigin::signed(AccountId32::from(account)) } } } -/// Returns a Vector of default accounts -/// -/// Accounts: -/// * Keyring::Admin -/// * Keyring::Alice -/// * Keyring::Bob -/// * Keyring::Ferdie -/// * Keyring::Charlie -/// * Keyring::Dave -/// * Keyring::Eve -/// * Keyring::TrancheInvestor(1) -/// * Keyring::TrancheInvestor(2) -/// * Keyring::TrancheInvestor(3) -/// * Keyring::TrancheInvestor(4) -/// * Keyring::TrancheInvestor(5) -/// * Keyring::TrancheInvestor(6) -/// * Keyring::TrancheInvestor(7) -/// * Keyring::TrancheInvestor(8) -/// * Keyring::TrancheInvestor(9) -/// * Keyring::TrancheInvestor(10) -/// * Keyring::TrancheInvestor(11) -/// * Keyring::TrancheInvestor(12) -/// * Keyring::TrancheInvestor(13) -/// * Keyring::TrancheInvestor(14) -/// * Keyring::TrancheInvestor(15) -/// * Keyring::TrancheInvestor(16) -/// * Keyring::TrancheInvestor(17) -/// * Keyring::TrancheInvestor(18) -/// * Keyring::TrancheInvestor(19) -/// * Keyring::TrancheInvestor(20) -/// * Keyring::TrancheInvestor(21) -/// * Keyring::TrancheInvestor(22) -/// * Keyring::TrancheInvestor(23) -/// * Keyring::TrancheInvestor(24) -/// * Keyring::TrancheInvestor(25) -/// * Keyring::TrancheInvestor(26) -/// * Keyring::TrancheInvestor(27) -/// * Keyring::TrancheInvestor(28) -/// * Keyring::TrancheInvestor(29) -/// * Keyring::TrancheInvestor(30) -/// * Keyring::TrancheInvestor(31) -/// * Keyring::TrancheInvestor(32) -/// * Keyring::TrancheInvestor(33) -/// * Keyring::TrancheInvestor(34) -/// * Keyring::TrancheInvestor(35) -/// * Keyring::TrancheInvestor(36) -/// * Keyring::TrancheInvestor(37) -/// * Keyring::TrancheInvestor(38) -/// * Keyring::TrancheInvestor(39) -/// * Keyring::TrancheInvestor(40) -/// * Keyring::TrancheInvestor(41) -/// * Keyring::TrancheInvestor(42) -/// * Keyring::TrancheInvestor(43) -/// * Keyring::TrancheInvestor(44) -/// * Keyring::TrancheInvestor(45) -/// * Keyring::TrancheInvestor(46) -/// * Keyring::TrancheInvestor(47) -/// * Keyring::TrancheInvestor(48) -/// * Keyring::TrancheInvestor(49) -/// * Keyring::TrancheInvestor(50) -pub fn default_accounts() -> Vec { - let mut standard = vec![ - Keyring::Admin, - Keyring::Alice, - Keyring::Bob, - Keyring::Ferdie, - Keyring::Charlie, - Keyring::Dave, - Keyring::Eve, - ]; - standard.extend(default_investors()); - standard -} +pub use ecdsa::Ecdsa; +mod ecdsa { + use sp_core::{ + crypto::AccountId32, + ecdsa::{Pair, Public, Signature}, + Hasher, Pair as PairT, H160, H256, + }; -/// Returns a Vector of default investor accounts -/// -/// Accounts: -/// * Keyring::TrancheInvestor(1) -/// * Keyring::TrancheInvestor(2) -/// * Keyring::TrancheInvestor(3) -/// * Keyring::TrancheInvestor(4) -/// * Keyring::TrancheInvestor(5) -/// * Keyring::TrancheInvestor(6) -/// * Keyring::TrancheInvestor(7) -/// * Keyring::TrancheInvestor(8) -/// * Keyring::TrancheInvestor(9) -/// * Keyring::TrancheInvestor(10) -/// * Keyring::TrancheInvestor(11) -/// * Keyring::TrancheInvestor(12) -/// * Keyring::TrancheInvestor(13) -/// * Keyring::TrancheInvestor(14) -/// * Keyring::TrancheInvestor(15) -/// * Keyring::TrancheInvestor(16) -/// * Keyring::TrancheInvestor(17) -/// * Keyring::TrancheInvestor(18) -/// * Keyring::TrancheInvestor(19) -/// * Keyring::TrancheInvestor(20) -/// * Keyring::TrancheInvestor(21) -/// * Keyring::TrancheInvestor(22) -/// * Keyring::TrancheInvestor(23) -/// * Keyring::TrancheInvestor(24) -/// * Keyring::TrancheInvestor(25) -/// * Keyring::TrancheInvestor(26) -/// * Keyring::TrancheInvestor(27) -/// * Keyring::TrancheInvestor(28) -/// * Keyring::TrancheInvestor(29) -/// * Keyring::TrancheInvestor(30) -/// * Keyring::TrancheInvestor(31) -/// * Keyring::TrancheInvestor(32) -/// * Keyring::TrancheInvestor(33) -/// * Keyring::TrancheInvestor(34) -/// * Keyring::TrancheInvestor(35) -/// * Keyring::TrancheInvestor(36) -/// * Keyring::TrancheInvestor(37) -/// * Keyring::TrancheInvestor(38) -/// * Keyring::TrancheInvestor(39) -/// * Keyring::TrancheInvestor(40) -/// * Keyring::TrancheInvestor(41) -/// * Keyring::TrancheInvestor(42) -/// * Keyring::TrancheInvestor(43) -/// * Keyring::TrancheInvestor(44) -/// * Keyring::TrancheInvestor(45) -/// * Keyring::TrancheInvestor(46) -/// * Keyring::TrancheInvestor(47) -/// * Keyring::TrancheInvestor(48) -/// * Keyring::TrancheInvestor(49) -/// * Keyring::TrancheInvestor(50) -pub fn default_investors() -> Vec { - vec![ - Keyring::TrancheInvestor(1), - Keyring::TrancheInvestor(2), - Keyring::TrancheInvestor(3), - Keyring::TrancheInvestor(4), - Keyring::TrancheInvestor(5), - Keyring::TrancheInvestor(6), - Keyring::TrancheInvestor(7), - Keyring::TrancheInvestor(8), - Keyring::TrancheInvestor(9), - Keyring::TrancheInvestor(10), - Keyring::TrancheInvestor(11), - Keyring::TrancheInvestor(12), - Keyring::TrancheInvestor(13), - Keyring::TrancheInvestor(14), - Keyring::TrancheInvestor(15), - Keyring::TrancheInvestor(16), - Keyring::TrancheInvestor(17), - Keyring::TrancheInvestor(18), - Keyring::TrancheInvestor(19), - Keyring::TrancheInvestor(20), - Keyring::TrancheInvestor(21), - Keyring::TrancheInvestor(22), - Keyring::TrancheInvestor(23), - Keyring::TrancheInvestor(24), - Keyring::TrancheInvestor(25), - Keyring::TrancheInvestor(26), - Keyring::TrancheInvestor(27), - Keyring::TrancheInvestor(28), - Keyring::TrancheInvestor(29), - Keyring::TrancheInvestor(30), - Keyring::TrancheInvestor(31), - Keyring::TrancheInvestor(32), - Keyring::TrancheInvestor(33), - Keyring::TrancheInvestor(34), - Keyring::TrancheInvestor(35), - Keyring::TrancheInvestor(36), - Keyring::TrancheInvestor(37), - Keyring::TrancheInvestor(38), - Keyring::TrancheInvestor(39), - Keyring::TrancheInvestor(40), - Keyring::TrancheInvestor(41), - Keyring::TrancheInvestor(42), - Keyring::TrancheInvestor(43), - Keyring::TrancheInvestor(44), - Keyring::TrancheInvestor(45), - Keyring::TrancheInvestor(46), - Keyring::TrancheInvestor(47), - Keyring::TrancheInvestor(48), - Keyring::TrancheInvestor(49), - Keyring::TrancheInvestor(50), - ] -} + use super::{Crypto, Keyring}; + use crate::chain::centrifuge; + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub struct Ecdsa; -impl From for AccountId32 { - fn from(k: Keyring) -> Self { - k.to_account_id() + impl Crypto for Ecdsa {} + + impl Keyring { + pub fn to_account_id(self) -> AccountId32 { + let h160 = H160::from(H256::from(sp_core::KeccakHasher::hash( + &self.public().as_ref(), + ))); + + runtime_common::account_conversion::AccountConverter::<(), ()>::convert_evm_address( + centrifuge::CHAIN_ID, + h160.0, + ) + } + + pub fn to_h160(self) -> H160 { + H160::from(H256::from(sp_core::KeccakHasher::hash( + &self.public().as_ref(), + ))) + } + + pub fn sign(self, msg: &[u8]) -> Signature { + sp_core::Pair::sign(&Pair::from(self.pair()), msg) + } + + pub fn pair(self) -> Pair { + let path = match self { + Keyring::Admin => "Admin".to_owned(), + Keyring::TrancheInvestor(tranche_index) => format!("Tranche{tranche_index}"), + Keyring::Alice => "Alice".to_owned(), + Keyring::Bob => "Bob".to_owned(), + Keyring::Charlie => "Charlie".to_owned(), + Keyring::Dave => "Dave".to_owned(), + Keyring::Eve => "Eve".to_owned(), + Keyring::Ferdie => "Ferdie".to_owned(), + Keyring::Custom(derivation_path) => derivation_path.to_owned(), + Keyring::__Ignore(..) => unreachable!("Variant can not be instantiated. qed."), + }; + + Pair::from_string(&format!("//{}", path.as_str()), None) + .expect("static values are known good; qed") + } + + pub fn public(self) -> Public { + self.pair().public() + } + + pub fn to_seed(self) -> String { + let path = match self { + Keyring::Admin => "Admin".to_owned(), + Keyring::TrancheInvestor(tranche_index) => format!("Tranche{tranche_index}"), + Keyring::Alice => "Alice".to_owned(), + Keyring::Bob => "Bob".to_owned(), + Keyring::Charlie => "Charlie".to_owned(), + Keyring::Dave => "Dave".to_owned(), + Keyring::Eve => "Eve".to_owned(), + Keyring::Ferdie => "Ferdie".to_owned(), + Keyring::Custom(derivation_path) => derivation_path.to_owned(), + Keyring::__Ignore(..) => unreachable!("Variant can not be instantiated. qed."), + }; + format!("//{}", path.as_str()) + } + + /// Create a crypto `Pair` from a numeric value. + pub fn numeric(idx: usize) -> Pair { + Pair::from_string(&format!("//{}", idx), None) + .expect("numeric values are known good; qed") + } + + /// Get account id of a `numeric` account. + pub fn numeric_id(idx: usize) -> AccountId32 { + let id = Self::numeric(idx); + let h160 = H160::from(H256::from(sp_core::KeccakHasher::hash( + &id.public().as_ref(), + ))); + + runtime_common::account_conversion::AccountConverter::<(), ()>::convert_evm_address( + centrifuge::CHAIN_ID, + h160.0, + ) + } } -} -impl From for Public { - fn from(k: Keyring) -> Self { - k.pair().public() + impl From> for sp_runtime::MultiSigner { + fn from(x: Keyring) -> Self { + sp_runtime::MultiSigner::Ecdsa(x.pair().into()) + } } -} -impl From for Pair { - fn from(k: Keyring) -> Self { - k.pair() + impl From> for sp_runtime::MultiAddress { + fn from(x: Keyring) -> Self { + sp_runtime::MultiAddress::Id(x.to_account_id()) + } } -} -impl From for [u8; 32] { - fn from(k: Keyring) -> Self { - k.pair().public().0 + #[derive(Debug)] + pub struct ParseKeyringError; + impl std::fmt::Display for ParseKeyringError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "ParseKeyringError") + } } -} -impl From for crate::chain::centrifuge::RuntimeOrigin { - fn from(account: Keyring) -> Self { - crate::chain::centrifuge::RuntimeOrigin::signed(AccountId32::from(account)) + impl std::str::FromStr for Keyring { + type Err = ParseKeyringError; + + fn from_str(s: &str) -> Result::Err> { + match s { + "alice" => Ok(Keyring::Alice), + "bob" => Ok(Keyring::Bob), + "charlie" => Ok(Keyring::Charlie), + "dave" => Ok(Keyring::Dave), + "eve" => Ok(Keyring::Eve), + "ferdie" => Ok(Keyring::Ferdie), + "admin" => Ok(Keyring::Admin), + _ => Err(ParseKeyringError), + } + } + } + + /// Returns a Vector of default accounts + /// + /// Accounts: + /// * Keyring::Admin + /// * Keyring::Alice + /// * Keyring::Bob + /// * Keyring::Ferdie + /// * Keyring::Charlie + /// * Keyring::Dave + /// * Keyring::Eve + pub fn default_accounts() -> Vec> { + vec![ + Keyring::Admin, + Keyring::Alice, + Keyring::Bob, + Keyring::Ferdie, + Keyring::Charlie, + Keyring::Dave, + Keyring::Eve, + ] + } + + /// Accounts: + /// * Keyring::Admin + /// * Keyring::Alice + /// * Keyring::Bob + /// * Keyring::Ferdie + /// * Keyring::Charlie + /// * Keyring::Dave + /// * Keyring::Eve + /// * Keyring::TrancheInvestor(1) + /// * Keyring::TrancheInvestor(2) + /// * Keyring::TrancheInvestor(3) + /// * Keyring::TrancheInvestor(4) + /// * Keyring::TrancheInvestor(5) + /// * Keyring::TrancheInvestor(6) + /// * Keyring::TrancheInvestor(7) + /// * Keyring::TrancheInvestor(8) + /// * Keyring::TrancheInvestor(9) + /// * Keyring::TrancheInvestor(10) + /// * Keyring::TrancheInvestor(11) + /// * Keyring::TrancheInvestor(12) + /// * Keyring::TrancheInvestor(13) + /// * Keyring::TrancheInvestor(14) + /// * Keyring::TrancheInvestor(15) + /// * Keyring::TrancheInvestor(16) + /// * Keyring::TrancheInvestor(17) + /// * Keyring::TrancheInvestor(18) + /// * Keyring::TrancheInvestor(19) + /// * Keyring::TrancheInvestor(20) + /// * Keyring::TrancheInvestor(21) + /// * Keyring::TrancheInvestor(22) + /// * Keyring::TrancheInvestor(23) + /// * Keyring::TrancheInvestor(24) + /// * Keyring::TrancheInvestor(25) + /// * Keyring::TrancheInvestor(26) + /// * Keyring::TrancheInvestor(27) + /// * Keyring::TrancheInvestor(28) + /// * Keyring::TrancheInvestor(29) + /// * Keyring::TrancheInvestor(30) + /// * Keyring::TrancheInvestor(31) + /// * Keyring::TrancheInvestor(32) + /// * Keyring::TrancheInvestor(33) + /// * Keyring::TrancheInvestor(34) + /// * Keyring::TrancheInvestor(35) + /// * Keyring::TrancheInvestor(36) + /// * Keyring::TrancheInvestor(37) + /// * Keyring::TrancheInvestor(38) + /// * Keyring::TrancheInvestor(39) + /// * Keyring::TrancheInvestor(40) + /// * Keyring::TrancheInvestor(41) + /// * Keyring::TrancheInvestor(42) + /// * Keyring::TrancheInvestor(43) + /// * Keyring::TrancheInvestor(44) + /// * Keyring::TrancheInvestor(45) + /// * Keyring::TrancheInvestor(46) + /// * Keyring::TrancheInvestor(47) + /// * Keyring::TrancheInvestor(48) + /// * Keyring::TrancheInvestor(49) + /// * Keyring::TrancheInvestor(50) + pub fn full_accounts() -> Vec> { + let mut accounts = default_accounts(); + accounts.extend(default_investors()); + accounts + } + + /// Returns a Vector of default investor accounts + /// + /// Accounts: + /// * Keyring::TrancheInvestor(1) + /// * Keyring::TrancheInvestor(2) + /// * Keyring::TrancheInvestor(3) + /// * Keyring::TrancheInvestor(4) + /// * Keyring::TrancheInvestor(5) + /// * Keyring::TrancheInvestor(6) + /// * Keyring::TrancheInvestor(7) + /// * Keyring::TrancheInvestor(8) + /// * Keyring::TrancheInvestor(9) + /// * Keyring::TrancheInvestor(10) + /// * Keyring::TrancheInvestor(11) + /// * Keyring::TrancheInvestor(12) + /// * Keyring::TrancheInvestor(13) + /// * Keyring::TrancheInvestor(14) + /// * Keyring::TrancheInvestor(15) + /// * Keyring::TrancheInvestor(16) + /// * Keyring::TrancheInvestor(17) + /// * Keyring::TrancheInvestor(18) + /// * Keyring::TrancheInvestor(19) + /// * Keyring::TrancheInvestor(20) + /// * Keyring::TrancheInvestor(21) + /// * Keyring::TrancheInvestor(22) + /// * Keyring::TrancheInvestor(23) + /// * Keyring::TrancheInvestor(24) + /// * Keyring::TrancheInvestor(25) + /// * Keyring::TrancheInvestor(26) + /// * Keyring::TrancheInvestor(27) + /// * Keyring::TrancheInvestor(28) + /// * Keyring::TrancheInvestor(29) + /// * Keyring::TrancheInvestor(30) + /// * Keyring::TrancheInvestor(31) + /// * Keyring::TrancheInvestor(32) + /// * Keyring::TrancheInvestor(33) + /// * Keyring::TrancheInvestor(34) + /// * Keyring::TrancheInvestor(35) + /// * Keyring::TrancheInvestor(36) + /// * Keyring::TrancheInvestor(37) + /// * Keyring::TrancheInvestor(38) + /// * Keyring::TrancheInvestor(39) + /// * Keyring::TrancheInvestor(40) + /// * Keyring::TrancheInvestor(41) + /// * Keyring::TrancheInvestor(42) + /// * Keyring::TrancheInvestor(43) + /// * Keyring::TrancheInvestor(44) + /// * Keyring::TrancheInvestor(45) + /// * Keyring::TrancheInvestor(46) + /// * Keyring::TrancheInvestor(47) + /// * Keyring::TrancheInvestor(48) + /// * Keyring::TrancheInvestor(49) + /// * Keyring::TrancheInvestor(50) + pub fn default_investors() -> Vec> { + vec![ + Keyring::TrancheInvestor(1), + Keyring::TrancheInvestor(2), + Keyring::TrancheInvestor(3), + Keyring::TrancheInvestor(4), + Keyring::TrancheInvestor(5), + Keyring::TrancheInvestor(6), + Keyring::TrancheInvestor(7), + Keyring::TrancheInvestor(8), + Keyring::TrancheInvestor(9), + Keyring::TrancheInvestor(10), + Keyring::TrancheInvestor(11), + Keyring::TrancheInvestor(12), + Keyring::TrancheInvestor(13), + Keyring::TrancheInvestor(14), + Keyring::TrancheInvestor(15), + Keyring::TrancheInvestor(16), + Keyring::TrancheInvestor(17), + Keyring::TrancheInvestor(18), + Keyring::TrancheInvestor(19), + Keyring::TrancheInvestor(20), + Keyring::TrancheInvestor(21), + Keyring::TrancheInvestor(22), + Keyring::TrancheInvestor(23), + Keyring::TrancheInvestor(24), + Keyring::TrancheInvestor(25), + Keyring::TrancheInvestor(26), + Keyring::TrancheInvestor(27), + Keyring::TrancheInvestor(28), + Keyring::TrancheInvestor(29), + Keyring::TrancheInvestor(30), + Keyring::TrancheInvestor(31), + Keyring::TrancheInvestor(32), + Keyring::TrancheInvestor(33), + Keyring::TrancheInvestor(34), + Keyring::TrancheInvestor(35), + Keyring::TrancheInvestor(36), + Keyring::TrancheInvestor(37), + Keyring::TrancheInvestor(38), + Keyring::TrancheInvestor(39), + Keyring::TrancheInvestor(40), + Keyring::TrancheInvestor(41), + Keyring::TrancheInvestor(42), + Keyring::TrancheInvestor(43), + Keyring::TrancheInvestor(44), + Keyring::TrancheInvestor(45), + Keyring::TrancheInvestor(46), + Keyring::TrancheInvestor(47), + Keyring::TrancheInvestor(48), + Keyring::TrancheInvestor(49), + Keyring::TrancheInvestor(50), + ] + } + + impl From> for AccountId32 { + fn from(k: Keyring) -> Self { + k.to_account_id() + } + } + + impl From> for Public { + fn from(k: Keyring) -> Self { + k.pair().public() + } + } + + impl From> for Pair { + fn from(k: Keyring) -> Self { + k.pair() + } + } + + impl From> for crate::chain::centrifuge::RuntimeOrigin { + fn from(account: Keyring) -> Self { + crate::chain::centrifuge::RuntimeOrigin::signed(AccountId32::from(account)) + } + } + + impl From> for crate::chain::relay::RuntimeOrigin { + fn from(account: Keyring) -> Self { + crate::chain::relay::RuntimeOrigin::signed(AccountId32::from(account)) + } } } -impl From for crate::chain::relay::RuntimeOrigin { - fn from(account: Keyring) -> Self { - crate::chain::relay::RuntimeOrigin::signed(AccountId32::from(account)) +pub use ed25519::Ed25519; +mod ed25519 { + use sp_core::{ + crypto::AccountId32, + ed25519::{Pair, Public, Signature}, + Pair as PairT, + }; + + use super::{Crypto, Keyring}; + + #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] + pub struct Ed25519; + + impl Crypto for Ed25519 {} + + impl Keyring { + pub fn to_account_id(self) -> AccountId32 { + self.public().0.into() + } + + pub fn sign(self, msg: &[u8]) -> Signature { + sp_core::Pair::sign(&Pair::from(self.pair()), msg) + } + + pub fn pair(self) -> Pair { + let path = match self { + Keyring::Admin => "Admin".to_owned(), + Keyring::TrancheInvestor(tranche_index) => format!("Tranche{tranche_index}"), + Keyring::Alice => "Alice".to_owned(), + Keyring::Bob => "Bob".to_owned(), + Keyring::Charlie => "Charlie".to_owned(), + Keyring::Dave => "Dave".to_owned(), + Keyring::Eve => "Eve".to_owned(), + Keyring::Ferdie => "Ferdie".to_owned(), + Keyring::Custom(derivation_path) => derivation_path.to_owned(), + Keyring::__Ignore(..) => unreachable!("Variant can not be instantiated. qed."), + }; + + Pair::from_string(&format!("//{}", path.as_str()), None) + .expect("static values are known good; qed") + } + + pub fn public(self) -> Public { + self.pair().public() + } + + pub fn to_seed(self) -> String { + let path = match self { + Keyring::Admin => "Admin".to_owned(), + Keyring::TrancheInvestor(tranche_index) => format!("Tranche{tranche_index}"), + Keyring::Alice => "Alice".to_owned(), + Keyring::Bob => "Bob".to_owned(), + Keyring::Charlie => "Charlie".to_owned(), + Keyring::Dave => "Dave".to_owned(), + Keyring::Eve => "Eve".to_owned(), + Keyring::Ferdie => "Ferdie".to_owned(), + Keyring::Custom(derivation_path) => derivation_path.to_owned(), + Keyring::__Ignore(..) => unreachable!("Variant can not be instantiated. qed."), + }; + format!("//{}", path.as_str()) + } + + /// Create a crypto `Pair` from a numeric value. + pub fn numeric(idx: usize) -> Pair { + Pair::from_string(&format!("//{}", idx), None) + .expect("numeric values are known good; qed") + } + + /// Get account id of a `numeric` account. + pub fn numeric_id(idx: usize) -> AccountId32 { + (*Self::numeric(idx).public().as_array_ref()).into() + } + } + + impl From> for sp_runtime::MultiSigner { + fn from(x: Keyring) -> Self { + sp_runtime::MultiSigner::Ed25519(x.pair().into()) + } + } + + impl From> for sp_runtime::MultiAddress { + fn from(x: Keyring) -> Self { + sp_runtime::MultiAddress::Id(x.to_account_id()) + } + } + + #[derive(Debug)] + pub struct ParseKeyringError; + impl std::fmt::Display for ParseKeyringError { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "ParseKeyringError") + } + } + + impl std::str::FromStr for Keyring { + type Err = ParseKeyringError; + + fn from_str(s: &str) -> Result::Err> { + match s { + "alice" => Ok(Keyring::Alice), + "bob" => Ok(Keyring::Bob), + "charlie" => Ok(Keyring::Charlie), + "dave" => Ok(Keyring::Dave), + "eve" => Ok(Keyring::Eve), + "ferdie" => Ok(Keyring::Ferdie), + "admin" => Ok(Keyring::Admin), + _ => Err(ParseKeyringError), + } + } + } + + /// Returns a Vector of default accounts + /// + /// Accounts: + /// * Keyring::Admin + /// * Keyring::Alice + /// * Keyring::Bob + /// * Keyring::Ferdie + /// * Keyring::Charlie + /// * Keyring::Dave + /// * Keyring::Eve + pub fn default_accounts() -> Vec> { + vec![ + Keyring::Admin, + Keyring::Alice, + Keyring::Bob, + Keyring::Ferdie, + Keyring::Charlie, + Keyring::Dave, + Keyring::Eve, + ] + } + + /// Accounts: + /// * Keyring::Admin + /// * Keyring::Alice + /// * Keyring::Bob + /// * Keyring::Ferdie + /// * Keyring::Charlie + /// * Keyring::Dave + /// * Keyring::Eve + /// * Keyring::TrancheInvestor(1) + /// * Keyring::TrancheInvestor(2) + /// * Keyring::TrancheInvestor(3) + /// * Keyring::TrancheInvestor(4) + /// * Keyring::TrancheInvestor(5) + /// * Keyring::TrancheInvestor(6) + /// * Keyring::TrancheInvestor(7) + /// * Keyring::TrancheInvestor(8) + /// * Keyring::TrancheInvestor(9) + /// * Keyring::TrancheInvestor(10) + /// * Keyring::TrancheInvestor(11) + /// * Keyring::TrancheInvestor(12) + /// * Keyring::TrancheInvestor(13) + /// * Keyring::TrancheInvestor(14) + /// * Keyring::TrancheInvestor(15) + /// * Keyring::TrancheInvestor(16) + /// * Keyring::TrancheInvestor(17) + /// * Keyring::TrancheInvestor(18) + /// * Keyring::TrancheInvestor(19) + /// * Keyring::TrancheInvestor(20) + /// * Keyring::TrancheInvestor(21) + /// * Keyring::TrancheInvestor(22) + /// * Keyring::TrancheInvestor(23) + /// * Keyring::TrancheInvestor(24) + /// * Keyring::TrancheInvestor(25) + /// * Keyring::TrancheInvestor(26) + /// * Keyring::TrancheInvestor(27) + /// * Keyring::TrancheInvestor(28) + /// * Keyring::TrancheInvestor(29) + /// * Keyring::TrancheInvestor(30) + /// * Keyring::TrancheInvestor(31) + /// * Keyring::TrancheInvestor(32) + /// * Keyring::TrancheInvestor(33) + /// * Keyring::TrancheInvestor(34) + /// * Keyring::TrancheInvestor(35) + /// * Keyring::TrancheInvestor(36) + /// * Keyring::TrancheInvestor(37) + /// * Keyring::TrancheInvestor(38) + /// * Keyring::TrancheInvestor(39) + /// * Keyring::TrancheInvestor(40) + /// * Keyring::TrancheInvestor(41) + /// * Keyring::TrancheInvestor(42) + /// * Keyring::TrancheInvestor(43) + /// * Keyring::TrancheInvestor(44) + /// * Keyring::TrancheInvestor(45) + /// * Keyring::TrancheInvestor(46) + /// * Keyring::TrancheInvestor(47) + /// * Keyring::TrancheInvestor(48) + /// * Keyring::TrancheInvestor(49) + /// * Keyring::TrancheInvestor(50) + pub fn full_accounts() -> Vec> { + let mut accounts = default_accounts(); + accounts.extend(default_investors()); + accounts + } + + /// Returns a Vector of default investor accounts + /// + /// Accounts: + /// * Keyring::TrancheInvestor(1) + /// * Keyring::TrancheInvestor(2) + /// * Keyring::TrancheInvestor(3) + /// * Keyring::TrancheInvestor(4) + /// * Keyring::TrancheInvestor(5) + /// * Keyring::TrancheInvestor(6) + /// * Keyring::TrancheInvestor(7) + /// * Keyring::TrancheInvestor(8) + /// * Keyring::TrancheInvestor(9) + /// * Keyring::TrancheInvestor(10) + /// * Keyring::TrancheInvestor(11) + /// * Keyring::TrancheInvestor(12) + /// * Keyring::TrancheInvestor(13) + /// * Keyring::TrancheInvestor(14) + /// * Keyring::TrancheInvestor(15) + /// * Keyring::TrancheInvestor(16) + /// * Keyring::TrancheInvestor(17) + /// * Keyring::TrancheInvestor(18) + /// * Keyring::TrancheInvestor(19) + /// * Keyring::TrancheInvestor(20) + /// * Keyring::TrancheInvestor(21) + /// * Keyring::TrancheInvestor(22) + /// * Keyring::TrancheInvestor(23) + /// * Keyring::TrancheInvestor(24) + /// * Keyring::TrancheInvestor(25) + /// * Keyring::TrancheInvestor(26) + /// * Keyring::TrancheInvestor(27) + /// * Keyring::TrancheInvestor(28) + /// * Keyring::TrancheInvestor(29) + /// * Keyring::TrancheInvestor(30) + /// * Keyring::TrancheInvestor(31) + /// * Keyring::TrancheInvestor(32) + /// * Keyring::TrancheInvestor(33) + /// * Keyring::TrancheInvestor(34) + /// * Keyring::TrancheInvestor(35) + /// * Keyring::TrancheInvestor(36) + /// * Keyring::TrancheInvestor(37) + /// * Keyring::TrancheInvestor(38) + /// * Keyring::TrancheInvestor(39) + /// * Keyring::TrancheInvestor(40) + /// * Keyring::TrancheInvestor(41) + /// * Keyring::TrancheInvestor(42) + /// * Keyring::TrancheInvestor(43) + /// * Keyring::TrancheInvestor(44) + /// * Keyring::TrancheInvestor(45) + /// * Keyring::TrancheInvestor(46) + /// * Keyring::TrancheInvestor(47) + /// * Keyring::TrancheInvestor(48) + /// * Keyring::TrancheInvestor(49) + /// * Keyring::TrancheInvestor(50) + pub fn default_investors() -> Vec> { + vec![ + Keyring::TrancheInvestor(1), + Keyring::TrancheInvestor(2), + Keyring::TrancheInvestor(3), + Keyring::TrancheInvestor(4), + Keyring::TrancheInvestor(5), + Keyring::TrancheInvestor(6), + Keyring::TrancheInvestor(7), + Keyring::TrancheInvestor(8), + Keyring::TrancheInvestor(9), + Keyring::TrancheInvestor(10), + Keyring::TrancheInvestor(11), + Keyring::TrancheInvestor(12), + Keyring::TrancheInvestor(13), + Keyring::TrancheInvestor(14), + Keyring::TrancheInvestor(15), + Keyring::TrancheInvestor(16), + Keyring::TrancheInvestor(17), + Keyring::TrancheInvestor(18), + Keyring::TrancheInvestor(19), + Keyring::TrancheInvestor(20), + Keyring::TrancheInvestor(21), + Keyring::TrancheInvestor(22), + Keyring::TrancheInvestor(23), + Keyring::TrancheInvestor(24), + Keyring::TrancheInvestor(25), + Keyring::TrancheInvestor(26), + Keyring::TrancheInvestor(27), + Keyring::TrancheInvestor(28), + Keyring::TrancheInvestor(29), + Keyring::TrancheInvestor(30), + Keyring::TrancheInvestor(31), + Keyring::TrancheInvestor(32), + Keyring::TrancheInvestor(33), + Keyring::TrancheInvestor(34), + Keyring::TrancheInvestor(35), + Keyring::TrancheInvestor(36), + Keyring::TrancheInvestor(37), + Keyring::TrancheInvestor(38), + Keyring::TrancheInvestor(39), + Keyring::TrancheInvestor(40), + Keyring::TrancheInvestor(41), + Keyring::TrancheInvestor(42), + Keyring::TrancheInvestor(43), + Keyring::TrancheInvestor(44), + Keyring::TrancheInvestor(45), + Keyring::TrancheInvestor(46), + Keyring::TrancheInvestor(47), + Keyring::TrancheInvestor(48), + Keyring::TrancheInvestor(49), + Keyring::TrancheInvestor(50), + ] + } + + impl From> for AccountId32 { + fn from(k: Keyring) -> Self { + k.to_account_id() + } + } + + impl From> for Public { + fn from(k: Keyring) -> Self { + k.pair().public() + } + } + + impl From> for Pair { + fn from(k: Keyring) -> Self { + k.pair() + } + } + + impl From> for [u8; 32] { + fn from(k: Keyring) -> Self { + k.pair().public().0 + } + } + + impl From> for crate::chain::centrifuge::RuntimeOrigin { + fn from(account: Keyring) -> Self { + crate::chain::centrifuge::RuntimeOrigin::signed(AccountId32::from(account)) + } + } + + impl From> for crate::chain::relay::RuntimeOrigin { + fn from(account: Keyring) -> Self { + crate::chain::relay::RuntimeOrigin::signed(AccountId32::from(account)) + } } } +pub trait Crypto: sp_std::fmt::Debug + Clone + Copy + PartialEq + Eq {} + +pub fn all_accounts() -> Vec { + let mut accounts = Vec::new(); + accounts.extend( + sr25519::full_accounts() + .into_iter() + .map(|account| account.to_account_id()), + ); + accounts.extend( + ecdsa::full_accounts() + .into_iter() + .map(|account| account.to_account_id()), + ); + accounts.extend( + ed25519::full_accounts() + .into_iter() + .map(|account| account.to_account_id()), + ); + accounts +} + #[cfg(test)] mod tests { - use sp_core::{sr25519::Pair, Pair as PairT}; + use sp_core::Pair as PairT; use super::*; #[test] fn keyring_works() { - assert!(Pair::verify( - &Keyring::Alice.sign(b"I am Alice!"), + // Sr25519 + assert!(sp_core::sr25519::Pair::verify( + &Keyring::::Alice.sign(b"I am Alice!"), + b"I am Alice!", + &Keyring::::Alice.public(), + )); + assert!(!sp_core::sr25519::Pair::verify( + &Keyring::::Alice.sign(b"I am Alice!"), + b"I am Bob!", + &Keyring::::Alice.public(), + )); + assert!(!sp_core::sr25519::Pair::verify( + &Keyring::::Alice.sign(b"I am Alice!"), + b"I am Alice!", + &Keyring::::Bob.public(), + )); + + // Ed25519 + assert!(sp_core::ed25519::Pair::verify( + &Keyring::::Alice.sign(b"I am Alice!"), + b"I am Alice!", + &Keyring::::Alice.public(), + )); + assert!(!sp_core::ed25519::Pair::verify( + &Keyring::::Alice.sign(b"I am Alice!"), + b"I am Bob!", + &Keyring::::Alice.public(), + )); + assert!(!sp_core::ed25519::Pair::verify( + &Keyring::::Alice.sign(b"I am Alice!"), + b"I am Alice!", + &Keyring::::Bob.public(), + )); + + // Ecdsa + assert!(sp_core::ecdsa::Pair::verify( + &Keyring::::Alice.sign(b"I am Alice!"), b"I am Alice!", - &Keyring::Alice.public(), + &Keyring::::Alice.public(), )); - assert!(!Pair::verify( - &Keyring::Alice.sign(b"I am Alice!"), + assert!(!sp_core::ecdsa::Pair::verify( + &Keyring::::Alice.sign(b"I am Alice!"), b"I am Bob!", - &Keyring::Alice.public(), + &Keyring::::Alice.public(), )); - assert!(!Pair::verify( - &Keyring::Alice.sign(b"I am Alice!"), + assert!(!sp_core::ecdsa::Pair::verify( + &Keyring::::Alice.sign(b"I am Alice!"), b"I am Alice!", - &Keyring::Bob.public(), + &Keyring::::Bob.public(), )); } } diff --git a/runtime/integration-tests/src/utils/env.rs b/runtime/integration-tests/src/utils/env.rs index 63bcb591ac..a8e46d24b5 100644 --- a/runtime/integration-tests/src/utils/env.rs +++ b/runtime/integration-tests/src/utils/env.rs @@ -18,6 +18,7 @@ use std::{ use cfg_primitives::{AuraId, BlockNumber, Index}; use codec::{Decode, Encode}; +use ethabi::Contract; use frame_support::traits::GenesisBuild; use frame_system::EventRecord; use fudge::{ @@ -39,7 +40,7 @@ use sc_executor::{WasmExecutionMethod, WasmExecutor}; use sc_service::{TFullClient, TaskManager}; use sp_consensus_babe::digests::CompatibleDigestItem; use sp_consensus_slots::SlotDuration; -use sp_core::H256; +use sp_core::{H160, H256}; use sp_runtime::{generic::BlockId, traits::Extrinsic, DigestItem, Storage}; use tokio::runtime::Handle; @@ -61,6 +62,14 @@ use crate::{ }, }; +/// Liquidity-Pool solidity artifacts generated by build-script. +/// All needed contracts can be loaded from here +pub const LP_SOL_SOURCES: &str = env!("LP_SOL_SOURCES", "Build script failed to populate environment variable LP_SOL_SOURCES pointing to solidity source files."); + +/// Axelar gateway solidity artifacts generated by build-script. +/// All needed contracts can be loaded from here +pub const AXELAR_SOL_SOURCES: &str = env!("AXELAR_SOL_SOURCES", "Build script failed to populate environment variable AXELAR_SOL_SOURCES pointing to solidity source files."); + pub mod macros { /// A macro that evolves the chain until the provided event and pattern are /// encountered. @@ -444,6 +453,7 @@ pub struct TestEnv { ParachainBuilder, nonce_manager: Arc>, pub events: Arc>, + pub evm_contracts: HashMap<&'static str, (H160, Contract)>, } pub type Header = cfg_primitives::Header; @@ -453,6 +463,18 @@ pub type UncheckedExtrinsic = centrifuge::UncheckedExtrinsic; // NOTE: Nonce management is a known issue when interacting with a chain and // wanting to submit a lot of extrinsic. This interface eases this issues. impl TestEnv { + pub fn try_get_contract(&self, name: &str) -> Option<(H160, Contract)> { + self.evm_contracts.get(name).map(|data| data.clone()) + } + + pub fn insert_contract( + &mut self, + name: &'static str, + info: (H160, Contract), + ) -> Option<(H160, Contract)> { + self.evm_contracts.insert(name, info) + } + pub fn events(&self, chain: Chain, range: EventRange) -> Result>, ()> where sp_runtime::generic::Block: sp_runtime::traits::Block, @@ -923,6 +945,7 @@ fn test_env( centrifuge, Arc::new(Mutex::new(NonceManager::new())), Arc::new(Mutex::new(EventsStorage::new())), + HashMap::new(), ) .expect("ESSENTIAL: Creating new TestEnv instance must not fail.") } diff --git a/runtime/integration-tests/src/utils/evm.rs b/runtime/integration-tests/src/utils/evm.rs index 57bccefb0d..3c9dfcfa95 100644 --- a/runtime/integration-tests/src/utils/evm.rs +++ b/runtime/integration-tests/src/utils/evm.rs @@ -10,15 +10,32 @@ // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. +use std::{fs, path::PathBuf}; + +use ethabi::{Contract, Token}; use frame_support::{dispatch::RawOrigin, traits::fungible::Mutate}; use fudge::primitives::Chain; -use pallet_evm::FeeCalculator; -use runtime_common::account_conversion::AccountConverter; +use pallet_evm::{ExecutionInfo, FeeCalculator, Runner}; +use runtime_common::{ + account_conversion::AccountConverter, + evm::{precompile::LP_AXELAR_GATEWAY, PRECOMPILE_CODE_STORAGE}, +}; use sp_core::{Get, H160, U256}; +const GAS_LIMIT: u64 = 5_000_000; +const VALIDATE: bool = true; +const TRANSACTIONAL: bool = true; + use crate::{ - chain::centrifuge::{Balances, Runtime, PARA_ID}, - utils::env::TestEnv, + chain::{ + centrifuge, + centrifuge::{Balances, Runtime, CHAIN_ID, PARA_ID}, + }, + utils::{ + accounts::{Ecdsa, Keyring}, + env::{TestEnv, AXELAR_SOL_SOURCES, LP_SOL_SOURCES}, + ESSENTIAL, + }, }; pub fn mint_balance_into_derived_account(env: &mut TestEnv, address: H160, balance: u128) { @@ -37,42 +54,222 @@ pub fn mint_balance_into_derived_account(env: &mut TestEnv, address: H160, balan .unwrap(); } -pub fn deploy_contract(env: &mut TestEnv, address: H160, code: Vec) { - let chain_id = env - .with_state(Chain::Para(PARA_ID), || { - pallet_evm_chain_id::Pallet::::get() - }) - .unwrap(); +pub fn view_contract( + env: &mut TestEnv, + caller: H160, + contract_address: H160, + input: Vec, +) -> ExecutionInfo> { + env.with_state(Chain::Para(PARA_ID), || { + let (base_fee, _) = ::FeeCalculator::min_gas_price(); - let derived_address = - AccountConverter::::convert_evm_address(chain_id, address.to_fixed_bytes()); + ::Runner::call( + caller, + contract_address, + input, + U256::zero(), + GAS_LIMIT, + Some(base_fee), + None, + None, + Vec::new(), + // NOTE: Taken from pallet-evm implementation + VALIDATE, + // NOTE: Taken from pallet-evm implementation + TRANSACTIONAL, + ::config(), + ) + .expect(ESSENTIAL) + }) + .expect(ESSENTIAL) +} - let transaction_create_cost = env - .with_state(Chain::Para(PARA_ID), || { - ::config().gas_transaction_create - }) - .unwrap(); +pub fn view_from_source( + env: &mut TestEnv, + caller: H160, + contract_address: H160, + contract: &Contract, + function: &str, + args: &[Token], +) -> ExecutionInfo> { + let input = contract + .function(function) + .expect(ESSENTIAL) + .encode_input(args) + .expect(ESSENTIAL); - let base_fee = env - .with_state(Chain::Para(PARA_ID), || { - let (base_fee, _) = ::FeeCalculator::min_gas_price(); - base_fee - }) - .unwrap(); + view_contract(env, caller, contract_address, input) +} + +pub fn call_contract( + env: &mut TestEnv, + caller: H160, + contract_address: H160, + input: Vec, +) -> ExecutionInfo> { + env.with_mut_state(Chain::Para(PARA_ID), || { + let (base_fee, _) = ::FeeCalculator::min_gas_price(); + + ::Runner::call( + caller, + contract_address, + input, + U256::zero(), + GAS_LIMIT, + Some(base_fee), + None, + None, + Vec::new(), + // NOTE: Taken from pallet-evm implementation + VALIDATE, + // NOTE: Taken from pallet-evm implementation + TRANSACTIONAL, + ::config(), + ) + .expect(ESSENTIAL) + }) + .expect(ESSENTIAL) +} + +pub fn call_from_source( + env: &mut TestEnv, + caller: H160, + contract_address: H160, + contract: &Contract, + function: &str, + args: &[Token], +) -> ExecutionInfo> { + let input = contract + .function(function) + .expect(ESSENTIAL) + .encode_input(args) + .expect(ESSENTIAL); + + call_contract(env, caller, contract_address, input) +} +pub fn deploy_contract(env: &mut TestEnv, address: H160, code: Vec) -> ExecutionInfo { env.with_mut_state(Chain::Para(PARA_ID), || { - pallet_evm::Pallet::::create( - RawOrigin::from(Some(derived_address)).into(), + let (base_fee, _) = ::FeeCalculator::min_gas_price(); + + ::Runner::create( address, code, U256::from(0), - transaction_create_cost * 10, - U256::from(base_fee + 10), + 5_000_000, + Some(U256::from(base_fee)), None, None, Vec::new(), + // NOTE: Taken from pallet-evm implementation + VALIDATE, + // NOTE: Taken from pallet-evm implementation + TRANSACTIONAL, + ::config(), ) - .unwrap(); + .expect(ESSENTIAL) }) - .unwrap(); + .expect(ESSENTIAL) +} + +pub fn deploy_from_source( + env: &mut TestEnv, + path: PathBuf, + creator: H160, + args: Option<&[Token]>, +) -> (H160, Contract) { + let contract_json: serde_json::Value = + serde_json::from_reader(fs::File::open(path).expect(ESSENTIAL)).expect(ESSENTIAL); + + let abi = contract_json.get("abi").expect(ESSENTIAL); + let contract = Contract::load(&mut serde_json::to_string(abi).expect(ESSENTIAL).as_bytes()) + .expect(ESSENTIAL); + let bytecode = hex::decode( + contract_json + .get("bytecode") + .expect(ESSENTIAL) + .get("object") + .expect(ESSENTIAL) + .as_str() + .expect(ESSENTIAL) + .trim_start_matches("0x"), + ) + .expect(ESSENTIAL); + let deployed_bytecode = hex::decode( + contract_json + .get("deployedBytecode") + .expect(ESSENTIAL) + .get("object") + .expect(ESSENTIAL) + .as_str() + .expect(ESSENTIAL) + .trim_start_matches("0x"), + ) + .expect(ESSENTIAL); + + let init = match (contract.constructor(), args) { + (None, None) => bytecode, + (Some(constructor), Some(args)) => { + constructor.encode_input(bytecode, args).expect(ESSENTIAL) + } + (Some(constructor), None) => constructor.encode_input(bytecode, &[]).expect(ESSENTIAL), + (None, Some(_)) => panic!("{ESSENTIAL}"), + }; + + let info = deploy_contract(env, creator, init); + + let runtime_code = env + .with_state(Chain::Para(PARA_ID), || { + pallet_evm::AccountCodes::::get(info.value) + }) + .expect(ESSENTIAL); + + assert_eq!(runtime_code, deployed_bytecode); + + (info.value, contract) +} + +fn path(sections: &[&str]) -> PathBuf { + let mut path = PathBuf::new(); + + for section in sections { + path.push(*section) + } + + path +} + +pub fn prepare_full_evm(env: &mut TestEnv) { + // This should probably happen for all precompiles. + env.with_mut_state(Chain::Para(PARA_ID), || { + pallet_evm::AccountCodes::::set( + H160::from(LP_AXELAR_GATEWAY), + PRECOMPILE_CODE_STORAGE.to_vec(), + ); + }) + .expect(ESSENTIAL); + + let source = Keyring::::Alice.to_h160(); + + let (gateway, gateway_contract) = deploy_from_source( + env, + path(&[ + LP_SOL_SOURCES, + "LocalGateway.sol", + "PassthroughGateway.json", + ]), + source, + None, + ); + + env.insert_contract("passthrough_gateway", (gateway.clone(), gateway_contract)); + + let (forwarder, forwarder_contract) = deploy_from_source( + env, + path(&[LP_SOL_SOURCES, "Forwarder.sol", "AxelarForwarder.json"]), + source, + Some(&[Token::Address(ethabi::Address::from(gateway.0))]), + ); + + env.insert_contract("forwarder", (forwarder, forwarder_contract)); } diff --git a/runtime/integration-tests/src/utils/genesis.rs b/runtime/integration-tests/src/utils/genesis.rs index 529d998ad0..54a66cbdc1 100644 --- a/runtime/integration-tests/src/utils/genesis.rs +++ b/runtime/integration-tests/src/utils/genesis.rs @@ -17,7 +17,7 @@ use serde::{Deserialize, Serialize}; use sp_runtime::{AccountId32, Storage}; use crate::utils::{ - accounts::{default_accounts, Keyring}, + accounts::{all_accounts, sr25519, Keyring, Sr25519}, tokens::{DECIMAL_BASE_12, DECIMAL_BASE_18}, AUSD_CURRENCY_ID, RELAY_ASSET_ID, }; @@ -31,14 +31,9 @@ where Runtime::AccountId: From, { pallet_balances::GenesisConfig:: { - balances: default_accounts() + balances: all_accounts() .into_iter() - .map(|acc| { - ( - AccountId32::from(acc).into(), - (100_000 * DECIMAL_BASE_18).into(), - ) - }) + .map(|acc| (acc.into(), (100_000 * DECIMAL_BASE_18).into())) .collect(), } .assimilate_storage(storage) @@ -55,7 +50,7 @@ where Runtime::CurrencyId: From, { orml_tokens::GenesisConfig:: { - balances: default_accounts() + balances: all_accounts() .into_iter() .map(|acc| { ( @@ -166,7 +161,7 @@ where ::Keys: From, /* ::Keys: From, */ { pallet_session::GenesisConfig:: { - keys: default_accounts() + keys: sr25519::default_accounts() .into_iter() .map(|acc| { ( @@ -198,7 +193,7 @@ where use sp_core::Get; pallet_collator_selection::GenesisConfig:: { - invulnerables: vec![Keyring::Admin.to_account_id().into()], + invulnerables: vec![Keyring::::Admin.to_account_id().into()], candidacy_bond: cfg_primitives::MILLI_CFG.into(), desired_candidates: ::MaxCandidates::get(), } @@ -214,7 +209,7 @@ where ::Balance: From, { pallet_block_rewards::GenesisConfig:: { - collators: vec![Keyring::Admin.to_account_id().into()], + collators: vec![Keyring::::Admin.to_account_id().into()], collator_reward: (1000 * cfg_primitives::CFG).into(), total_reward: (10_000 * cfg_primitives::CFG).into(), } @@ -229,7 +224,7 @@ where Runtime: pallet_collective::Config, Runtime::AccountId: From, { - council_members::(default_accounts(), storage) + council_members::(sr25519::default_accounts(), storage) } /// Sets the provided account IDs as council members. diff --git a/runtime/integration-tests/src/utils/mod.rs b/runtime/integration-tests/src/utils/mod.rs index 686713f73b..194c5a52d5 100644 --- a/runtime/integration-tests/src/utils/mod.rs +++ b/runtime/integration-tests/src/utils/mod.rs @@ -37,3 +37,10 @@ pub const AUSD_CURRENCY_ID: CurrencyId = CurrencyId::ForeignAsset(3); pub const USDT_CURRENCY_ID: CurrencyId = CurrencyId::ForeignAsset(1); /// The EVM Chain id of Moonbeam pub const MOONBEAM_EVM_CHAIN_ID: u64 = 1284; + +/// Type that can not be instantiated. +#[derive(Debug, Copy, PartialEq, Eq, Clone, Hash)] +pub enum Never {} + +pub const ESSENTIAL: &str = + "Essential part of the test codebase failed. Assumed infallible under sane circumstances"; diff --git a/runtime/integration-tests/src/utils/pools.rs b/runtime/integration-tests/src/utils/pools.rs index 496884b0df..dbc5eebed6 100644 --- a/runtime/integration-tests/src/utils/pools.rs +++ b/runtime/integration-tests/src/utils/pools.rs @@ -400,6 +400,7 @@ mod with_ext { use cfg_traits::PoolNAV; use super::*; + use crate::utils::accounts::Sr25519; /// Whitelists 10 tranche-investors per tranche. /// @@ -449,7 +450,7 @@ mod with_ext { pub fn get_tranche_prices(pool: PoolId) -> Vec { let now = Timestamp::now(); let mut details = PoolSystem::pool(pool).expect("POOLS: Getting pool failed."); - Loans::update_portfolio_valuation(Keyring::Admin.into(), pool) + Loans::update_portfolio_valuation(Keyring::::Admin.into(), pool) .expect("LOANS: UpdatingNav failed"); let (epoch_nav, _) = >::nav(pool).expect("LOANS: Getting NAV failed"); @@ -479,11 +480,19 @@ mod with_ext { /// /// **Needs: Mut Externalities to persist** pub fn permit_admin(id: PoolId) { - permission_for(Keyring::Admin.into(), id, PoolRole::PricingAdmin); - permission_for(Keyring::Admin.into(), id, PoolRole::LiquidityAdmin); - permission_for(Keyring::Admin.into(), id, PoolRole::LoanAdmin); - permission_for(Keyring::Admin.into(), id, PoolRole::InvestorAdmin); - permission_for(Keyring::Admin.into(), id, PoolRole::Borrower); + permission_for(Keyring::::Admin.into(), id, PoolRole::PricingAdmin); + permission_for( + Keyring::::Admin.into(), + id, + PoolRole::LiquidityAdmin, + ); + permission_for(Keyring::::Admin.into(), id, PoolRole::LoanAdmin); + permission_for( + Keyring::::Admin.into(), + id, + PoolRole::InvestorAdmin, + ); + permission_for(Keyring::::Admin.into(), id, PoolRole::Borrower); } /// Add a `PoolRole::TrancheInvestor to a Keyring::TrancheInvestor(u32) @@ -492,7 +501,7 @@ mod with_ext { /// **Needs: Mut Externalities to persist** pub fn permit_investor(investor: u32, pool: PoolId, tranche: TrancheId) { permission_for( - Keyring::TrancheInvestor(investor).into(), + Keyring::::TrancheInvestor(investor).into(), pool, PoolRole::TrancheInvestor(tranche, SECONDS_PER_YEAR), ) diff --git a/runtime/integration-tests/submodules/axelar-cgp-solidity b/runtime/integration-tests/submodules/axelar-cgp-solidity new file mode 160000 index 0000000000..4c38242fb4 --- /dev/null +++ b/runtime/integration-tests/submodules/axelar-cgp-solidity @@ -0,0 +1 @@ +Subproject commit 4c38242fb4e72dc183c035309a4877a898dea4a5 diff --git a/runtime/integration-tests/submodules/liquidity-pools b/runtime/integration-tests/submodules/liquidity-pools new file mode 160000 index 0000000000..9da666e268 --- /dev/null +++ b/runtime/integration-tests/submodules/liquidity-pools @@ -0,0 +1 @@ +Subproject commit 9da666e26841226ac0f558f66aa8716b50fea2af