diff --git a/Cargo.lock b/Cargo.lock index c6f5104cb..15812a4db 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -776,14 +776,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8d696c370c750c948ada61c69a0ee2cbbb9c50b1019ddb86d9317157a99c2cae" -[[package]] -name = "bridge-pot-currency-swap" -version = "0.1.0" -dependencies = [ - "frame-support", - "primitives-currency-swap", -] - [[package]] name = "bs58" version = "0.4.0" @@ -3674,7 +3666,6 @@ version = "0.1.0" dependencies = [ "author-ext-api", "bioauth-flow-api", - "bridge-pot-currency-swap", "chrono", "crypto-utils", "eip191-crypto", @@ -3704,6 +3695,7 @@ dependencies = [ "pallet-base-fee", "pallet-bioauth", "pallet-bootnodes", + "pallet-bridge-pot-currency-swap", "pallet-chain-properties", "pallet-chain-start-moment", "pallet-currency-swap", @@ -5892,6 +5884,22 @@ dependencies = [ "sp-std", ] +[[package]] +name = "pallet-bridge-pot-currency-swap" +version = "0.1.0" +dependencies = [ + "frame-support", + "frame-system", + "mockall", + "pallet-balances", + "pallet-pot", + "parity-scale-codec", + "primitives-currency-swap", + "scale-info", + "sp-core", + "sp-std", +] + [[package]] name = "pallet-chain-properties" version = "0.1.0" diff --git a/crates/bridge-pot-currency-swap/Cargo.toml b/crates/bridge-pot-currency-swap/Cargo.toml deleted file mode 100644 index e02df5338..000000000 --- a/crates/bridge-pot-currency-swap/Cargo.toml +++ /dev/null @@ -1,15 +0,0 @@ -[package] -name = "bridge-pot-currency-swap" -version = "0.1.0" -edition = "2021" -publish = false - -[dependencies] -primitives-currency-swap = { version = "0.1", path = "../primitives-currency-swap", default-features = false } - -frame-support = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "locked/polkadot-v0.9.38" } - -[features] -default = ["std"] -std = ["frame-support/std", "primitives-currency-swap/std"] -try-runtime = ["frame-support/try-runtime", "primitives-currency-swap/try-runtime"] diff --git a/crates/bridge-pot-currency-swap/src/lib.rs b/crates/bridge-pot-currency-swap/src/lib.rs deleted file mode 100644 index c9da023f2..000000000 --- a/crates/bridge-pot-currency-swap/src/lib.rs +++ /dev/null @@ -1,56 +0,0 @@ -//! Bridge pot currency swap implementation. - -// Either generate code at stadard mode, or `no_std`, based on the `std` feature presence. -#![cfg_attr(not(feature = "std"), no_std)] - -use frame_support::{ - sp_runtime::traits::Convert, - sp_std::marker::PhantomData, - traits::{fungible::Inspect, Currency, Get}, -}; - -pub mod existence_optional; -pub mod existence_required; - -pub use existence_optional::Marker as ExistenceOptional; -pub use existence_required::Marker as ExistenceRequired; - -/// The config for the generic bridge pot currency swap logic. -pub trait Config { - /// The type representing the account key for the currency to swap from. - type AccountIdFrom; - - /// The type representing the account key for the currency to swap to. - type AccountIdTo; - - /// The currency to swap from. - type CurrencyFrom: Currency - + Inspect< - Self::AccountIdFrom, - Balance = >::Balance, - >; - - /// The currency to swap to. - type CurrencyTo: Currency - + Inspect< - Self::AccountIdTo, - Balance = >::Balance, - >; - - /// The converter to determine how the balance amount should be converted from one currency to - /// another. - type BalanceConverter: Convert< - >::Balance, - >::Balance, - >; - - /// The account to land the balances to when receiving the funds as part of the swap operation. - type PotFrom: Get; - - /// The account to take the balances from when sending the funds as part of the swap operation. - type PotTo: Get; -} - -/// A [`primitives_currency_swap::CurrencySwap`] implementation that does the swap using two -/// "pot" accounts for each of end swapped currencies. -pub struct CurrencySwap(PhantomData<(T, ExistenceRequirement)>); diff --git a/crates/humanode-peer/src/chain_spec.rs b/crates/humanode-peer/src/chain_spec.rs index 5b556053a..a6fd32850 100644 --- a/crates/humanode-peer/src/chain_spec.rs +++ b/crates/humanode-peer/src/chain_spec.rs @@ -377,6 +377,8 @@ fn testnet_genesis( )], total_claimable: Some(DEV_ACCOUNT_BALANCE), }, + evm_to_native_swap_bridge: Default::default(), + native_to_evm_swap_bridge: Default::default(), } } diff --git a/crates/humanode-runtime/Cargo.toml b/crates/humanode-runtime/Cargo.toml index ecf0045da..c75674997 100644 --- a/crates/humanode-runtime/Cargo.toml +++ b/crates/humanode-runtime/Cargo.toml @@ -10,7 +10,6 @@ substrate-wasm-builder = { git = "https://github.com/humanode-network/substrate" [dependencies] author-ext-api = { version = "0.1", path = "../author-ext-api", default-features = false } bioauth-flow-api = { version = "0.1", path = "../bioauth-flow-api", default-features = false } -bridge-pot-currency-swap = { version = "0.1", path = "../bridge-pot-currency-swap", default-features = false } eip191-crypto = { version = "0.1", path = "../eip191-crypto", default-features = false } eip191-token-claim = { version = "0.1", path = "../eip191-token-claim", default-features = false } eip712-account-claim = { version = "0.1", path = "../eip712-account-claim", default-features = false } @@ -19,6 +18,7 @@ eip712-token-claim = { version = "0.1", path = "../eip712-token-claim", default- keystore-bioauth-account-id = { version = "0.1", path = "../keystore-bioauth-account-id", default-features = false } pallet-bioauth = { version = "0.1", path = "../pallet-bioauth", default-features = false } pallet-bootnodes = { version = "0.1", path = "../pallet-bootnodes", default-features = false } +pallet-bridge-pot-currency-swap = { version = "0.1", path = "../pallet-bridge-pot-currency-swap", default-features = false } pallet-chain-properties = { version = "0.1", path = "../pallet-chain-properties", default-features = false } pallet-chain-start-moment = { version = "0.1", path = "../pallet-chain-start-moment", default-features = false } pallet-currency-swap = { version = "0.1", path = "../pallet-currency-swap", default-features = false } @@ -138,7 +138,6 @@ runtime-benchmarks = [ std = [ "author-ext-api/std", "bioauth-flow-api/std", - "bridge-pot-currency-swap/std", "chrono/std", "codec/std", "eip191-crypto/std", @@ -161,6 +160,7 @@ std = [ "pallet-base-fee/std", "pallet-bioauth/std", "pallet-bootnodes/std", + "pallet-bridge-pot-currency-swap/std", "pallet-chain-properties/std", "pallet-chain-start-moment/std", "pallet-currency-swap/std", @@ -217,7 +217,6 @@ std = [ "vesting-scheduling-timestamp/std", ] try-runtime = [ - "bridge-pot-currency-swap/try-runtime", "fp-self-contained/try-runtime", "frame-executive/try-runtime", "frame-support/try-runtime", @@ -229,6 +228,7 @@ try-runtime = [ "pallet-base-fee/try-runtime", "pallet-bioauth/try-runtime", "pallet-bootnodes/try-runtime", + "pallet-bridge-pot-currency-swap/try-runtime", "pallet-chain-properties/try-runtime", "pallet-chain-start-moment/try-runtime", "pallet-currency-swap/try-runtime", diff --git a/crates/humanode-runtime/src/currency_swap.rs b/crates/humanode-runtime/src/currency_swap.rs index 8298a6f9b..1ce96bcfe 100644 --- a/crates/humanode-runtime/src/currency_swap.rs +++ b/crates/humanode-runtime/src/currency_swap.rs @@ -1,44 +1,22 @@ -use bridge_pot_currency_swap::ExistenceRequired; -use sp_runtime::traits::Identity; +use pallet_bridge_pot_currency_swap::ExistenceRequired; use crate::{ - parameter_types, AccountId, Balances, EvmAccountId, EvmBalances, EvmToNativeSwapBridgePot, - FeesPot, NativeToEvmSwapBridgePot, TreasuryPot, + AccountId, EvmAccountId, EvmToNativeSwapBridge, EvmToNativeSwapBridgePot, FeesPot, + NativeToEvmSwapBridge, TreasuryPot, }; -parameter_types! { - pub NativeToEvmSwapBridgePotAccountId: AccountId = NativeToEvmSwapBridgePot::account_id(); - pub EvmToNativeSwapBridgePotAccountId: EvmAccountId = EvmToNativeSwapBridgePot::account_id(); -} - pub type NativeToEvmOneToOne = - bridge_pot_currency_swap::CurrencySwap; - -pub struct NativeToEvmOneToOneConfig; - -impl bridge_pot_currency_swap::Config for NativeToEvmOneToOneConfig { - type AccountIdFrom = AccountId; - type AccountIdTo = EvmAccountId; - type CurrencyFrom = Balances; - type CurrencyTo = EvmBalances; - type BalanceConverter = Identity; - type PotFrom = NativeToEvmSwapBridgePotAccountId; - type PotTo = EvmToNativeSwapBridgePotAccountId; -} + pallet_bridge_pot_currency_swap::CurrencySwap; pub type EvmToNativeOneToOne = - bridge_pot_currency_swap::CurrencySwap; + pallet_bridge_pot_currency_swap::CurrencySwap; -pub struct EvmToNativeOneToOneConfig; +pub struct GenesisVerifier; -impl bridge_pot_currency_swap::Config for EvmToNativeOneToOneConfig { - type AccountIdFrom = EvmAccountId; - type AccountIdTo = AccountId; - type CurrencyFrom = EvmBalances; - type CurrencyTo = Balances; - type BalanceConverter = Identity; - type PotFrom = EvmToNativeSwapBridgePotAccountId; - type PotTo = NativeToEvmSwapBridgePotAccountId; +impl pallet_bridge_pot_currency_swap::GenesisVerifier for GenesisVerifier { + fn verify() -> bool { + true + } } pub struct EvmToNativeProxyConfig; diff --git a/crates/humanode-runtime/src/lib.rs b/crates/humanode-runtime/src/lib.rs index 7977398fe..95168b1b8 100644 --- a/crates/humanode-runtime/src/lib.rs +++ b/crates/humanode-runtime/src/lib.rs @@ -62,7 +62,8 @@ use sp_runtime::{ create_runtime_str, generic, impl_opaque_keys, traits::{ AccountIdLookup, BlakeTwo256, Block as BlockT, DispatchInfoOf, Dispatchable, - IdentifyAccount, NumberFor, One, OpaqueKeys, PostDispatchInfoOf, StaticLookup, Verify, + IdentifyAccount, Identity, NumberFor, One, OpaqueKeys, PostDispatchInfoOf, StaticLookup, + Verify, }, transaction_validity::{ TransactionPriority, TransactionSource, TransactionValidity, TransactionValidityError, @@ -775,6 +776,41 @@ impl pallet_utility::Config for Runtime { type WeightInfo = weights::pallet_utility::WeightInfo; } +parameter_types! { + pub const NativeToEvmSwapBridgePalletId: PalletId = PalletId(*b"hmsb/ne1"); + pub const EvmToNativeSwapBridgePalletId: PalletId = PalletId(*b"hmsb/en1"); +} + +parameter_types! { + pub NativeToEvmSwapBridgePotAccountId: AccountId = NativeToEvmSwapBridgePot::account_id(); + pub EvmToNativeSwapBridgePotAccountId: EvmAccountId = EvmToNativeSwapBridgePot::account_id(); +} + +type BridgeInstanceNativeToEvmSwap = pallet_bridge_pot_currency_swap::Instance1; +type BridgeInstanceEvmToNativeSwap = pallet_bridge_pot_currency_swap::Instance2; + +impl pallet_bridge_pot_currency_swap::Config for Runtime { + type AccountIdFrom = AccountId; + type AccountIdTo = EvmAccountId; + type CurrencyFrom = Balances; + type CurrencyTo = EvmBalances; + type BalanceConverter = Identity; + type PotFrom = NativeToEvmSwapBridgePotAccountId; + type PotTo = EvmToNativeSwapBridgePotAccountId; + type GenesisVerifier = currency_swap::GenesisVerifier; +} + +impl pallet_bridge_pot_currency_swap::Config for Runtime { + type AccountIdFrom = EvmAccountId; + type AccountIdTo = AccountId; + type CurrencyFrom = EvmBalances; + type CurrencyTo = Balances; + type BalanceConverter = Identity; + type PotFrom = EvmToNativeSwapBridgePotAccountId; + type PotTo = NativeToEvmSwapBridgePotAccountId; + type GenesisVerifier = currency_swap::GenesisVerifier; +} + // Create the runtime by composing the FRAME pallets that were previously // configured. construct_runtime!( @@ -820,6 +856,8 @@ construct_runtime!( NativeToEvmSwapBridgePot: pallet_pot:: = 33, EvmToNativeSwapBridgePot: pallet_pot:: = 34, CurrencySwap: pallet_currency_swap = 35, + NativeToEvmSwapBridge: pallet_bridge_pot_currency_swap:: = 36, + EvmToNativeSwapBridge: pallet_bridge_pot_currency_swap:: = 37, } ); diff --git a/crates/humanode-runtime/src/tests/claims_and_vesting.rs b/crates/humanode-runtime/src/tests/claims_and_vesting.rs index 6f7e1c11e..df2155b5d 100644 --- a/crates/humanode-runtime/src/tests/claims_and_vesting.rs +++ b/crates/humanode-runtime/src/tests/claims_and_vesting.rs @@ -353,7 +353,9 @@ fn prepare_genesis_json(token_claims: &str, token_claim_pot_balance: u128) -> St }}, "evmToNativeSwapBridgePot": {{ "initialState": "Initialized" - }} + }}, + "nativeToEvmSwapBridge": null, + "evmToNativeSwapBridge": null }}"# ) } diff --git a/crates/humanode-runtime/src/tests/genesis_config.rs b/crates/humanode-runtime/src/tests/genesis_config.rs index 8d6c5c095..93f9e174e 100644 --- a/crates/humanode-runtime/src/tests/genesis_config.rs +++ b/crates/humanode-runtime/src/tests/genesis_config.rs @@ -117,7 +117,9 @@ fn works() { }, "evmToNativeSwapBridgePot": { "initialState": "Initialized" - } + }, + "nativeToEvmSwapBridge": null, + "evmToNativeSwapBridge": null }"#; let config: GenesisConfig = serde_json::from_str(json_input).unwrap(); assert_ok!(config.build_storage()); @@ -136,7 +138,8 @@ fn unknown_field() { `system`, `bootnodes`, `bioauth`, `babe`, `balances`, `treasuryPot`, \ `feesPot`, `tokenClaimsPot`, `transactionPayment`, `session`, `chainProperties`, \ `ethereumChainId`, `sudo`, `grandpa`, `ethereum`, `evm`, `dynamicFee`, `baseFee`, \ - `imOnline`, `evmAccountsMapping`, `tokenClaims`, `nativeToEvmSwapBridgePot`, `evmToNativeSwapBridgePot` at line 1 column 6" + `imOnline`, `evmAccountsMapping`, `tokenClaims`, `nativeToEvmSwapBridgePot`, \ + `evmToNativeSwapBridgePot`, `nativeToEvmSwapBridge`, `evmToNativeSwapBridge` at line 1 column 6" ); } diff --git a/crates/pallet-bridge-pot-currency-swap/Cargo.toml b/crates/pallet-bridge-pot-currency-swap/Cargo.toml new file mode 100644 index 000000000..9a57a0a6c --- /dev/null +++ b/crates/pallet-bridge-pot-currency-swap/Cargo.toml @@ -0,0 +1,41 @@ +[package] +name = "pallet-bridge-pot-currency-swap" +version = "0.1.0" +edition = "2021" +publish = false + +[dependencies] +primitives-currency-swap = { version = "0.1", path = "../primitives-currency-swap", default-features = false } + +codec = { package = "parity-scale-codec", version = "3.2.2", default-features = false, features = ["derive"] } +frame-support = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "locked/polkadot-v0.9.38" } +frame-system = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "locked/polkadot-v0.9.38" } +scale-info = { version = "2.5.0", default-features = false, features = ["derive"] } +sp-std = { default-features = false, git = "https://github.com/humanode-network/substrate", branch = "locked/polkadot-v0.9.38" } + +[dev-dependencies] +pallet-pot = { version = "0.1", path = "../pallet-pot", default-features = false } + +mockall = "0.11" +pallet-balances = { git = "https://github.com/humanode-network/substrate", branch = "locked/polkadot-v0.9.38" } +sp-core = { git = "https://github.com/humanode-network/substrate", branch = "locked/polkadot-v0.9.38" } + +[features] +default = ["std"] +std = [ + "codec/std", + "frame-support/std", + "frame-system/std", + "pallet-balances/std", + "pallet-pot/std", + "primitives-currency-swap/std", + "scale-info/std", + "sp-std/std", +] +try-runtime = [ + "frame-support/try-runtime", + "frame-system/try-runtime", + "pallet-balances/try-runtime", + "pallet-pot/try-runtime", + "primitives-currency-swap/try-runtime", +] diff --git a/crates/bridge-pot-currency-swap/src/existence_optional.rs b/crates/pallet-bridge-pot-currency-swap/src/existence_optional.rs similarity index 89% rename from crates/bridge-pot-currency-swap/src/existence_optional.rs rename to crates/pallet-bridge-pot-currency-swap/src/existence_optional.rs index 0a7bd3693..e498c8409 100644 --- a/crates/bridge-pot-currency-swap/src/existence_optional.rs +++ b/crates/pallet-bridge-pot-currency-swap/src/existence_optional.rs @@ -6,13 +6,14 @@ use frame_support::{ traits::{Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons}, }; -use super::{Config, CurrencySwap}; +use super::{Config, CurrencySwap, Pallet}; /// A marker type for the implementation that does not require pot accounts existence. pub enum Marker {} -impl primitives_currency_swap::CurrencySwap - for CurrencySwap +impl, I: 'static> + primitives_currency_swap::CurrencySwap + for CurrencySwap, Marker> { type From = T::CurrencyFrom; type To = T::CurrencyTo; diff --git a/crates/bridge-pot-currency-swap/src/existence_required.rs b/crates/pallet-bridge-pot-currency-swap/src/existence_required.rs similarity index 93% rename from crates/bridge-pot-currency-swap/src/existence_required.rs rename to crates/pallet-bridge-pot-currency-swap/src/existence_required.rs index fb0103999..109e3699e 100644 --- a/crates/bridge-pot-currency-swap/src/existence_required.rs +++ b/crates/pallet-bridge-pot-currency-swap/src/existence_required.rs @@ -5,7 +5,7 @@ use frame_support::{ traits::{Currency, ExistenceRequirement, Get, Imbalance, WithdrawReasons}, }; -use super::{Config, CurrencySwap}; +use super::{Config, CurrencySwap, Pallet}; /// A marker type for the implementation that requires pot accounts existence. pub enum Marker {} @@ -30,8 +30,9 @@ impl From for DispatchError { } } -impl primitives_currency_swap::CurrencySwap - for CurrencySwap +impl, I: 'static> + primitives_currency_swap::CurrencySwap + for CurrencySwap, Marker> { type From = T::CurrencyFrom; type To = T::CurrencyTo; diff --git a/crates/pallet-bridge-pot-currency-swap/src/lib.rs b/crates/pallet-bridge-pot-currency-swap/src/lib.rs new file mode 100644 index 000000000..997ecae36 --- /dev/null +++ b/crates/pallet-bridge-pot-currency-swap/src/lib.rs @@ -0,0 +1,126 @@ +//! A substrate pallet for bridge pot currency swap implementation. + +// Either generate code at stadard mode, or `no_std`, based on the `std` feature presence. +#![cfg_attr(not(feature = "std"), no_std)] + +use frame_support::{ + sp_runtime::traits::Convert, + sp_std::marker::PhantomData, + traits::{fungible::Inspect, Currency, StorageVersion}, +}; +pub mod existence_optional; +pub mod existence_required; + +pub use existence_optional::Marker as ExistenceOptional; +pub use existence_required::Marker as ExistenceRequired; +pub use pallet::*; + +#[cfg(test)] +mod mock; + +#[cfg(test)] +mod tests; + +/// The current storage version. +const STORAGE_VERSION: StorageVersion = StorageVersion::new(0); + +/// The interface to verify bridge pot currency swap related data at genesis. +pub trait GenesisVerifier { + /// Verify bridge pot currency swap related data. + fn verify() -> bool; +} + +// We have to temporarily allow some clippy lints. Later on we'll send patches to substrate to +// fix them at their end. +#[allow(clippy::missing_docs_in_private_items)] +#[frame_support::pallet] +pub mod pallet { + use frame_support::{pallet_prelude::*, sp_runtime::traits::MaybeDisplay}; + use sp_std::fmt::Debug; + + use super::*; + + /// The Bridge Pot Currency Swap Pallet. + #[pallet::pallet] + #[pallet::storage_version(STORAGE_VERSION)] + #[pallet::generate_store(pub(super) trait Store)] + pub struct Pallet(_); + + /// Configuration trait of this pallet. + #[pallet::config] + pub trait Config: frame_system::Config { + /// The type representing the account key for the currency to swap from. + type AccountIdFrom: Parameter + + Member + + MaybeSerializeDeserialize + + Debug + + MaybeDisplay + + Ord + + MaxEncodedLen; + + /// The type representing the account key for the currency to swap to. + type AccountIdTo: Parameter + + Member + + MaybeSerializeDeserialize + + Debug + + MaybeDisplay + + Ord + + MaxEncodedLen; + + /// The currency to swap from. + type CurrencyFrom: Currency + + Inspect< + Self::AccountIdFrom, + Balance = >::Balance, + >; + + /// The currency to swap to. + type CurrencyTo: Currency + + Inspect< + Self::AccountIdTo, + Balance = >::Balance, + >; + + /// The converter to determine how the balance amount should be converted from one currency to + /// another. + type BalanceConverter: Convert< + >::Balance, + >::Balance, + >; + + /// The account to land the balances to when receiving the funds as part of the swap operation. + type PotFrom: Get; + + /// The account to take the balances from when sending the funds as part of the swap operation. + type PotTo: Get; + + /// Interface into genesis verifier implementation. + type GenesisVerifier: GenesisVerifier; + } + + #[pallet::genesis_config] + pub struct GenesisConfig, I: 'static = ()>(PhantomData<(T, I)>); + + // The default value for the genesis config type. + #[cfg(feature = "std")] + impl, I: 'static> Default for GenesisConfig { + fn default() -> Self { + Self(PhantomData) + } + } + + // The build of genesis for the pallet. + #[pallet::genesis_build] + impl, I: 'static> GenesisBuild for GenesisConfig { + fn build(&self) { + assert!( + T::GenesisVerifier::verify(), + "invalid genesis bridge pot currency swap related data" + ); + } + } +} + +/// A [`primitives_currency_swap::CurrencySwap`] implementation that does the swap using two +/// "pot" accounts for each of end swapped currencies. +pub struct CurrencySwap(PhantomData<(Pallet, ExistenceRequirement)>); diff --git a/crates/pallet-bridge-pot-currency-swap/src/mock.rs b/crates/pallet-bridge-pot-currency-swap/src/mock.rs new file mode 100644 index 000000000..da4e7f81d --- /dev/null +++ b/crates/pallet-bridge-pot-currency-swap/src/mock.rs @@ -0,0 +1,147 @@ +//! The mock for the pallet. + +// Allow simple integer arithmetic in tests. +#![allow(clippy::integer_arithmetic)] + +use frame_support::{ + parameter_types, sp_io, + sp_runtime::{ + testing::Header, + traits::{BlakeTwo256, Identity, IdentityLookup}, + BuildStorage, + }, + traits::{ConstU32, ConstU64}, + PalletId, +}; +use mockall::mock; +use sp_core::H256; + +use crate::{self as pallet_bridge_pot_currency_swap}; + +pub(crate) const EXISTENTIAL_DEPOSIT: u64 = 10; + +type UncheckedExtrinsic = frame_system::mocking::MockUncheckedExtrinsic; +type Block = frame_system::mocking::MockBlock; + +pub(crate) type AccountId = u64; +type Balance = u64; + +frame_support::construct_runtime!( + pub enum Test where + Block = Block, + NodeBlock = Block, + UncheckedExtrinsic = UncheckedExtrinsic, + { + System: frame_system, + Balances: pallet_balances, + SwapBridgePot: pallet_pot::, + SwapBridge: pallet_bridge_pot_currency_swap::, + } +); + +impl frame_system::Config for Test { + 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 = AccountId; + 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 = ConstU32<16>; +} + +impl pallet_balances::Config for Test { + type Balance = u64; + type RuntimeEvent = RuntimeEvent; + type DustRemoval = (); + type ExistentialDeposit = ConstU64; + type AccountStore = System; + type MaxLocks = (); + type MaxReserves = (); + type ReserveIdentifier = [u8; 8]; + type WeightInfo = (); +} + +parameter_types! { + pub const SwapBridgePotPalletId: PalletId = PalletId(*b"humanod1"); +} + +type PotInstanceSwapBridge = pallet_pot::Instance1; + +impl pallet_pot::Config for Test { + type RuntimeEvent = RuntimeEvent; + type AccountId = AccountId; + type PalletId = SwapBridgePotPalletId; + type Currency = Balances; +} + +mock! { + #[derive(Debug)] + pub GenesisVerifier {} + + impl crate::GenesisVerifier for GenesisVerifier { + fn verify() -> bool; + } +} + +parameter_types! { + pub const SwapBridgePalletId: PalletId = PalletId(*b"hmsb/ne1"); +} + +parameter_types! { + pub SwapBridgePotAccountId: AccountId = SwapBridgePot::account_id(); +} + +type BridgeInstanceNativeToEvmSwap = pallet_bridge_pot_currency_swap::Instance1; + +impl pallet_bridge_pot_currency_swap::Config for Test { + type AccountIdFrom = AccountId; + type AccountIdTo = AccountId; + type CurrencyFrom = Balances; + type CurrencyTo = Balances; + type BalanceConverter = Identity; + type PotFrom = SwapBridgePotAccountId; + type PotTo = SwapBridgePotAccountId; + type GenesisVerifier = MockGenesisVerifier; +} + +// This function basically just builds a genesis storage key/value store according to +// our desired mockup. +pub fn new_test_ext_with(genesis_config: GenesisConfig) -> sp_io::TestExternalities { + let storage = genesis_config.build_storage().unwrap(); + storage.into() +} + +pub fn runtime_lock() -> std::sync::MutexGuard<'static, ()> { + static MOCK_RUNTIME_MUTEX: std::sync::Mutex<()> = std::sync::Mutex::new(()); + + // Ignore the poisoning for the tests that panic. + // We only care about concurrency here, not about the poisoning. + match MOCK_RUNTIME_MUTEX.lock() { + Ok(guard) => guard, + Err(poisoned) => poisoned.into_inner(), + } +} + +pub fn with_runtime_lock(f: impl FnOnce() -> R) -> R { + let lock = runtime_lock(); + let res = f(); + drop(lock); + res +} diff --git a/crates/pallet-bridge-pot-currency-swap/src/tests.rs b/crates/pallet-bridge-pot-currency-swap/src/tests.rs new file mode 100644 index 000000000..365ddd383 --- /dev/null +++ b/crates/pallet-bridge-pot-currency-swap/src/tests.rs @@ -0,0 +1,44 @@ +use crate::mock::*; + +/// This test verifies that the genesis builder correctly ensures genesis verifier result in case +/// it returns false. +#[test] +#[should_panic = "invalid genesis bridge pot currency swap related data"] +fn genesis_verifier_false() { + with_runtime_lock(|| { + let verify_ctx = MockGenesisVerifier::verify_context(); + verify_ctx.expect().once().return_const(false); + + let config = GenesisConfig { + swap_bridge_pot: pallet_pot::GenesisConfig { + initial_state: pallet_pot::InitialState::Unchecked, + }, + ..Default::default() + }; + + new_test_ext_with(config).execute_with(move || {}); + + verify_ctx.checkpoint(); + }) +} + +/// This test verifies that the genesis builder correctly ensures genesis verifier result in case +/// it returns true. +#[test] +fn genesis_verifier_true() { + with_runtime_lock(|| { + let verify_ctx = MockGenesisVerifier::verify_context(); + verify_ctx.expect().once().return_const(true); + + let config = GenesisConfig { + swap_bridge_pot: pallet_pot::GenesisConfig { + initial_state: pallet_pot::InitialState::Unchecked, + }, + ..Default::default() + }; + + new_test_ext_with(config).execute_with(move || {}); + + verify_ctx.checkpoint(); + }) +}