diff --git a/bridges/bin/node/node/Cargo.toml b/bridges/bin/node/node/Cargo.toml
index 84edf0183e35a..f60ad3ac0c826 100644
--- a/bridges/bin/node/node/Cargo.toml
+++ b/bridges/bin/node/node/Cargo.toml
@@ -146,9 +146,7 @@ tag = 'v2.0.0-rc4'
git = "https://github.com/paritytech/substrate.git"
[features]
-default = ["bridge-rialto"]
-bridge-kovan = ["bridge-node-runtime/bridge-kovan"]
-bridge-rialto = ["bridge-node-runtime/bridge-rialto"]
+default = []
runtime-benchmarks = [
"bridge-node-runtime/runtime-benchmarks",
]
diff --git a/bridges/bin/node/node/src/chain_spec.rs b/bridges/bin/node/node/src/chain_spec.rs
index 425448b921c2d..12c97f140e9d2 100644
--- a/bridges/bin/node/node/src/chain_spec.rs
+++ b/bridges/bin/node/node/src/chain_spec.rs
@@ -15,8 +15,8 @@
// along with Parity Bridges Common. If not, see .
use bridge_node_runtime::{
- AccountId, AuraConfig, BalancesConfig, BridgeEthPoAConfig, GenesisConfig, GrandpaConfig, SessionConfig,
- SessionKeys, Signature, SudoConfig, SystemConfig, WASM_BINARY,
+ AccountId, AuraConfig, BalancesConfig, BridgeKovanConfig, BridgeRialtoConfig, GenesisConfig, GrandpaConfig,
+ SessionConfig, SessionKeys, Signature, SudoConfig, SystemConfig, WASM_BINARY,
};
use grandpa_primitives::AuthorityId as GrandpaId;
use sp_consensus_aura::sr25519::AuthorityId as AuraId;
@@ -152,7 +152,8 @@ fn testnet_genesis(
pallet_aura: Some(AuraConfig {
authorities: Vec::new(),
}),
- pallet_bridge_eth_poa: load_bridge_config(),
+ pallet_bridge_eth_poa_Instance1: load_rialto_bridge_config(),
+ pallet_bridge_eth_poa_Instance2: load_kovan_bridge_config(),
pallet_grandpa: Some(GrandpaConfig {
authorities: Vec::new(),
}),
@@ -166,10 +167,18 @@ fn testnet_genesis(
}
}
-fn load_bridge_config() -> Option {
- Some(BridgeEthPoAConfig {
- initial_header: bridge_node_runtime::bridge::genesis_header(),
+fn load_rialto_bridge_config() -> Option {
+ Some(BridgeRialtoConfig {
+ initial_header: bridge_node_runtime::rialto::genesis_header(),
initial_difficulty: 0.into(),
- initial_validators: bridge_node_runtime::bridge::genesis_validators(),
+ initial_validators: bridge_node_runtime::rialto::genesis_validators(),
+ })
+}
+
+fn load_kovan_bridge_config() -> Option {
+ Some(BridgeKovanConfig {
+ initial_header: bridge_node_runtime::kovan::genesis_header(),
+ initial_difficulty: 0.into(),
+ initial_validators: bridge_node_runtime::kovan::genesis_validators(),
})
}
diff --git a/bridges/bin/node/runtime/Cargo.toml b/bridges/bin/node/runtime/Cargo.toml
index c1437ae4d511a..755dc99b343fe 100644
--- a/bridges/bin/node/runtime/Cargo.toml
+++ b/bridges/bin/node/runtime/Cargo.toml
@@ -224,9 +224,7 @@ package = "substrate-wasm-builder-runner"
git = "https://github.com/paritytech/substrate/"
[features]
-default = ["std", "bridge-rialto"]
-bridge-kovan = []
-bridge-rialto = []
+default = ["std"]
std = [
"pallet-aura/std",
"pallet-balances/std",
@@ -268,5 +266,4 @@ runtime-benchmarks = [
"pallet-bridge-eth-poa/runtime-benchmarks",
"sp-bridge-eth-poa/test-helpers",
"sp-runtime/runtime-benchmarks",
- "bridge-kovan",
]
diff --git a/bridges/bin/node/runtime/src/exchange.rs b/bridges/bin/node/runtime/src/exchange.rs
index 75b2007bff286..e41ec9ac40498 100644
--- a/bridges/bin/node/runtime/src/exchange.rs
+++ b/bridges/bin/node/runtime/src/exchange.rs
@@ -30,7 +30,6 @@
use codec::{Decode, Encode};
use frame_support::RuntimeDebug;
use hex_literal::hex;
-use pallet_bridge_currency_exchange::Blockchain;
use sp_bridge_eth_poa::{transaction_decode, RawTransaction};
use sp_currency_exchange::{
Error as ExchangeError, LockFundsTransaction, MaybeLockFundsTransaction, Result as ExchangeResult,
@@ -65,25 +64,6 @@ pub struct EthereumTransactionTag {
pub nonce: sp_core::U256,
}
-/// Eth blockchain from runtime perspective.
-pub struct EthBlockchain;
-
-impl Blockchain for EthBlockchain {
- type Transaction = RawTransaction;
- type TransactionInclusionProof = EthereumTransactionInclusionProof;
-
- fn verify_transaction_inclusion_proof(proof: &Self::TransactionInclusionProof) -> Option {
- let is_transaction_finalized =
- crate::BridgeEthPoA::verify_transaction_finalized(proof.block, proof.index, &proof.proof);
-
- if !is_transaction_finalized {
- return None;
- }
-
- proof.proof.get(proof.index as usize).cloned()
- }
-}
-
/// Eth transaction from runtime perspective.
pub struct EthTransaction;
@@ -147,7 +127,7 @@ impl MaybeLockFundsTransaction for EthTransaction {
/// Prepares everything required to bench claim of funds locked by given transaction.
#[cfg(feature = "runtime-benchmarks")]
-pub(crate) fn prepare_environment_for_claim(
+pub(crate) fn prepare_environment_for_claim, I: pallet_bridge_eth_poa::Instance>(
transactions: &[RawTransaction],
) -> sp_bridge_eth_poa::H256 {
use pallet_bridge_eth_poa::{
@@ -156,8 +136,8 @@ pub(crate) fn prepare_environment_for_claim(
};
use sp_bridge_eth_poa::compute_merkle_root;
- let mut storage = BridgeStorage::::new();
- let header = HeaderBuilder::with_parent_number_on_runtime::(0)
+ let mut storage = BridgeStorage::::new();
+ let header = HeaderBuilder::with_parent_number_on_runtime::(0)
.with_transactions_root(compute_merkle_root(transactions.iter()))
.sign_by(&validator(0));
let header_id = header.compute_id();
diff --git a/bridges/bin/node/runtime/src/kovan.rs b/bridges/bin/node/runtime/src/kovan.rs
index fe62fce163b12..ad641aa728a6d 100644
--- a/bridges/bin/node/runtime/src/kovan.rs
+++ b/bridges/bin/node/runtime/src/kovan.rs
@@ -14,12 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see .
+use crate::exchange::EthereumTransactionInclusionProof;
+
use frame_support::RuntimeDebug;
use hex_literal::hex;
+use pallet_bridge_currency_exchange::PeerBlockchain;
use pallet_bridge_eth_poa::{
AuraConfiguration, PruningStrategy as BridgePruningStrategy, ValidatorsConfiguration, ValidatorsSource,
};
-use sp_bridge_eth_poa::{Address, Header, U256};
+use sp_bridge_eth_poa::{Address, Header, RawTransaction, U256};
use sp_std::prelude::*;
frame_support::parameter_types! {
@@ -131,6 +134,25 @@ impl BridgePruningStrategy for PruningStrategy {
}
}
+/// The Kovan Blockchain as seen by the runtime.
+pub struct KovanBlockchain;
+
+impl PeerBlockchain for KovanBlockchain {
+ type Transaction = RawTransaction;
+ type TransactionInclusionProof = EthereumTransactionInclusionProof;
+
+ fn verify_transaction_inclusion_proof(proof: &Self::TransactionInclusionProof) -> Option {
+ let is_transaction_finalized =
+ crate::BridgeKovan::verify_transaction_finalized(proof.block, proof.index, &proof.proof);
+
+ if !is_transaction_finalized {
+ return None;
+ }
+
+ proof.proof.get(proof.index as usize).cloned()
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/bridges/bin/node/runtime/src/lib.rs b/bridges/bin/node/runtime/src/lib.rs
index 9f473fee9d8ba..6c4ad00692e4b 100644
--- a/bridges/bin/node/runtime/src/lib.rs
+++ b/bridges/bin/node/runtime/src/lib.rs
@@ -32,17 +32,11 @@ pub mod exchange;
#[cfg(feature = "runtime-benchmarks")]
pub mod benches;
-#[cfg(feature = "bridge-kovan")]
pub mod kovan;
-#[cfg(feature = "bridge-rialto")]
pub mod rialto;
#[cfg(feature = "runtime-benchmarks")]
pub use benches as bridge;
-#[cfg(all(feature = "bridge-kovan", not(feature = "runtime-benchmarks")))]
-pub use kovan as bridge;
-#[cfg(all(feature = "bridge-rialto", not(feature = "runtime-benchmarks")))]
-pub use rialto as bridge;
use codec::{Decode, Encode};
use pallet_grandpa::{fg_primitives, AuthorityId as GrandpaId, AuthorityList as GrandpaAuthorityList};
@@ -69,10 +63,12 @@ pub use frame_support::{
weights::{IdentityFee, RuntimeDbWeight, Weight},
StorageValue,
};
+
pub use pallet_balances::Call as BalancesCall;
pub use pallet_bridge_currency_exchange::Call as BridgeCurrencyExchangeCall;
pub use pallet_bridge_eth_poa::Call as BridgeEthPoACall;
pub use pallet_timestamp::Call as TimestampCall;
+
#[cfg(any(feature = "std", test))]
pub use sp_runtime::BuildStorage;
pub use sp_runtime::{Perbill, Permill};
@@ -233,17 +229,39 @@ impl pallet_aura::Trait for Runtime {
type AuthorityId = AuraId;
}
-impl pallet_bridge_eth_poa::Trait for Runtime {
- type AuraConfiguration = bridge::BridgeAuraConfiguration;
- type FinalityVotesCachingInterval = bridge::FinalityVotesCachingInterval;
- type ValidatorsConfiguration = bridge::BridgeValidatorsConfiguration;
- type PruningStrategy = bridge::PruningStrategy;
+type Rialto = pallet_bridge_eth_poa::Instance1;
+impl pallet_bridge_eth_poa::Trait for Runtime {
+ type AuraConfiguration = rialto::BridgeAuraConfiguration;
+ type FinalityVotesCachingInterval = rialto::FinalityVotesCachingInterval;
+ type ValidatorsConfiguration = rialto::BridgeValidatorsConfiguration;
+ type PruningStrategy = rialto::PruningStrategy;
+ type OnHeadersSubmitted = ();
+}
+
+type Kovan = pallet_bridge_eth_poa::Instance2;
+impl pallet_bridge_eth_poa::Trait for Runtime {
+ type AuraConfiguration = kovan::BridgeAuraConfiguration;
+ type FinalityVotesCachingInterval = kovan::FinalityVotesCachingInterval;
+ type ValidatorsConfiguration = kovan::BridgeValidatorsConfiguration;
+ type PruningStrategy = kovan::PruningStrategy;
type OnHeadersSubmitted = ();
}
-impl pallet_bridge_currency_exchange::Trait for Runtime {
+type RialtoCurrencyExchange = pallet_bridge_currency_exchange::Instance1;
+impl pallet_bridge_currency_exchange::Trait for Runtime {
type OnTransactionSubmitted = ();
- type PeerBlockchain = exchange::EthBlockchain;
+ type PeerBlockchain = rialto::RialtoBlockchain;
+ type PeerMaybeLockFundsTransaction = exchange::EthTransaction;
+ type RecipientsMap = sp_currency_exchange::IdentityRecipients;
+ type Amount = Balance;
+ type CurrencyConverter = sp_currency_exchange::IdentityCurrencyConverter;
+ type DepositInto = DepositInto;
+}
+
+type KovanCurrencyExchange = pallet_bridge_currency_exchange::Instance2;
+impl pallet_bridge_currency_exchange::Trait for Runtime {
+ type OnTransactionSubmitted = ();
+ type PeerBlockchain = kovan::KovanBlockchain;
type PeerMaybeLockFundsTransaction = exchange::EthTransaction;
type RecipientsMap = sp_currency_exchange::IdentityRecipients;
type Amount = Balance;
@@ -439,6 +457,10 @@ construct_runtime!(
NodeBlock = opaque::Block,
UncheckedExtrinsic = UncheckedExtrinsic
{
+ BridgeRialto: pallet_bridge_eth_poa::::{Module, Call, Config, Storage, ValidateUnsigned},
+ BridgeKovan: pallet_bridge_eth_poa::::{Module, Call, Config, Storage, ValidateUnsigned},
+ BridgeRialtoCurrencyExchange: pallet_bridge_currency_exchange::::{Module, Call},
+ BridgeKovanCurrencyExchange: pallet_bridge_currency_exchange::::{Module, Call},
System: frame_system::{Module, Call, Config, Storage, Event},
RandomnessCollectiveFlip: pallet_randomness_collective_flip::{Module, Call, Storage},
Timestamp: pallet_timestamp::{Module, Call, Storage, Inherent},
@@ -448,8 +470,6 @@ construct_runtime!(
TransactionPayment: pallet_transaction_payment::{Module, Storage},
Sudo: pallet_sudo::{Module, Call, Config, Storage, Event},
Session: pallet_session::{Module, Call, Storage, Event, Config},
- BridgeEthPoA: pallet_bridge_eth_poa::{Module, Call, Config, Storage, ValidateUnsigned},
- BridgeCurrencyExchange: pallet_bridge_currency_exchange::{Module, Call},
}
);
@@ -535,32 +555,59 @@ impl_runtime_apis! {
}
}
- impl sp_bridge_eth_poa::EthereumHeadersApi for Runtime {
+ impl sp_bridge_eth_poa::RialtoHeaderApi for Runtime {
fn best_block() -> (u64, sp_bridge_eth_poa::H256) {
- let best_block = BridgeEthPoA::best_block();
+ let best_block = BridgeRialto::best_block();
(best_block.number, best_block.hash)
}
fn finalized_block() -> (u64, sp_bridge_eth_poa::H256) {
- let finalized_block = BridgeEthPoA::finalized_block();
+ let finalized_block = BridgeRialto::finalized_block();
(finalized_block.number, finalized_block.hash)
}
fn is_import_requires_receipts(header: sp_bridge_eth_poa::Header) -> bool {
- BridgeEthPoA::is_import_requires_receipts(header)
+ BridgeRialto::is_import_requires_receipts(header)
}
fn is_known_block(hash: sp_bridge_eth_poa::H256) -> bool {
- BridgeEthPoA::is_known_block(hash)
+ BridgeRialto::is_known_block(hash)
}
}
- impl sp_currency_exchange::CurrencyExchangeApi for Runtime {
+ impl sp_bridge_eth_poa::KovanHeaderApi for Runtime {
+ fn best_block() -> (u64, sp_bridge_eth_poa::H256) {
+ let best_block = BridgeKovan::best_block();
+ (best_block.number, best_block.hash)
+ }
+
+ fn finalized_block() -> (u64, sp_bridge_eth_poa::H256) {
+ let finalized_block = BridgeKovan::finalized_block();
+ (finalized_block.number, finalized_block.hash)
+ }
+
+ fn is_import_requires_receipts(header: sp_bridge_eth_poa::Header) -> bool {
+ BridgeKovan::is_import_requires_receipts(header)
+ }
+
+ fn is_known_block(hash: sp_bridge_eth_poa::H256) -> bool {
+ BridgeKovan::is_known_block(hash)
+ }
+ }
+
+ impl sp_currency_exchange::RialtoCurrencyExchangeApi for Runtime {
+ fn filter_transaction_proof(proof: exchange::EthereumTransactionInclusionProof) -> bool {
+ BridgeRialtoCurrencyExchange::filter_transaction_proof(&proof)
+ }
+ }
+
+ impl sp_currency_exchange::KovanCurrencyExchangeApi for Runtime {
fn filter_transaction_proof(proof: exchange::EthereumTransactionInclusionProof) -> bool {
- BridgeCurrencyExchange::filter_transaction_proof(&proof)
+ BridgeKovanCurrencyExchange::filter_transaction_proof(&proof)
}
}
+
impl sp_transaction_pool::runtime_api::TaggedTransactionQueue for Runtime {
fn validate_transaction(
source: TransactionSource,
@@ -656,14 +703,14 @@ impl_runtime_apis! {
ProofParams as BridgeCurrencyExchangeProofParams,
};
- impl BridgeCurrencyExchangeTrait for Runtime {
+ impl BridgeCurrencyExchangeTrait for Runtime {
fn make_proof(
proof_params: BridgeCurrencyExchangeProofParams,
) -> crate::exchange::EthereumTransactionInclusionProof {
use sp_currency_exchange::DepositInto;
if proof_params.recipient_exists {
- ::DepositInto::deposit_into(
+ >::DepositInto::deposit_into(
proof_params.recipient.clone(),
ExistentialDeposit::get(),
).unwrap();
@@ -681,7 +728,7 @@ impl_runtime_apis! {
let transactions = sp_std::iter::repeat(transaction.clone())
.take(1 + proof_params.proof_size_factor as usize)
.collect::>();
- let block_hash = crate::exchange::prepare_environment_for_claim::(&transactions);
+ let block_hash = crate::exchange::prepare_environment_for_claim::(&transactions);
crate::exchange::EthereumTransactionInclusionProof {
block: block_hash,
index: 0,
@@ -690,8 +737,8 @@ impl_runtime_apis! {
}
}
- add_benchmark!(params, batches, b"bridge-eth-poa", BridgeEthPoA);
- add_benchmark!(params, batches, b"bridge-currency-exchange", BridgeCurrencyExchangeBench::);
+ add_benchmark!(params, batches, b"bridge-eth-poa", BridgeKovan);
+ add_benchmark!(params, batches, b"bridge-currency-exchange", BridgeCurrencyExchangeBench::);
if batches.is_empty() { return Err("Benchmark not found for this pallet.".into()) }
Ok(batches)
@@ -785,7 +832,7 @@ mod tests {
let initial_amount =
as Currency>::free_balance(&existing_account);
let additional_amount = 10_000;
- ::DepositInto::deposit_into(
+ >::DepositInto::deposit_into(
existing_account.clone(),
additional_amount,
)
@@ -804,7 +851,7 @@ mod tests {
let initial_amount = 0;
let additional_amount = ExistentialDeposit::get() + 10_000;
let new_account: AccountId = [42u8; 32].into();
- ::DepositInto::deposit_into(
+ >::DepositInto::deposit_into(
new_account.clone(),
additional_amount,
)
diff --git a/bridges/bin/node/runtime/src/rialto.rs b/bridges/bin/node/runtime/src/rialto.rs
index cdc314fb480cc..6560dbb398097 100644
--- a/bridges/bin/node/runtime/src/rialto.rs
+++ b/bridges/bin/node/runtime/src/rialto.rs
@@ -14,12 +14,15 @@
// You should have received a copy of the GNU General Public License
// along with Parity Bridges Common. If not, see .
+use crate::exchange::EthereumTransactionInclusionProof;
+
use frame_support::RuntimeDebug;
use hex_literal::hex;
+use pallet_bridge_currency_exchange::PeerBlockchain;
use pallet_bridge_eth_poa::{
AuraConfiguration, PruningStrategy as TPruningStrategy, ValidatorsConfiguration, ValidatorsSource,
};
-use sp_bridge_eth_poa::{Address, Header, U256};
+use sp_bridge_eth_poa::{Address, Header, RawTransaction, U256};
use sp_std::prelude::*;
frame_support::parameter_types! {
@@ -104,6 +107,25 @@ impl TPruningStrategy for PruningStrategy {
}
}
+/// The Rialto Blockchain as seen by the runtime.
+pub struct RialtoBlockchain;
+
+impl PeerBlockchain for RialtoBlockchain {
+ type Transaction = RawTransaction;
+ type TransactionInclusionProof = EthereumTransactionInclusionProof;
+
+ fn verify_transaction_inclusion_proof(proof: &Self::TransactionInclusionProof) -> Option {
+ let is_transaction_finalized =
+ crate::BridgeRialto::verify_transaction_finalized(proof.block, proof.index, &proof.proof);
+
+ if !is_transaction_finalized {
+ return None;
+ }
+
+ proof.proof.get(proof.index as usize).cloned()
+ }
+}
+
#[cfg(test)]
mod tests {
use super::*;
diff --git a/bridges/modules/currency-exchange/src/benchmarking.rs b/bridges/modules/currency-exchange/src/benchmarking.rs
index dc032720ce3c0..30fb7e63f0075 100644
--- a/bridges/modules/currency-exchange/src/benchmarking.rs
+++ b/bridges/modules/currency-exchange/src/benchmarking.rs
@@ -18,10 +18,10 @@
//! So we are giving runtime opportunity to prepare environment and construct proof
//! before invoking module calls.
-use super::{Blockchain, Call, Module as CurrencyExchangeModule, Trait as CurrencyExchangeTrait};
+use super::{Call, Instance, Module as CurrencyExchangeModule, PeerBlockchain, Trait as CurrencyExchangeTrait};
use sp_std::prelude::*;
-use frame_benchmarking::{account, benchmarks};
+use frame_benchmarking::{account, benchmarks_instance};
use frame_system::RawOrigin;
const SEED: u32 = 0;
@@ -29,7 +29,7 @@ const WORST_TX_SIZE_FACTOR: u32 = 1000;
const WORST_PROOF_SIZE_FACTOR: u32 = 1000;
/// Module we're benchmarking here.
-pub struct Module(CurrencyExchangeModule);
+pub struct Module, I: Instance>(CurrencyExchangeModule);
/// Proof benchmarking parameters.
pub struct ProofParams {
@@ -46,14 +46,14 @@ pub struct ProofParams {
}
/// Trait that must be implemented by runtime.
-pub trait Trait: CurrencyExchangeTrait {
+pub trait Trait: CurrencyExchangeTrait {
/// Prepare proof for importing exchange transaction.
fn make_proof(
proof_params: ProofParams,
- ) -> <::PeerBlockchain as Blockchain>::TransactionInclusionProof;
+ ) -> <>::PeerBlockchain as PeerBlockchain>::TransactionInclusionProof;
}
-benchmarks! {
+benchmarks_instance! {
_ { }
// Benchmark `import_peer_transaction` extrinsic with the best possible conditions:
diff --git a/bridges/modules/currency-exchange/src/lib.rs b/bridges/modules/currency-exchange/src/lib.rs
index 1c39e1aea9323..cf03239c8a664 100644
--- a/bridges/modules/currency-exchange/src/lib.rs
+++ b/bridges/modules/currency-exchange/src/lib.rs
@@ -33,8 +33,8 @@ pub trait OnTransactionSubmitted {
fn on_valid_transaction_submitted(submitter: AccountId);
}
-/// Peer blockhain interface.
-pub trait Blockchain {
+/// Peer blockchain interface.
+pub trait PeerBlockchain {
/// Transaction type.
type Transaction: Parameter;
/// Transaction inclusion proof type.
@@ -47,14 +47,14 @@ pub trait Blockchain {
}
/// The module configuration trait
-pub trait Trait: frame_system::Trait {
+pub trait Trait: frame_system::Trait {
/// Handler for transaction submission result.
type OnTransactionSubmitted: OnTransactionSubmitted;
- /// Peer blockchain type.
- type PeerBlockchain: Blockchain;
+ /// Represents the blockchain that we'll be exchanging currency with.
+ type PeerBlockchain: PeerBlockchain;
/// Peer blockchain transaction parser.
type PeerMaybeLockFundsTransaction: MaybeLockFundsTransaction<
- Transaction = ::Transaction,
+ Transaction = ::Transaction,
>;
/// Map between blockchains recipients.
type RecipientsMap: RecipientsMap<
@@ -73,7 +73,7 @@ pub trait Trait: frame_system::Trait {
}
decl_error! {
- pub enum Error for Module {
+ pub enum Error for Module, I: Instance> {
/// Invalid peer blockchain transaction provided.
InvalidTransaction,
/// Peer transaction has invalid amount.
@@ -96,17 +96,17 @@ decl_error! {
}
decl_module! {
- pub struct Module for enum Call where origin: T::Origin {
+ pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin {
/// Imports lock fund transaction of the peer blockchain.
#[weight = 0] // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78)
pub fn import_peer_transaction(
origin,
- proof: <::PeerBlockchain as Blockchain>::TransactionInclusionProof,
+ proof: <>::PeerBlockchain as PeerBlockchain>::TransactionInclusionProof,
) -> DispatchResult {
let submitter = frame_system::ensure_signed(origin)?;
// verify and parse transaction proof
- let deposit = prepare_deposit_details::(&proof)?;
+ let deposit = prepare_deposit_details::(&proof)?;
// make sure to update the mapping if we deposit successfully to avoid double spending,
// i.e. whenever `deposit_into` is successful we MUST update `Transfers`.
@@ -117,9 +117,9 @@ decl_module! {
match deposit_result {
Ok(_) => (),
Err(ExchangeError::DepositPartiallyFailed) => (),
- Err(error) => return Err(Error::::from(error).into()),
+ Err(error) => return Err(Error::::from(error).into()),
}
- Transfers::::insert(&deposit.transfer_id, ())
+ Transfers::::insert(&deposit.transfer_id, ())
}
// reward submitter for providing valid message
@@ -137,17 +137,17 @@ decl_module! {
}
decl_storage! {
- trait Store for Module as Bridge {
+ trait Store for Module, I: Instance = DefaultInstance> as Bridge {
/// All transfers that have already been claimed.
Transfers: map hasher(blake2_128_concat) ::Id => ();
}
}
-impl Module {
+impl, I: Instance> Module {
/// Returns true if currency exchange module is able to import given transaction proof in
/// its current state.
- pub fn filter_transaction_proof(proof: &::TransactionInclusionProof) -> bool {
- if prepare_deposit_details::(proof).is_err() {
+ pub fn filter_transaction_proof(proof: &::TransactionInclusionProof) -> bool {
+ if prepare_deposit_details::(proof).is_err() {
return false;
}
@@ -155,7 +155,7 @@ impl Module {
}
}
-impl From for Error {
+impl, I: Instance> From for Error {
fn from(error: ExchangeError) -> Self {
match error {
ExchangeError::InvalidTransaction => Error::InvalidTransaction,
@@ -174,7 +174,7 @@ impl OnTransactionSubmitted for () {
}
/// Exchange deposit details.
-struct DepositDetails {
+struct DepositDetails, I: Instance> {
/// Transfer id.
pub transfer_id: ::Id,
/// Transfer recipient.
@@ -185,21 +185,25 @@ struct DepositDetails {
/// Verify and parse transaction proof, preparing everything required for importing
/// this transaction proof.
-fn prepare_deposit_details(
- proof: &<::PeerBlockchain as Blockchain>::TransactionInclusionProof,
-) -> Result, Error> {
+fn prepare_deposit_details, I: Instance>(
+ proof: &<>::PeerBlockchain as PeerBlockchain>::TransactionInclusionProof,
+) -> Result, Error> {
// ensure that transaction is included in finalized block that we know of
- let transaction = ::PeerBlockchain::verify_transaction_inclusion_proof(proof)
- .ok_or_else(|| Error::::UnfinalizedTransaction)?;
+ let transaction = >::PeerBlockchain::verify_transaction_inclusion_proof(proof)
+ .ok_or_else(|| Error::::UnfinalizedTransaction)?;
// parse transaction
- let transaction = ::PeerMaybeLockFundsTransaction::parse(&transaction).map_err(Error::::from)?;
+ let transaction =
+ >::PeerMaybeLockFundsTransaction::parse(&transaction).map_err(Error::::from)?;
let transfer_id = transaction.id;
- ensure!(!Transfers::::contains_key(&transfer_id), Error::::AlreadyClaimed);
+ ensure!(
+ !Transfers::::contains_key(&transfer_id),
+ Error::::AlreadyClaimed
+ );
// grant recipient
- let recipient = T::RecipientsMap::map(transaction.recipient).map_err(Error::::from)?;
- let amount = T::CurrencyConverter::convert(transaction.amount).map_err(Error::::from)?;
+ let recipient = T::RecipientsMap::map(transaction.recipient).map_err(Error::::from)?;
+ let amount = T::CurrencyConverter::convert(transaction.amount).map_err(Error::::from)?;
Ok(DepositDetails {
transfer_id,
@@ -235,13 +239,13 @@ mod tests {
impl OnTransactionSubmitted for DummyTransactionSubmissionHandler {
fn on_valid_transaction_submitted(submitter: AccountId) {
- Transfers::::insert(submitter, ());
+ Transfers::::insert(submitter, ());
}
}
pub struct DummyBlockchain;
- impl Blockchain for DummyBlockchain {
+ impl PeerBlockchain for DummyBlockchain {
type Transaction = RawTransaction;
type TransactionInclusionProof = (bool, RawTransaction);
@@ -386,7 +390,7 @@ mod tests {
new_test_ext().execute_with(|| {
assert_noop!(
Exchange::import_peer_transaction(Origin::signed(SUBMITTER), (false, transaction(0))),
- Error::::UnfinalizedTransaction,
+ Error::::UnfinalizedTransaction,
);
});
}
@@ -399,7 +403,7 @@ mod tests {
Origin::signed(SUBMITTER),
(true, transaction(INVALID_TRANSACTION_ID)),
),
- Error::::InvalidTransaction,
+ Error::::InvalidTransaction,
);
});
}
@@ -413,7 +417,7 @@ mod tests {
Origin::signed(SUBMITTER),
(true, transaction(ALREADY_CLAIMED_TRANSACTION_ID)),
),
- Error::::AlreadyClaimed,
+ Error::::AlreadyClaimed,
);
});
}
@@ -425,7 +429,7 @@ mod tests {
transaction.recipient = UNKNOWN_RECIPIENT_ID;
assert_noop!(
Exchange::import_peer_transaction(Origin::signed(SUBMITTER), (true, transaction)),
- Error::::FailedToMapRecipients,
+ Error::::FailedToMapRecipients,
);
});
}
@@ -437,7 +441,7 @@ mod tests {
transaction.amount = INVALID_AMOUNT;
assert_noop!(
Exchange::import_peer_transaction(Origin::signed(SUBMITTER), (true, transaction)),
- Error::::FailedToConvertCurrency,
+ Error::::FailedToConvertCurrency,
);
});
}
@@ -449,7 +453,7 @@ mod tests {
transaction.amount = MAX_DEPOSIT_AMOUNT + 1;
assert_noop!(
Exchange::import_peer_transaction(Origin::signed(SUBMITTER), (true, transaction)),
- Error::::DepositFailed,
+ Error::::DepositFailed,
);
});
}
diff --git a/bridges/modules/ethereum/src/benchmarking.rs b/bridges/modules/ethereum/src/benchmarking.rs
index 1f0a7fbe96f20..1da7019c6408f 100644
--- a/bridges/modules/ethereum/src/benchmarking.rs
+++ b/bridges/modules/ethereum/src/benchmarking.rs
@@ -21,11 +21,11 @@ use crate::test_utils::{
HeaderBuilder,
};
-use frame_benchmarking::benchmarks;
+use frame_benchmarking::benchmarks_instance;
use frame_system::RawOrigin;
use primitives::{compute_merkle_root, U256};
-benchmarks! {
+benchmarks_instance! {
_ { }
// Benchmark `import_unsigned_header` extrinsic with the best possible conditions:
@@ -37,7 +37,7 @@ benchmarks! {
let n in 1..1000;
let num_validators = 2;
- let initial_header = initialize_bench::(num_validators);
+ let initial_header = initialize_bench::(num_validators);
// prepare header to be inserted
let header = build_custom_header(
@@ -50,7 +50,7 @@ benchmarks! {
);
}: import_unsigned_header(RawOrigin::None, header, None)
verify {
- let storage = BridgeStorage::::new();
+ let storage = BridgeStorage::::new();
assert_eq!(storage.best_block().0.number, 1);
assert_eq!(storage.finalized_block().number, 0);
}
@@ -67,9 +67,9 @@ benchmarks! {
// finalization.
let n in 1..7;
- let mut storage = BridgeStorage::::new();
+ let mut storage = BridgeStorage::::new();
let num_validators: u32 = 2;
- let initial_header = initialize_bench::(num_validators as usize);
+ let initial_header = initialize_bench::(num_validators as usize);
// Since we only have two validators we need to make sure the number of blocks is even to
// make sure the right validator signs the final block
@@ -95,7 +95,7 @@ benchmarks! {
let header = HeaderBuilder::with_parent(&last_header).sign_by(&last_authority);
}: import_unsigned_header(RawOrigin::None, header, None)
verify {
- let storage = BridgeStorage::::new();
+ let storage = BridgeStorage::::new();
assert_eq!(storage.best_block().0.number, (num_blocks + 1) as u64);
assert_eq!(storage.finalized_block().number, num_blocks as u64);
}
@@ -108,9 +108,9 @@ benchmarks! {
// finalization.
let n in 7..100;
- let mut storage = BridgeStorage::::new();
+ let mut storage = BridgeStorage::::new();
let num_validators: u32 = 2;
- let initial_header = initialize_bench::(num_validators as usize);
+ let initial_header = initialize_bench::(num_validators as usize);
// Since we only have two validators we need to make sure the number of blocks is even to
// make sure the right validator signs the final block
@@ -136,7 +136,7 @@ benchmarks! {
let header = HeaderBuilder::with_parent(&last_header).sign_by(&last_authority);
}: import_unsigned_header(RawOrigin::None, header, None)
verify {
- let storage = BridgeStorage::::new();
+ let storage = BridgeStorage::::new();
assert_eq!(storage.best_block().0.number, (num_blocks + 1) as u64);
assert_eq!(storage.finalized_block().number, num_blocks as u64);
}
@@ -148,14 +148,14 @@ benchmarks! {
import_unsigned_pruning {
let n in 1..MAX_BLOCKS_TO_PRUNE_IN_SINGLE_IMPORT as u32;
- let mut storage = BridgeStorage::::new();
+ let mut storage = BridgeStorage::::new();
let num_validators = 3;
- let initial_header = initialize_bench::(num_validators as usize);
+ let initial_header = initialize_bench::(num_validators as usize);
let validators = validators(num_validators);
// Want to prune eligible blocks between [0, n)
- BlocksToPrune::put(PruningRange {
+ BlocksToPrune::::put(PruningRange {
oldest_unpruned_block: 0,
oldest_block_to_keep: n as u64,
});
@@ -171,11 +171,11 @@ benchmarks! {
let header = HeaderBuilder::with_parent(&parent).sign_by_set(&validators);
}: import_unsigned_header(RawOrigin::None, header, None)
verify {
- let storage = BridgeStorage::::new();
+ let storage = BridgeStorage::::new();
let max_pruned: u64 = (n - 1) as _;
assert_eq!(storage.best_block().0.number, (n + 1) as u64);
- assert!(HeadersByNumber::get(&0).is_none());
- assert!(HeadersByNumber::get(&max_pruned).is_none());
+ assert!(HeadersByNumber::::get(&0).is_none());
+ assert!(HeadersByNumber::::get(&max_pruned).is_none());
}
// The goal of this bench is to import a block which contains a transaction receipt. The receipt
@@ -184,10 +184,10 @@ benchmarks! {
import_unsigned_with_receipts {
let n in 1..100;
- let mut storage = BridgeStorage::::new();
+ let mut storage = BridgeStorage::::new();
let num_validators = 1;
- let initial_header = initialize_bench::(num_validators as usize);
+ let initial_header = initialize_bench::(num_validators as usize);
let mut receipts = vec![];
for i in 1..=n {
@@ -213,18 +213,18 @@ benchmarks! {
);
}: import_unsigned_header(RawOrigin::None, header, Some(receipts))
verify {
- let storage = BridgeStorage::::new();
+ let storage = BridgeStorage::::new();
assert_eq!(storage.best_block().0.number, 2);
}
}
-fn initialize_bench(num_validators: usize) -> Header {
+fn initialize_bench, I: Instance>(num_validators: usize) -> Header {
// Initialize storage with some initial header
let initial_header = build_genesis_header(&validator(0));
let initial_difficulty = initial_header.difficulty;
let initial_validators = validators_addresses(num_validators as usize);
- initialize_storage::(&initial_header, initial_difficulty, &initial_validators);
+ initialize_storage::(&initial_header, initial_difficulty, &initial_validators);
initial_header
}
diff --git a/bridges/modules/ethereum/src/import.rs b/bridges/modules/ethereum/src/import.rs
index 490c164e47b58..20c86cf6eb8b1 100644
--- a/bridges/modules/ethereum/src/import.rs
+++ b/bridges/modules/ethereum/src/import.rs
@@ -169,6 +169,7 @@ mod tests {
validators_change_receipt, HeaderBuilder, KeepSomeHeadersBehindBest, TestRuntime, GAS_LIMIT,
};
use crate::validators::ValidatorsSource;
+ use crate::DefaultInstance;
use crate::{BlocksToPrune, BridgeStorage, Headers, PruningRange};
use frame_support::{StorageMap, StorageValue};
use secp256k1::SecretKey;
@@ -352,7 +353,7 @@ mod tests {
step += 3;
}
assert_eq!(
- BlocksToPrune::get(),
+ BlocksToPrune::::get(),
PruningRange {
oldest_unpruned_block: 11,
oldest_block_to_keep: 14,
@@ -378,7 +379,7 @@ mod tests {
.unwrap();
assert_eq!(finalized_blocks, expected_blocks);
assert_eq!(
- BlocksToPrune::get(),
+ BlocksToPrune::::get(),
PruningRange {
oldest_unpruned_block: 15,
oldest_block_to_keep: 15,
diff --git a/bridges/modules/ethereum/src/lib.rs b/bridges/modules/ethereum/src/lib.rs
index bfae5d4b260c4..de25c5aaa218b 100644
--- a/bridges/modules/ethereum/src/lib.rs
+++ b/bridges/modules/ethereum/src/lib.rs
@@ -351,7 +351,7 @@ impl OnHeadersSubmitted for () {
}
/// The module configuration trait.
-pub trait Trait: frame_system::Trait {
+pub trait Trait: frame_system::Trait {
/// Aura configuration.
type AuraConfiguration: Get;
/// Validators configuration.
@@ -372,14 +372,14 @@ pub trait Trait: frame_system::Trait {
}
decl_module! {
- pub struct Module for enum Call where origin: T::Origin {
+ pub struct Module, I: Instance = DefaultInstance> for enum Call where origin: T::Origin {
/// Import single Aura header. Requires transaction to be **UNSIGNED**.
#[weight = 0] // TODO: update me (https://github.com/paritytech/parity-bridges-common/issues/78)
pub fn import_unsigned_header(origin, header: Header, receipts: Option>) {
frame_system::ensure_none(origin)?;
import::import_header(
- &mut BridgeStorage::::new(),
+ &mut BridgeStorage::::new(),
&mut T::PruningStrategy::default(),
&T::AuraConfiguration::get(),
&T::ValidatorsConfiguration::get(),
@@ -400,7 +400,7 @@ decl_module! {
let submitter = frame_system::ensure_signed(origin)?;
let mut finalized_headers = BTreeMap::new();
let import_result = import::import_headers(
- &mut BridgeStorage::::new(),
+ &mut BridgeStorage::::new(),
&mut T::PruningStrategy::default(),
&T::AuraConfiguration::get(),
&T::ValidatorsConfiguration::get(),
@@ -434,7 +434,7 @@ decl_module! {
}
decl_storage! {
- trait Store for Module as Bridge {
+ trait Store for Module, I: Instance = DefaultInstance> as Bridge {
/// Best known block.
BestBlock: (HeaderId, U256);
/// Best finalized block.
@@ -473,7 +473,7 @@ decl_storage! {
"Initial validators set can't be empty",
);
- initialize_storage::(
+ initialize_storage::(
&config.initial_header,
config.initial_difficulty,
&config.initial_validators,
@@ -482,43 +482,47 @@ decl_storage! {
}
}
-impl Module {
+impl, I: Instance> Module {
/// Returns number and hash of the best block known to the bridge module.
/// The caller should only submit `import_header` transaction that makes
/// (or leads to making) other header the best one.
pub fn best_block() -> HeaderId {
- BridgeStorage::::new().best_block().0
+ BridgeStorage::::new().best_block().0
}
/// Returns number and hash of the best finalized block known to the bridge module.
pub fn finalized_block() -> HeaderId {
- BridgeStorage::::new().finalized_block()
+ BridgeStorage::::new().finalized_block()
}
/// Returns true if the import of given block requires transactions receipts.
pub fn is_import_requires_receipts(header: Header) -> bool {
- import::header_import_requires_receipts(&BridgeStorage::::new(), &T::ValidatorsConfiguration::get(), &header)
+ import::header_import_requires_receipts(
+ &BridgeStorage::::new(),
+ &T::ValidatorsConfiguration::get(),
+ &header,
+ )
}
/// Returns true if header is known to the runtime.
pub fn is_known_block(hash: H256) -> bool {
- BridgeStorage::::new().header(&hash).is_some()
+ BridgeStorage::::new().header(&hash).is_some()
}
/// Verify that transaction is included into given finalized block.
pub fn verify_transaction_finalized(block: H256, tx_index: u64, proof: &[RawTransaction]) -> bool {
- crate::verify_transaction_finalized(&BridgeStorage::::new(), block, tx_index, proof)
+ crate::verify_transaction_finalized(&BridgeStorage::::new(), block, tx_index, proof)
}
}
-impl frame_support::unsigned::ValidateUnsigned for Module {
- type Call = Call;
+impl, I: Instance> frame_support::unsigned::ValidateUnsigned for Module {
+ type Call = Call;
fn validate_unsigned(_source: TransactionSource, call: &Self::Call) -> TransactionValidity {
match *call {
Self::Call::import_unsigned_header(ref header, ref receipts) => {
let accept_result = verification::accept_aura_header_into_pool(
- &BridgeStorage::::new(),
+ &BridgeStorage::::new(),
&T::AuraConfiguration::get(),
&T::ValidatorsConfiguration::get(),
&pool_configuration(),
@@ -550,17 +554,17 @@ impl frame_support::unsigned::ValidateUnsigned for Module {
/// Runtime bridge storage.
#[derive(Default)]
-pub struct BridgeStorage(sp_std::marker::PhantomData);
+pub struct BridgeStorage(sp_std::marker::PhantomData<(T, I)>);
-impl BridgeStorage {
+impl, I: Instance> BridgeStorage {
/// Create new BridgeStorage.
pub fn new() -> Self {
- BridgeStorage(sp_std::marker::PhantomData::::default())
+ BridgeStorage(sp_std::marker::PhantomData::<(T, I)>::default())
}
/// Prune old blocks.
fn prune_blocks(&self, mut max_blocks_to_prune: u64, finalized_number: u64, prune_end: u64) {
- let pruning_range = BlocksToPrune::get();
+ let pruning_range = BlocksToPrune::::get();
let mut new_pruning_range = pruning_range.clone();
// update oldest block we want to keep
@@ -579,7 +583,7 @@ impl BridgeStorage {
}
// read hashes of blocks with given number and try to prune these blocks
- let blocks_at_number = HeadersByNumber::take(number);
+ let blocks_at_number = HeadersByNumber::::take(number);
if let Some(mut blocks_at_number) = blocks_at_number {
self.prune_blocks_by_hashes(
&mut max_blocks_to_prune,
@@ -590,7 +594,7 @@ impl BridgeStorage {
// if we haven't pruned all blocks, remember unpruned
if !blocks_at_number.is_empty() {
- HeadersByNumber::insert(number, blocks_at_number);
+ HeadersByNumber::::insert(number, blocks_at_number);
break;
}
}
@@ -606,7 +610,7 @@ impl BridgeStorage {
// update pruning range in storage
if pruning_range != new_pruning_range {
- BlocksToPrune::put(new_pruning_range);
+ BlocksToPrune::::put(new_pruning_range);
}
}
@@ -619,13 +623,13 @@ impl BridgeStorage {
blocks_at_number: &mut Vec,
) {
// ensure that unfinalized headers we want to prune do not have scheduled changes
- if number > finalized_number && blocks_at_number.iter().any(ScheduledChanges::contains_key) {
+ if number > finalized_number && blocks_at_number.iter().any(ScheduledChanges::::contains_key) {
return;
}
// physically remove headers and (probably) obsolete validators sets
while let Some(hash) = blocks_at_number.pop() {
- let header = Headers::::take(&hash);
+ let header = Headers::::take(&hash);
frame_support::debug::trace!(
target: "runtime",
"Pruning PoA header: ({}, {})",
@@ -633,10 +637,10 @@ impl BridgeStorage {
hash,
);
- ScheduledChanges::remove(hash);
- FinalityCache::::remove(hash);
+ ScheduledChanges::::remove(hash);
+ FinalityCache::::remove(hash);
if let Some(header) = header {
- ValidatorsSetsRc::mutate(header.next_validators_set_id, |rc| match *rc {
+ ValidatorsSetsRc::::mutate(header.next_validators_set_id, |rc| match *rc {
Some(rc) if rc > 1 => Some(rc - 1),
_ => None,
});
@@ -651,19 +655,19 @@ impl BridgeStorage {
}
}
-impl Storage for BridgeStorage {
+impl, I: Instance> Storage for BridgeStorage {
type Submitter = T::AccountId;
fn best_block(&self) -> (HeaderId, U256) {
- BestBlock::get()
+ BestBlock::