Support Pallet Instances in Relay (#238)

* Sketch out how to support different bridge pallet instances

* Create a common interface for using pallet instances

* Start introducing generic instance parameter

Attemps to make the compiler happy, but I'm having second thoughts about
this approach. Commiting now as a way to have a checkpoint, but I think
I'm going to need to re-consider my approach here.

Ideally I want a change which introduces minimal changes, but this seems
to be propagating around the codebase in ways I don't want.

* Use trait objects instead of generics

* Implement traits for Boxed trait objects

This is done in order to statisfy trait bounds by types
which use these new trait objects

* Remove Clone usage for sync parameters

* Remove implementation of Default for sync params

* Require that BridgeInstance implements Debug

* Ensure that BridgeInstance trait implements Send/Sync

* Add documentation related to instances

* Rust Fmt

* Remove needless format

* Make instance CLI option case insensitive

* Replace `with_*` constructors with `new`

* Clean up usage of instance structs

* Enforce a default instance in the CLI params

* Build sync params as we process input from CLI

* Remove case insensitivity from sub-tx-mode

I think this should happen, but maybe as part of a different PR

* Process default Eth contract deployment config in CLI

* Build EthereumExchangeParams in CLI

* Process EthereumExchangeSubmitParams params in CLI
This commit is contained in:
Hernando Castano
2020-08-04 12:03:21 -04:00
committed by Bastian Köcher
parent 6fd1651b21
commit 7f8360d8ab
10 changed files with 467 additions and 286 deletions
@@ -26,6 +26,7 @@ use crate::exchange::{
TransactionProofPipeline,
};
use crate::exchange_loop::{run as run_loop, InMemoryStorage};
use crate::instances::BridgeInstance;
use crate::metrics::MetricsParams;
use crate::rpc::{EthereumRpc, SubstrateRpc};
use crate::rpc_errors::RpcError;
@@ -58,15 +59,17 @@ pub enum ExchangeRelayMode {
#[derive(Debug)]
pub struct EthereumExchangeParams {
/// Ethereum connection params.
pub eth: EthereumConnectionParams,
pub eth_params: EthereumConnectionParams,
/// Substrate connection params.
pub sub: SubstrateConnectionParams,
pub sub_params: SubstrateConnectionParams,
/// Substrate signing params.
pub sub_sign: SubstrateSigningParams,
/// Relay working mode.
pub mode: ExchangeRelayMode,
/// Metrics parameters.
pub metrics_params: Option<MetricsParams>,
/// Instance of the bridge pallet being synchronized.
pub instance: Box<dyn BridgeInstance>,
}
/// Ethereum to Substrate exchange pipeline.
@@ -253,18 +256,6 @@ impl TargetClient<EthereumToSubstrateExchange> for SubstrateTransactionsTarget {
}
}
impl Default for EthereumExchangeParams {
fn default() -> Self {
EthereumExchangeParams {
eth: Default::default(),
sub: Default::default(),
sub_sign: Default::default(),
mode: ExchangeRelayMode::Auto(None),
metrics_params: Some(Default::default()),
}
}
}
/// Relay exchange transaction proof(s) to Substrate node.
pub fn run(params: EthereumExchangeParams) {
match params.mode {
@@ -279,14 +270,22 @@ pub fn run(params: EthereumExchangeParams) {
fn run_single_transaction_relay(params: EthereumExchangeParams, eth_tx_hash: H256) {
let mut local_pool = futures::executor::LocalPool::new();
let EthereumExchangeParams {
eth_params,
sub_params,
sub_sign,
instance,
..
} = params;
let result = local_pool.run_until(async move {
let eth_client = EthereumRpcClient::new(params.eth);
let sub_client = SubstrateRpcClient::new(params.sub).await?;
let eth_client = EthereumRpcClient::new(eth_params);
let sub_client = SubstrateRpcClient::new(sub_params, instance).await?;
let source = EthereumTransactionsSource { client: eth_client };
let target = SubstrateTransactionsTarget {
client: sub_client,
sign_params: params.sub_sign,
sign_params: sub_sign,
};
relay_single_transaction_proof(&source, &target, eth_tx_hash).await
@@ -313,9 +312,18 @@ fn run_single_transaction_relay(params: EthereumExchangeParams, eth_tx_hash: H25
/// Run auto-relay loop.
fn run_auto_transactions_relay_loop(params: EthereumExchangeParams, eth_start_with_block_number: Option<u64>) {
let EthereumExchangeParams {
eth_params,
sub_params,
sub_sign,
metrics_params,
instance,
..
} = params;
let do_run_loop = move || -> Result<(), String> {
let eth_client = EthereumRpcClient::new(params.eth);
let sub_client = async_std::task::block_on(SubstrateRpcClient::new(params.sub))
let eth_client = EthereumRpcClient::new(eth_params);
let sub_client = async_std::task::block_on(SubstrateRpcClient::new(sub_params, instance))
.map_err(|err| format!("Error starting Substrate client: {:?}", err))?;
let eth_start_with_block_number = match eth_start_with_block_number {
@@ -337,9 +345,9 @@ fn run_auto_transactions_relay_loop(params: EthereumExchangeParams, eth_start_wi
EthereumTransactionsSource { client: eth_client },
SubstrateTransactionsTarget {
client: sub_client,
sign_params: params.sub_sign,
sign_params: sub_sign,
},
params.metrics_params,
metrics_params,
futures::future::pending(),
);