mirror of
https://github.com/pezkuwichain/pezkuwi-subxt.git
synced 2026-06-14 06:21:11 +00:00
Replace BATCH_CALL_SUPPORTED (#1733)
* Simplify submit_and_watch_signed_extrinsic The way submit_and_watch_signed_extrinsic is used now, we can always derive the SignParam from other params. If in the future we need more customization possibilities, we can define a new method. * Simplify submit_signed_extrinsic * Send maybe_batch_tx as a parameter Send `maybe_batch_tx` as a parameter to `submit_proof()`. This way we can deduplicate the logic that submits the extrinsic for `messages_source and `messages_target` and we can simplify the logic in the race loop a bit. * Define BatchProofTransaction Deduplicate BatchConfirmationTransaction and BatchDeliveryTransaction by replacing both of them with BatchProofTransaction * Define ChainWithUtilityPallet and BatchCallBuilderConstructor - Define `ChainWithUtilityPallet` in order to be able to associate the batching functionality with chains - Defining `BatchCallBuilderConstructor` in order to have a more reliable way of checking whether an end of a messages pipeline supports batching or no. `BatchCallBuilderConstructor::new_builder()` returns an `Option<BatchCallBuilder>`.This is a bit safer because each time a caller tries to start creating a batch call, it will call `new_builder()` and will be required to handle the returned `Option`. Before we only had a bool `BATCH_CALL_SUPPORTED` the caller could have forgetten to check.
This commit is contained in:
committed by
Bastian Köcher
parent
df1aed01c4
commit
e47f1e42e0
@@ -23,7 +23,7 @@ use substrate_relay_helper::{
|
|||||||
DirectReceiveMessagesDeliveryProofCallBuilder, DirectReceiveMessagesProofCallBuilder,
|
DirectReceiveMessagesDeliveryProofCallBuilder, DirectReceiveMessagesProofCallBuilder,
|
||||||
SubstrateMessageLane,
|
SubstrateMessageLane,
|
||||||
},
|
},
|
||||||
BundledBatchCallBuilder,
|
UtilityPalletBatchCallBuilder,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Description of RialtoParachain -> Millau messages bridge.
|
/// Description of RialtoParachain -> Millau messages bridge.
|
||||||
@@ -46,5 +46,5 @@ impl SubstrateMessageLane for RialtoParachainMessagesToMillau {
|
|||||||
>;
|
>;
|
||||||
|
|
||||||
type SourceBatchCallBuilder = ();
|
type SourceBatchCallBuilder = ();
|
||||||
type TargetBatchCallBuilder = BundledBatchCallBuilder<millau_runtime::Runtime>;
|
type TargetBatchCallBuilder = UtilityPalletBatchCallBuilder<Millau>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ use crate::{
|
|||||||
cli::{bridge::CliBridgeBase, chain_schema::*},
|
cli::{bridge::CliBridgeBase, chain_schema::*},
|
||||||
};
|
};
|
||||||
use bp_runtime::Chain as ChainBase;
|
use bp_runtime::Chain as ChainBase;
|
||||||
use relay_substrate_client::{AccountKeyPairOf, Chain, SignParam, UnsignedTransaction};
|
use relay_substrate_client::{AccountKeyPairOf, Chain, UnsignedTransaction};
|
||||||
use sp_core::Pair;
|
use sp_core::Pair;
|
||||||
use structopt::StructOpt;
|
use structopt::StructOpt;
|
||||||
use strum::{EnumString, EnumVariantNames, VariantNames};
|
use strum::{EnumString, EnumVariantNames, VariantNames};
|
||||||
@@ -83,17 +83,10 @@ where
|
|||||||
let target_sign = data.target_sign.to_keypair::<Self::Target>()?;
|
let target_sign = data.target_sign.to_keypair::<Self::Target>()?;
|
||||||
let dry_run = data.dry_run;
|
let dry_run = data.dry_run;
|
||||||
|
|
||||||
let (spec_version, transaction_version) = target_client.simple_runtime_version().await?;
|
|
||||||
substrate_relay_helper::finality::initialize::initialize::<Self::Engine, _, _, _>(
|
substrate_relay_helper::finality::initialize::initialize::<Self::Engine, _, _, _>(
|
||||||
source_client,
|
source_client,
|
||||||
target_client.clone(),
|
target_client.clone(),
|
||||||
target_sign.public().into(),
|
target_sign,
|
||||||
SignParam {
|
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash: *target_client.genesis_hash(),
|
|
||||||
signer: target_sign,
|
|
||||||
},
|
|
||||||
move |transaction_nonce, initialization_data| {
|
move |transaction_nonce, initialization_data| {
|
||||||
let call = Self::encode_init_bridge(initialization_data);
|
let call = Self::encode_init_bridge(initialization_data);
|
||||||
log::info!(
|
log::info!(
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ use polkadot_runtime_common::{
|
|||||||
paras_registrar::Call as ParaRegistrarCall, slots::Call as ParaSlotsCall,
|
paras_registrar::Call as ParaRegistrarCall, slots::Call as ParaSlotsCall,
|
||||||
};
|
};
|
||||||
use polkadot_runtime_parachains::paras::ParaLifecycle;
|
use polkadot_runtime_parachains::paras::ParaLifecycle;
|
||||||
use relay_substrate_client::{AccountIdOf, CallOf, Chain, Client, SignParam, UnsignedTransaction};
|
use relay_substrate_client::{AccountIdOf, CallOf, Chain, Client, UnsignedTransaction};
|
||||||
use relay_utils::{TrackedTransactionStatus, TransactionTracker};
|
use relay_utils::{TrackedTransactionStatus, TransactionTracker};
|
||||||
use rialto_runtime::SudoCall;
|
use rialto_runtime::SudoCall;
|
||||||
use sp_core::{
|
use sp_core::{
|
||||||
@@ -108,28 +108,16 @@ impl RegisterParachain {
|
|||||||
log::info!(target: "bridge", "Going to reserve parachain id: {:?}", para_id);
|
log::info!(target: "bridge", "Going to reserve parachain id: {:?}", para_id);
|
||||||
|
|
||||||
// step 1: reserve a parachain id
|
// step 1: reserve a parachain id
|
||||||
let relay_genesis_hash = *relay_client.genesis_hash();
|
|
||||||
let relay_sudo_account: AccountIdOf<Relaychain> = relay_sign.public().into();
|
let relay_sudo_account: AccountIdOf<Relaychain> = relay_sign.public().into();
|
||||||
let reserve_parachain_id_call: CallOf<Relaychain> =
|
let reserve_parachain_id_call: CallOf<Relaychain> =
|
||||||
ParaRegistrarCall::reserve {}.into();
|
ParaRegistrarCall::reserve {}.into();
|
||||||
let reserve_parachain_signer = relay_sign.clone();
|
|
||||||
let (spec_version, transaction_version) = relay_client.simple_runtime_version().await?;
|
|
||||||
let reserve_result = relay_client
|
let reserve_result = relay_client
|
||||||
.submit_and_watch_signed_extrinsic(
|
.submit_and_watch_signed_extrinsic(&relay_sign, move |_, transaction_nonce| {
|
||||||
relay_sudo_account.clone(),
|
Ok(UnsignedTransaction::new(
|
||||||
SignParam::<Relaychain> {
|
reserve_parachain_id_call.into(),
|
||||||
spec_version,
|
transaction_nonce,
|
||||||
transaction_version,
|
))
|
||||||
genesis_hash: relay_genesis_hash,
|
})
|
||||||
signer: reserve_parachain_signer,
|
|
||||||
},
|
|
||||||
move |_, transaction_nonce| {
|
|
||||||
Ok(UnsignedTransaction::new(
|
|
||||||
reserve_parachain_id_call.into(),
|
|
||||||
transaction_nonce,
|
|
||||||
))
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await?
|
.await?
|
||||||
.wait()
|
.wait()
|
||||||
.await;
|
.await;
|
||||||
@@ -162,23 +150,10 @@ impl RegisterParachain {
|
|||||||
validation_code: ParaValidationCode(para_code),
|
validation_code: ParaValidationCode(para_code),
|
||||||
}
|
}
|
||||||
.into();
|
.into();
|
||||||
let register_parathread_signer = relay_sign.clone();
|
|
||||||
let register_result = relay_client
|
let register_result = relay_client
|
||||||
.submit_and_watch_signed_extrinsic(
|
.submit_and_watch_signed_extrinsic(&relay_sign, move |_, transaction_nonce| {
|
||||||
relay_sudo_account.clone(),
|
Ok(UnsignedTransaction::new(register_parathread_call.into(), transaction_nonce))
|
||||||
SignParam::<Relaychain> {
|
})
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash: relay_genesis_hash,
|
|
||||||
signer: register_parathread_signer,
|
|
||||||
},
|
|
||||||
move |_, transaction_nonce| {
|
|
||||||
Ok(UnsignedTransaction::new(
|
|
||||||
register_parathread_call.into(),
|
|
||||||
transaction_nonce,
|
|
||||||
))
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await?
|
.await?
|
||||||
.wait()
|
.wait()
|
||||||
.await;
|
.await;
|
||||||
@@ -227,20 +202,10 @@ impl RegisterParachain {
|
|||||||
),
|
),
|
||||||
}
|
}
|
||||||
.into();
|
.into();
|
||||||
let force_lease_signer = relay_sign.clone();
|
|
||||||
relay_client
|
relay_client
|
||||||
.submit_signed_extrinsic(
|
.submit_signed_extrinsic(&relay_sign, move |_, transaction_nonce| {
|
||||||
relay_sudo_account,
|
Ok(UnsignedTransaction::new(force_lease_call.into(), transaction_nonce))
|
||||||
SignParam::<Relaychain> {
|
})
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash: relay_genesis_hash,
|
|
||||||
signer: force_lease_signer,
|
|
||||||
},
|
|
||||||
move |_, transaction_nonce| {
|
|
||||||
Ok(UnsignedTransaction::new(force_lease_call.into(), transaction_nonce))
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
log::info!(target: "bridge", "Registered parachain leases: {:?}. Waiting for onboarding", para_id);
|
log::info!(target: "bridge", "Registered parachain leases: {:?}. Waiting for onboarding", para_id);
|
||||||
|
|
||||||
|
|||||||
@@ -31,8 +31,7 @@ use crate::{
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use codec::{Decode, Encode};
|
use codec::{Decode, Encode};
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
AccountIdOf, AccountKeyPairOf, Chain, ChainBase, ChainWithTransactions, SignParam,
|
AccountIdOf, AccountKeyPairOf, Chain, ChainBase, ChainWithTransactions, UnsignedTransaction,
|
||||||
UnsignedTransaction,
|
|
||||||
};
|
};
|
||||||
use sp_core::Pair;
|
use sp_core::Pair;
|
||||||
use sp_runtime::AccountId32;
|
use sp_runtime::AccountId32;
|
||||||
@@ -80,28 +79,17 @@ where
|
|||||||
data.bridge.bridge_instance_index(),
|
data.bridge.bridge_instance_index(),
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let source_genesis_hash = *source_client.genesis_hash();
|
|
||||||
let (spec_version, transaction_version) = source_client.simple_runtime_version().await?;
|
|
||||||
source_client
|
source_client
|
||||||
.submit_signed_extrinsic(
|
.submit_signed_extrinsic(&source_sign, move |_, transaction_nonce| {
|
||||||
source_sign.public().into(),
|
let unsigned = UnsignedTransaction::new(send_message_call, transaction_nonce);
|
||||||
SignParam::<Self::Source> {
|
log::info!(
|
||||||
spec_version,
|
target: "bridge",
|
||||||
transaction_version,
|
"Sending message to {}. Size: {}",
|
||||||
genesis_hash: source_genesis_hash,
|
Self::Target::NAME,
|
||||||
signer: source_sign.clone(),
|
payload_len,
|
||||||
},
|
);
|
||||||
move |_, transaction_nonce| {
|
Ok(unsigned)
|
||||||
let unsigned = UnsignedTransaction::new(send_message_call, transaction_nonce);
|
})
|
||||||
log::info!(
|
|
||||||
target: "bridge",
|
|
||||||
"Sending message to {}. Size: {}",
|
|
||||||
Self::Target::NAME,
|
|
||||||
payload_len,
|
|
||||||
);
|
|
||||||
Ok(unsigned)
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -20,8 +20,8 @@ use bp_messages::MessageNonce;
|
|||||||
use codec::{Compact, Decode, Encode};
|
use codec::{Compact, Decode, Encode};
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
BalanceOf, Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
|
BalanceOf, Chain, ChainWithBalances, ChainWithGrandpa, ChainWithMessages,
|
||||||
ChainWithTransactions, Error as SubstrateError, IndexOf, SignParam, UnderlyingChainProvider,
|
ChainWithTransactions, ChainWithUtilityPallet, Error as SubstrateError,
|
||||||
UnsignedTransaction,
|
FullRuntimeUtilityPallet, IndexOf, SignParam, UnderlyingChainProvider, UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_core::{storage::StorageKey, Pair};
|
use sp_core::{storage::StorageKey, Pair};
|
||||||
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
use sp_runtime::{generic::SignedPayload, traits::IdentifyAccount};
|
||||||
@@ -149,6 +149,10 @@ impl ChainWithTransactions for Millau {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ChainWithUtilityPallet for Millau {
|
||||||
|
type UtilityPallet = FullRuntimeUtilityPallet<millau_runtime::Runtime>;
|
||||||
|
}
|
||||||
|
|
||||||
/// Millau signing params.
|
/// Millau signing params.
|
||||||
pub type SigningParams = sp_core::sr25519::Pair;
|
pub type SigningParams = sp_core::sr25519::Pair;
|
||||||
|
|
||||||
|
|||||||
@@ -34,6 +34,7 @@ frame-system = { git = "https://github.com/paritytech/substrate", branch = "mast
|
|||||||
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-balances = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-transaction-payment = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
pallet-transaction-payment-rpc-runtime-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
pallet-utility = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-chain-spec = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-rpc-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
sc-transaction-pool-api = { git = "https://github.com/paritytech/substrate", branch = "master" }
|
||||||
|
|||||||
@@ -234,3 +234,31 @@ impl<Block: BlockT> BlockWithJustification<Block::Header> for SignedBlock<Block>
|
|||||||
self.justifications.as_ref().and_then(|j| j.get(engine_id))
|
self.justifications.as_ref().and_then(|j| j.get(engine_id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Trait that provides functionality defined inside `pallet-utility`
|
||||||
|
pub trait UtilityPallet<C: Chain> {
|
||||||
|
/// Create batch call from given calls vector.
|
||||||
|
fn build_batch_call(calls: Vec<C::Call>) -> C::Call;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Structure that implements `UtilityPalletProvider` based on a full runtime.
|
||||||
|
pub struct FullRuntimeUtilityPallet<R> {
|
||||||
|
_phantom: std::marker::PhantomData<R>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<C, R> UtilityPallet<C> for FullRuntimeUtilityPallet<R>
|
||||||
|
where
|
||||||
|
C: Chain,
|
||||||
|
R: pallet_utility::Config<RuntimeCall = C::Call>,
|
||||||
|
<R as pallet_utility::Config>::RuntimeCall: From<pallet_utility::Call<R>>,
|
||||||
|
{
|
||||||
|
fn build_batch_call(calls: Vec<C::Call>) -> C::Call {
|
||||||
|
pallet_utility::Call::batch_all { calls }.into()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Substrate-based chain that uses `pallet-utility`.
|
||||||
|
pub trait ChainWithUtilityPallet: Chain {
|
||||||
|
/// The utility pallet provider.
|
||||||
|
type UtilityPallet: UtilityPallet<Self>;
|
||||||
|
}
|
||||||
|
|||||||
@@ -23,8 +23,8 @@ use crate::{
|
|||||||
SubstrateFrameSystemClient, SubstrateStateClient, SubstrateSystemClient,
|
SubstrateFrameSystemClient, SubstrateStateClient, SubstrateSystemClient,
|
||||||
SubstrateTransactionPaymentClient,
|
SubstrateTransactionPaymentClient,
|
||||||
},
|
},
|
||||||
transaction_stall_timeout, ConnectionParams, Error, HashOf, HeaderIdOf, Result, SignParam,
|
transaction_stall_timeout, AccountKeyPairOf, ConnectionParams, Error, HashOf, HeaderIdOf,
|
||||||
TransactionTracker, UnsignedTransaction,
|
Result, SignParam, TransactionTracker, UnsignedTransaction,
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_std::sync::{Arc, Mutex};
|
use async_std::sync::{Arc, Mutex};
|
||||||
@@ -43,7 +43,7 @@ use pallet_transaction_payment::InclusionFee;
|
|||||||
use relay_utils::{relay_loop::RECONNECT_DELAY, STALL_TIMEOUT};
|
use relay_utils::{relay_loop::RECONNECT_DELAY, STALL_TIMEOUT};
|
||||||
use sp_core::{
|
use sp_core::{
|
||||||
storage::{StorageData, StorageKey},
|
storage::{StorageData, StorageKey},
|
||||||
Bytes, Hasher,
|
Bytes, Hasher, Pair,
|
||||||
};
|
};
|
||||||
use sp_runtime::{
|
use sp_runtime::{
|
||||||
traits::Header as HeaderT,
|
traits::Header as HeaderT,
|
||||||
@@ -426,6 +426,19 @@ impl<C: Chain> Client<C> {
|
|||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn build_sign_params(&self, signer: AccountKeyPairOf<C>) -> Result<SignParam<C>>
|
||||||
|
where
|
||||||
|
C: ChainWithTransactions,
|
||||||
|
{
|
||||||
|
let (spec_version, transaction_version) = self.simple_runtime_version().await?;
|
||||||
|
Ok(SignParam::<C> {
|
||||||
|
spec_version,
|
||||||
|
transaction_version,
|
||||||
|
genesis_hash: self.genesis_hash,
|
||||||
|
signer,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Submit an extrinsic signed by given account.
|
/// Submit an extrinsic signed by given account.
|
||||||
///
|
///
|
||||||
/// All calls of this method are synchronized, so there can't be more than one active
|
/// All calls of this method are synchronized, so there can't be more than one active
|
||||||
@@ -435,18 +448,19 @@ impl<C: Chain> Client<C> {
|
|||||||
/// Note: The given transaction needs to be SCALE encoded beforehand.
|
/// Note: The given transaction needs to be SCALE encoded beforehand.
|
||||||
pub async fn submit_signed_extrinsic(
|
pub async fn submit_signed_extrinsic(
|
||||||
&self,
|
&self,
|
||||||
extrinsic_signer: C::AccountId,
|
signer: &AccountKeyPairOf<C>,
|
||||||
signing_data: SignParam<C>,
|
|
||||||
prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Result<UnsignedTransaction<C>>
|
prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Result<UnsignedTransaction<C>>
|
||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) -> Result<C::Hash>
|
) -> Result<C::Hash>
|
||||||
where
|
where
|
||||||
C: ChainWithTransactions,
|
C: ChainWithTransactions,
|
||||||
|
C::AccountId: From<<C::AccountKeyPair as Pair>::Public>,
|
||||||
{
|
{
|
||||||
let _guard = self.submit_signed_extrinsic_lock.lock().await;
|
let _guard = self.submit_signed_extrinsic_lock.lock().await;
|
||||||
let transaction_nonce = self.next_account_index(extrinsic_signer).await?;
|
let transaction_nonce = self.next_account_index(signer.public().into()).await?;
|
||||||
let best_header = self.best_header().await?;
|
let best_header = self.best_header().await?;
|
||||||
|
let signing_data = self.build_sign_params(signer.clone()).await?;
|
||||||
|
|
||||||
// By using parent of best block here, we are protecing again best-block reorganizations.
|
// By using parent of best block here, we are protecing again best-block reorganizations.
|
||||||
// E.g. transaction may have been submitted when the best block was `A[num=100]`. Then it
|
// E.g. transaction may have been submitted when the best block was `A[num=100]`. Then it
|
||||||
@@ -475,18 +489,19 @@ impl<C: Chain> Client<C> {
|
|||||||
/// after submission.
|
/// after submission.
|
||||||
pub async fn submit_and_watch_signed_extrinsic(
|
pub async fn submit_and_watch_signed_extrinsic(
|
||||||
&self,
|
&self,
|
||||||
extrinsic_signer: C::AccountId,
|
signer: &AccountKeyPairOf<C>,
|
||||||
signing_data: SignParam<C>,
|
|
||||||
prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Result<UnsignedTransaction<C>>
|
prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Result<UnsignedTransaction<C>>
|
||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
) -> Result<TransactionTracker<C, Self>>
|
) -> Result<TransactionTracker<C, Self>>
|
||||||
where
|
where
|
||||||
C: ChainWithTransactions,
|
C: ChainWithTransactions,
|
||||||
|
C::AccountId: From<<C::AccountKeyPair as Pair>::Public>,
|
||||||
{
|
{
|
||||||
let self_clone = self.clone();
|
let self_clone = self.clone();
|
||||||
|
let signing_data = self.build_sign_params(signer.clone()).await?;
|
||||||
let _guard = self.submit_signed_extrinsic_lock.lock().await;
|
let _guard = self.submit_signed_extrinsic_lock.lock().await;
|
||||||
let transaction_nonce = self.next_account_index(extrinsic_signer).await?;
|
let transaction_nonce = self.next_account_index(signer.public().into()).await?;
|
||||||
let best_header = self.best_header().await?;
|
let best_header = self.best_header().await?;
|
||||||
let best_header_id = best_header.id();
|
let best_header_id = best_header.id();
|
||||||
let (sender, receiver) = futures::channel::mpsc::channel(MAX_SUBSCRIPTION_CAPACITY);
|
let (sender, receiver) = futures::channel::mpsc::channel(MAX_SUBSCRIPTION_CAPACITY);
|
||||||
|
|||||||
@@ -34,8 +34,9 @@ use std::time::Duration;
|
|||||||
pub use crate::{
|
pub use crate::{
|
||||||
chain::{
|
chain::{
|
||||||
AccountKeyPairOf, BlockWithJustification, CallOf, Chain, ChainWithBalances,
|
AccountKeyPairOf, BlockWithJustification, CallOf, Chain, ChainWithBalances,
|
||||||
ChainWithGrandpa, ChainWithMessages, ChainWithTransactions, Parachain, RelayChain,
|
ChainWithGrandpa, ChainWithMessages, ChainWithTransactions, ChainWithUtilityPallet,
|
||||||
SignParam, TransactionStatusOf, UnsignedTransaction,
|
FullRuntimeUtilityPallet, Parachain, RelayChain, SignParam, TransactionStatusOf,
|
||||||
|
UnsignedTransaction, UtilityPallet,
|
||||||
},
|
},
|
||||||
client::{
|
client::{
|
||||||
ChainRuntimeVersion, Client, OpaqueGrandpaAuthoritiesSet, Subscription,
|
ChainRuntimeVersion, Client, OpaqueGrandpaAuthoritiesSet, Subscription,
|
||||||
|
|||||||
@@ -22,9 +22,11 @@
|
|||||||
//! with this header.
|
//! with this header.
|
||||||
|
|
||||||
use crate::{error::Error, finality::engine::Engine};
|
use crate::{error::Error, finality::engine::Engine};
|
||||||
|
use sp_core::Pair;
|
||||||
|
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
Chain, ChainWithTransactions, Client, Error as SubstrateError, SignParam, UnsignedTransaction,
|
AccountKeyPairOf, Chain, ChainWithTransactions, Client, Error as SubstrateError,
|
||||||
|
UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use sp_runtime::traits::Header as HeaderT;
|
use sp_runtime::traits::Header as HeaderT;
|
||||||
|
|
||||||
@@ -37,8 +39,7 @@ pub async fn initialize<
|
|||||||
>(
|
>(
|
||||||
source_client: Client<SourceChain>,
|
source_client: Client<SourceChain>,
|
||||||
target_client: Client<TargetChain>,
|
target_client: Client<TargetChain>,
|
||||||
target_transactions_signer: TargetChain::AccountId,
|
target_signer: AccountKeyPairOf<TargetChain>,
|
||||||
target_signing_data: SignParam<TargetChain>,
|
|
||||||
prepare_initialize_transaction: F,
|
prepare_initialize_transaction: F,
|
||||||
dry_run: bool,
|
dry_run: bool,
|
||||||
) where
|
) where
|
||||||
@@ -48,12 +49,12 @@ pub async fn initialize<
|
|||||||
) -> Result<UnsignedTransaction<TargetChain>, SubstrateError>
|
) -> Result<UnsignedTransaction<TargetChain>, SubstrateError>
|
||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
|
TargetChain::AccountId: From<<TargetChain::AccountKeyPair as Pair>::Public>,
|
||||||
{
|
{
|
||||||
let result = do_initialize::<E, _, _, _>(
|
let result = do_initialize::<E, _, _, _>(
|
||||||
source_client,
|
source_client,
|
||||||
target_client,
|
target_client,
|
||||||
target_transactions_signer,
|
target_signer,
|
||||||
target_signing_data,
|
|
||||||
prepare_initialize_transaction,
|
prepare_initialize_transaction,
|
||||||
dry_run,
|
dry_run,
|
||||||
)
|
)
|
||||||
@@ -87,8 +88,7 @@ async fn do_initialize<
|
|||||||
>(
|
>(
|
||||||
source_client: Client<SourceChain>,
|
source_client: Client<SourceChain>,
|
||||||
target_client: Client<TargetChain>,
|
target_client: Client<TargetChain>,
|
||||||
target_transactions_signer: TargetChain::AccountId,
|
target_signer: AccountKeyPairOf<TargetChain>,
|
||||||
target_signing_data: SignParam<TargetChain>,
|
|
||||||
prepare_initialize_transaction: F,
|
prepare_initialize_transaction: F,
|
||||||
dry_run: bool,
|
dry_run: bool,
|
||||||
) -> Result<
|
) -> Result<
|
||||||
@@ -102,6 +102,7 @@ where
|
|||||||
) -> Result<UnsignedTransaction<TargetChain>, SubstrateError>
|
) -> Result<UnsignedTransaction<TargetChain>, SubstrateError>
|
||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
|
TargetChain::AccountId: From<<TargetChain::AccountKeyPair as Pair>::Public>,
|
||||||
{
|
{
|
||||||
let is_initialized = E::is_initialized(&target_client)
|
let is_initialized = E::is_initialized(&target_client)
|
||||||
.await
|
.await
|
||||||
@@ -128,20 +129,16 @@ where
|
|||||||
);
|
);
|
||||||
|
|
||||||
let initialization_tx_hash = target_client
|
let initialization_tx_hash = target_client
|
||||||
.submit_signed_extrinsic(
|
.submit_signed_extrinsic(&target_signer, move |_, transaction_nonce| {
|
||||||
target_transactions_signer,
|
let tx = prepare_initialize_transaction(transaction_nonce, initialization_data);
|
||||||
target_signing_data,
|
if dry_run {
|
||||||
move |_, transaction_nonce| {
|
Err(SubstrateError::Custom(
|
||||||
let tx = prepare_initialize_transaction(transaction_nonce, initialization_data);
|
"Not submitting extrinsic in `dry-run` mode!".to_string(),
|
||||||
if dry_run {
|
))
|
||||||
Err(SubstrateError::Custom(
|
} else {
|
||||||
"Not submitting extrinsic in `dry-run` mode!".to_string(),
|
tx
|
||||||
))
|
}
|
||||||
} else {
|
})
|
||||||
tx
|
|
||||||
}
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|err| Error::SubmitTransaction(TargetChain::NAME, err))?;
|
.map_err(|err| Error::SubmitTransaction(TargetChain::NAME, err))?;
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ use crate::{
|
|||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use finality_relay::TargetClient;
|
use finality_relay::TargetClient;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
AccountIdOf, AccountKeyPairOf, Chain, Client, Error, HeaderIdOf, HeaderOf, SignParam,
|
AccountIdOf, AccountKeyPairOf, Chain, Client, Error, HeaderIdOf, HeaderOf, SyncHeader,
|
||||||
SyncHeader, TransactionEra, TransactionTracker, UnsignedTransaction,
|
TransactionEra, TransactionTracker, UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use relay_utils::relay_loop::Client as RelayClient;
|
use relay_utils::relay_loop::Client as RelayClient;
|
||||||
use sp_core::Pair;
|
use sp_core::Pair;
|
||||||
@@ -111,20 +111,12 @@ where
|
|||||||
header: SyncHeader<HeaderOf<P::SourceChain>>,
|
header: SyncHeader<HeaderOf<P::SourceChain>>,
|
||||||
proof: SubstrateFinalityProof<P>,
|
proof: SubstrateFinalityProof<P>,
|
||||||
) -> Result<Self::TransactionTracker, Error> {
|
) -> Result<Self::TransactionTracker, Error> {
|
||||||
let genesis_hash = *self.client.genesis_hash();
|
|
||||||
let transaction_params = self.transaction_params.clone();
|
let transaction_params = self.transaction_params.clone();
|
||||||
let call =
|
let call =
|
||||||
P::SubmitFinalityProofCallBuilder::build_submit_finality_proof_call(header, proof);
|
P::SubmitFinalityProofCallBuilder::build_submit_finality_proof_call(header, proof);
|
||||||
let (spec_version, transaction_version) = self.client.simple_runtime_version().await?;
|
|
||||||
self.client
|
self.client
|
||||||
.submit_and_watch_signed_extrinsic(
|
.submit_and_watch_signed_extrinsic(
|
||||||
self.transaction_params.signer.public().into(),
|
&self.transaction_params.signer,
|
||||||
SignParam::<P::TargetChain> {
|
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash,
|
|
||||||
signer: transaction_params.signer.clone(),
|
|
||||||
},
|
|
||||||
move |best_block_id, transaction_nonce| {
|
move |best_block_id, transaction_nonce| {
|
||||||
Ok(UnsignedTransaction::new(call.into(), transaction_nonce)
|
Ok(UnsignedTransaction::new(call.into(), transaction_nonce)
|
||||||
.era(TransactionEra::new(best_block_id, transaction_params.mortality)))
|
.era(TransactionEra::new(best_block_id, transaction_params.mortality)))
|
||||||
|
|||||||
@@ -18,7 +18,8 @@
|
|||||||
|
|
||||||
#![warn(missing_docs)]
|
#![warn(missing_docs)]
|
||||||
|
|
||||||
use relay_substrate_client::Error as SubstrateError;
|
use relay_substrate_client::{Chain, ChainWithUtilityPallet, UtilityPallet};
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
pub mod error;
|
pub mod error;
|
||||||
@@ -90,50 +91,41 @@ impl<AccountId> TaggedAccount<AccountId> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Batch call builder.
|
/// Batch call builder.
|
||||||
pub trait BatchCallBuilder<Call> {
|
pub trait BatchCallBuilder<Call>: Send {
|
||||||
/// Associated error type.
|
|
||||||
type Error;
|
|
||||||
/// If `true`, then batch calls are supported at the chain.
|
|
||||||
const BATCH_CALL_SUPPORTED: bool;
|
|
||||||
|
|
||||||
/// Create batch call from given calls vector.
|
/// Create batch call from given calls vector.
|
||||||
fn build_batch_call(_calls: Vec<Call>) -> Result<Call, Self::Error>;
|
fn build_batch_call(&self, _calls: Vec<Call>) -> Call;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Call> BatchCallBuilder<Call> for () {
|
/// Batch call builder constructor.
|
||||||
type Error = SubstrateError;
|
pub trait BatchCallBuilderConstructor<Call> {
|
||||||
const BATCH_CALL_SUPPORTED: bool = false;
|
/// Create a new instance of a batch call builder.
|
||||||
|
fn new_builder() -> Option<Box<dyn BatchCallBuilder<Call>>>;
|
||||||
fn build_batch_call(_calls: Vec<Call>) -> Result<Call, SubstrateError> {
|
|
||||||
debug_assert!(
|
|
||||||
false,
|
|
||||||
"only called if `BATCH_CALL_SUPPORTED` is true;\
|
|
||||||
`BATCH_CALL_SUPPORTED` is false;\
|
|
||||||
qed"
|
|
||||||
);
|
|
||||||
|
|
||||||
Err(SubstrateError::Custom("<() as BatchCallBuilder>::build_batch_call() is called".into()))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Batch call builder for bundled runtimes.
|
/// Batch call builder based on `pallet-utility`.
|
||||||
pub struct BundledBatchCallBuilder<R>(PhantomData<R>);
|
pub struct UtilityPalletBatchCallBuilder<C: Chain>(PhantomData<C>);
|
||||||
|
|
||||||
impl<R> BatchCallBuilder<<R as frame_system::Config>::RuntimeCall> for BundledBatchCallBuilder<R>
|
impl<C: Chain> BatchCallBuilder<C::Call> for UtilityPalletBatchCallBuilder<C>
|
||||||
where
|
where
|
||||||
R: pallet_utility::Config<RuntimeCall = <R as frame_system::Config>::RuntimeCall>,
|
C: ChainWithUtilityPallet,
|
||||||
<R as frame_system::Config>::RuntimeCall: From<pallet_utility::Call<R>>,
|
|
||||||
{
|
{
|
||||||
type Error = SubstrateError;
|
fn build_batch_call(&self, calls: Vec<C::Call>) -> C::Call {
|
||||||
const BATCH_CALL_SUPPORTED: bool = true;
|
C::UtilityPallet::build_batch_call(calls)
|
||||||
|
}
|
||||||
fn build_batch_call(
|
}
|
||||||
mut calls: Vec<<R as frame_system::Config>::RuntimeCall>,
|
|
||||||
) -> Result<<R as frame_system::Config>::RuntimeCall, SubstrateError> {
|
impl<C: Chain> BatchCallBuilderConstructor<C::Call> for UtilityPalletBatchCallBuilder<C>
|
||||||
Ok(if calls.len() == 1 {
|
where
|
||||||
calls.remove(0)
|
C: ChainWithUtilityPallet,
|
||||||
} else {
|
{
|
||||||
pallet_utility::Call::batch_all { calls }.into()
|
fn new_builder() -> Option<Box<dyn BatchCallBuilder<C::Call>>> {
|
||||||
})
|
Some(Box::new(Self(Default::default())))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// A `BatchCallBuilderConstructor` that always returns `None`.
|
||||||
|
impl<Call> BatchCallBuilderConstructor<Call> for () {
|
||||||
|
fn new_builder() -> Option<Box<dyn BatchCallBuilder<Call>>> {
|
||||||
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,18 +20,18 @@ use crate::{
|
|||||||
messages_source::{SubstrateMessagesProof, SubstrateMessagesSource},
|
messages_source::{SubstrateMessagesProof, SubstrateMessagesSource},
|
||||||
messages_target::{SubstrateMessagesDeliveryProof, SubstrateMessagesTarget},
|
messages_target::{SubstrateMessagesDeliveryProof, SubstrateMessagesTarget},
|
||||||
on_demand::OnDemandRelay,
|
on_demand::OnDemandRelay,
|
||||||
BatchCallBuilder, TransactionParams,
|
BatchCallBuilder, BatchCallBuilderConstructor, TransactionParams,
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_std::sync::Arc;
|
use async_std::sync::Arc;
|
||||||
use bp_messages::{LaneId, MessageNonce};
|
use bp_messages::{LaneId, MessageNonce};
|
||||||
use bp_runtime::{AccountIdOf, Chain as _, WeightExtraOps};
|
use bp_runtime::{AccountIdOf, Chain as _, HeaderIdOf, WeightExtraOps};
|
||||||
use bridge_runtime_common::messages::{
|
use bridge_runtime_common::messages::{
|
||||||
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
|
source::FromBridgedChainMessagesDeliveryProof, target::FromBridgedChainMessagesProof,
|
||||||
};
|
};
|
||||||
use codec::Encode;
|
use codec::Encode;
|
||||||
use frame_support::{dispatch::GetDispatchInfo, weights::Weight};
|
use frame_support::{dispatch::GetDispatchInfo, weights::Weight};
|
||||||
use messages_relay::message_lane::MessageLane;
|
use messages_relay::{message_lane::MessageLane, message_lane_loop::BatchTransaction};
|
||||||
use pallet_bridge_messages::{Call as BridgeMessagesCall, Config as BridgeMessagesConfig};
|
use pallet_bridge_messages::{Call as BridgeMessagesCall, Config as BridgeMessagesConfig};
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
transaction_stall_timeout, AccountKeyPairOf, BalanceOf, BlockNumberOf, CallOf, Chain,
|
transaction_stall_timeout, AccountKeyPairOf, BalanceOf, BlockNumberOf, CallOf, Chain,
|
||||||
@@ -57,9 +57,9 @@ pub trait SubstrateMessageLane: 'static + Clone + Debug + Send + Sync {
|
|||||||
type ReceiveMessagesDeliveryProofCallBuilder: ReceiveMessagesDeliveryProofCallBuilder<Self>;
|
type ReceiveMessagesDeliveryProofCallBuilder: ReceiveMessagesDeliveryProofCallBuilder<Self>;
|
||||||
|
|
||||||
/// How batch calls are built at the source chain?
|
/// How batch calls are built at the source chain?
|
||||||
type SourceBatchCallBuilder: BatchCallBuilder<CallOf<Self::SourceChain>, Error = SubstrateError>;
|
type SourceBatchCallBuilder: BatchCallBuilderConstructor<CallOf<Self::SourceChain>>;
|
||||||
/// How batch calls are built at the target chain?
|
/// How batch calls are built at the target chain?
|
||||||
type TargetBatchCallBuilder: BatchCallBuilder<CallOf<Self::TargetChain>, Error = SubstrateError>;
|
type TargetBatchCallBuilder: BatchCallBuilderConstructor<CallOf<Self::TargetChain>>;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adapter that allows all `SubstrateMessageLane` to act as `MessageLane`.
|
/// Adapter that allows all `SubstrateMessageLane` to act as `MessageLane`.
|
||||||
@@ -105,6 +105,53 @@ pub struct MessagesRelayParams<P: SubstrateMessageLane> {
|
|||||||
pub metrics_params: MetricsParams,
|
pub metrics_params: MetricsParams,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Batch transaction that brings headers + and messages delivery/receiving confirmations to the
|
||||||
|
/// source node.
|
||||||
|
pub struct BatchProofTransaction<SC: Chain, TC: Chain, B: BatchCallBuilderConstructor<CallOf<SC>>> {
|
||||||
|
builder: Box<dyn BatchCallBuilder<CallOf<SC>>>,
|
||||||
|
proved_header: HeaderIdOf<TC>,
|
||||||
|
prove_calls: Vec<CallOf<SC>>,
|
||||||
|
|
||||||
|
/// Using `fn() -> B` in order to avoid implementing `Send` for `B`.
|
||||||
|
_phantom: PhantomData<fn() -> B>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SC: Chain, TC: Chain, B: BatchCallBuilderConstructor<CallOf<SC>>>
|
||||||
|
BatchProofTransaction<SC, TC, B>
|
||||||
|
{
|
||||||
|
/// Creates a new instance of `BatchProofTransaction`.
|
||||||
|
pub async fn new(
|
||||||
|
relay: Arc<dyn OnDemandRelay<TC, SC>>,
|
||||||
|
block_num: BlockNumberOf<TC>,
|
||||||
|
) -> Result<Option<Self>, SubstrateError> {
|
||||||
|
if let Some(builder) = B::new_builder() {
|
||||||
|
let (proved_header, prove_calls) = relay.prove_header(block_num).await?;
|
||||||
|
return Ok(Some(Self {
|
||||||
|
builder,
|
||||||
|
proved_header,
|
||||||
|
prove_calls,
|
||||||
|
_phantom: Default::default(),
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(None)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a batch call that includes the provided call.
|
||||||
|
pub fn append_call_and_build(mut self, call: CallOf<SC>) -> CallOf<SC> {
|
||||||
|
self.prove_calls.push(call);
|
||||||
|
self.builder.build_batch_call(self.prove_calls)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<SC: Chain, TC: Chain, B: BatchCallBuilderConstructor<CallOf<SC>>>
|
||||||
|
BatchTransaction<HeaderIdOf<TC>> for BatchProofTransaction<SC, TC, B>
|
||||||
|
{
|
||||||
|
fn required_header_id(&self) -> HeaderIdOf<TC> {
|
||||||
|
self.proved_header
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Run Substrate-to-Substrate messages sync loop.
|
/// Run Substrate-to-Substrate messages sync loop.
|
||||||
pub async fn run<P: SubstrateMessageLane>(params: MessagesRelayParams<P>) -> anyhow::Result<()>
|
pub async fn run<P: SubstrateMessageLane>(params: MessagesRelayParams<P>) -> anyhow::Result<()>
|
||||||
where
|
where
|
||||||
|
|||||||
@@ -20,11 +20,11 @@
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
messages_lane::{
|
messages_lane::{
|
||||||
MessageLaneAdapter, ReceiveMessagesDeliveryProofCallBuilder, SubstrateMessageLane,
|
BatchProofTransaction, MessageLaneAdapter, ReceiveMessagesDeliveryProofCallBuilder,
|
||||||
|
SubstrateMessageLane,
|
||||||
},
|
},
|
||||||
messages_target::SubstrateMessagesDeliveryProof,
|
|
||||||
on_demand::OnDemandRelay,
|
on_demand::OnDemandRelay,
|
||||||
BatchCallBuilder, TransactionParams,
|
TransactionParams,
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_std::sync::Arc;
|
use async_std::sync::Arc;
|
||||||
@@ -41,15 +41,15 @@ use frame_support::weights::Weight;
|
|||||||
use messages_relay::{
|
use messages_relay::{
|
||||||
message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf},
|
message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf},
|
||||||
message_lane_loop::{
|
message_lane_loop::{
|
||||||
BatchTransaction, ClientState, MessageDetails, MessageDetailsMap, MessageProofParameters,
|
ClientState, MessageDetails, MessageDetailsMap, MessageProofParameters, SourceClient,
|
||||||
SourceClient, SourceClientState,
|
SourceClientState,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use num_traits::Zero;
|
use num_traits::Zero;
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
AccountIdOf, AccountKeyPairOf, BalanceOf, BlockNumberOf, CallOf, Chain, ChainWithMessages,
|
AccountIdOf, AccountKeyPairOf, BalanceOf, BlockNumberOf, Chain, ChainWithMessages, Client,
|
||||||
Client, Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam, TransactionEra,
|
Error as SubstrateError, HashOf, HeaderIdOf, TransactionEra, TransactionTracker,
|
||||||
TransactionTracker, UnsignedTransaction,
|
UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use relay_utils::{relay_loop::Client as RelayClient, HeaderId};
|
use relay_utils::{relay_loop::Client as RelayClient, HeaderId};
|
||||||
use sp_core::{Bytes, Pair};
|
use sp_core::{Bytes, Pair};
|
||||||
@@ -140,7 +140,8 @@ impl<P: SubstrateMessageLane> SourceClient<MessageLaneAdapter<P>> for SubstrateM
|
|||||||
where
|
where
|
||||||
AccountIdOf<P::SourceChain>: From<<AccountKeyPairOf<P::SourceChain> as Pair>::Public>,
|
AccountIdOf<P::SourceChain>: From<<AccountKeyPairOf<P::SourceChain> as Pair>::Public>,
|
||||||
{
|
{
|
||||||
type BatchTransaction = BatchConfirmationTransaction<P>;
|
type BatchTransaction =
|
||||||
|
BatchProofTransaction<P::SourceChain, P::TargetChain, P::SourceBatchCallBuilder>;
|
||||||
type TransactionTracker = TransactionTracker<P::SourceChain, Client<P::SourceChain>>;
|
type TransactionTracker = TransactionTracker<P::SourceChain, Client<P::SourceChain>>;
|
||||||
|
|
||||||
async fn state(&self) -> Result<SourceClientState<MessageLaneAdapter<P>>, SubstrateError> {
|
async fn state(&self) -> Result<SourceClientState<MessageLaneAdapter<P>>, SubstrateError> {
|
||||||
@@ -332,30 +333,27 @@ where
|
|||||||
|
|
||||||
async fn submit_messages_receiving_proof(
|
async fn submit_messages_receiving_proof(
|
||||||
&self,
|
&self,
|
||||||
|
maybe_batch_tx: Option<Self::BatchTransaction>,
|
||||||
_generated_at_block: TargetHeaderIdOf<MessageLaneAdapter<P>>,
|
_generated_at_block: TargetHeaderIdOf<MessageLaneAdapter<P>>,
|
||||||
proof: <MessageLaneAdapter<P> as MessageLane>::MessagesReceivingProof,
|
proof: <MessageLaneAdapter<P> as MessageLane>::MessagesReceivingProof,
|
||||||
) -> Result<Self::TransactionTracker, SubstrateError> {
|
) -> Result<Self::TransactionTracker, SubstrateError> {
|
||||||
let genesis_hash = *self.source_client.genesis_hash();
|
let messages_proof_call =
|
||||||
|
P::ReceiveMessagesDeliveryProofCallBuilder::build_receive_messages_delivery_proof_call(
|
||||||
|
proof,
|
||||||
|
maybe_batch_tx.is_none(),
|
||||||
|
);
|
||||||
|
let final_call = match maybe_batch_tx {
|
||||||
|
Some(batch_tx) => batch_tx.append_call_and_build(messages_proof_call),
|
||||||
|
None => messages_proof_call,
|
||||||
|
};
|
||||||
|
|
||||||
let transaction_params = self.transaction_params.clone();
|
let transaction_params = self.transaction_params.clone();
|
||||||
let (spec_version, transaction_version) =
|
|
||||||
self.source_client.simple_runtime_version().await?;
|
|
||||||
self.source_client
|
self.source_client
|
||||||
.submit_and_watch_signed_extrinsic(
|
.submit_and_watch_signed_extrinsic(
|
||||||
self.transaction_params.signer.public().into(),
|
&self.transaction_params.signer,
|
||||||
SignParam::<P::SourceChain> {
|
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash,
|
|
||||||
signer: self.transaction_params.signer.clone(),
|
|
||||||
},
|
|
||||||
move |best_block_id, transaction_nonce| {
|
move |best_block_id, transaction_nonce| {
|
||||||
make_messages_delivery_proof_transaction::<P>(
|
Ok(UnsignedTransaction::new(final_call.into(), transaction_nonce)
|
||||||
&transaction_params,
|
.era(TransactionEra::new(best_block_id, transaction_params.mortality)))
|
||||||
best_block_id,
|
|
||||||
transaction_nonce,
|
|
||||||
proof,
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
@@ -366,14 +364,10 @@ where
|
|||||||
id: TargetHeaderIdOf<MessageLaneAdapter<P>>,
|
id: TargetHeaderIdOf<MessageLaneAdapter<P>>,
|
||||||
) -> Result<Option<Self::BatchTransaction>, SubstrateError> {
|
) -> Result<Option<Self::BatchTransaction>, SubstrateError> {
|
||||||
if let Some(ref target_to_source_headers_relay) = self.target_to_source_headers_relay {
|
if let Some(ref target_to_source_headers_relay) = self.target_to_source_headers_relay {
|
||||||
if P::SourceBatchCallBuilder::BATCH_CALL_SUPPORTED {
|
if let Some(batch_tx) =
|
||||||
let (proved_header, prove_calls) =
|
BatchProofTransaction::new(target_to_source_headers_relay.clone(), id.0).await?
|
||||||
target_to_source_headers_relay.prove_header(id.0).await?;
|
{
|
||||||
return Ok(Some(BatchConfirmationTransaction {
|
return Ok(Some(batch_tx))
|
||||||
messages_source: self.clone(),
|
|
||||||
proved_header,
|
|
||||||
prove_calls,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
target_to_source_headers_relay.require_more_headers(id.0).await;
|
target_to_source_headers_relay.require_more_headers(id.0).await;
|
||||||
@@ -383,65 +377,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Batch transaction that brings target headers + and delivery confirmations to the source node.
|
|
||||||
pub struct BatchConfirmationTransaction<P: SubstrateMessageLane> {
|
|
||||||
messages_source: SubstrateMessagesSource<P>,
|
|
||||||
proved_header: TargetHeaderIdOf<MessageLaneAdapter<P>>,
|
|
||||||
prove_calls: Vec<CallOf<P::SourceChain>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<P: SubstrateMessageLane>
|
|
||||||
BatchTransaction<
|
|
||||||
TargetHeaderIdOf<MessageLaneAdapter<P>>,
|
|
||||||
<MessageLaneAdapter<P> as MessageLane>::MessagesReceivingProof,
|
|
||||||
TransactionTracker<P::SourceChain, Client<P::SourceChain>>,
|
|
||||||
SubstrateError,
|
|
||||||
> for BatchConfirmationTransaction<P>
|
|
||||||
where
|
|
||||||
AccountIdOf<P::SourceChain>: From<<AccountKeyPairOf<P::SourceChain> as Pair>::Public>,
|
|
||||||
{
|
|
||||||
fn required_header_id(&self) -> TargetHeaderIdOf<MessageLaneAdapter<P>> {
|
|
||||||
self.proved_header
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn append_proof_and_send(
|
|
||||||
self,
|
|
||||||
proof: <MessageLaneAdapter<P> as MessageLane>::MessagesReceivingProof,
|
|
||||||
) -> Result<TransactionTracker<P::SourceChain, Client<P::SourceChain>>, SubstrateError> {
|
|
||||||
let mut calls = self.prove_calls;
|
|
||||||
calls.push(
|
|
||||||
P::ReceiveMessagesDeliveryProofCallBuilder::build_receive_messages_delivery_proof_call(
|
|
||||||
proof, false,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
let batch_call = P::SourceBatchCallBuilder::build_batch_call(calls)?;
|
|
||||||
|
|
||||||
let (spec_version, transaction_version) =
|
|
||||||
self.messages_source.source_client.simple_runtime_version().await?;
|
|
||||||
self.messages_source
|
|
||||||
.source_client
|
|
||||||
.submit_and_watch_signed_extrinsic(
|
|
||||||
self.messages_source.transaction_params.signer.public().into(),
|
|
||||||
SignParam::<P::SourceChain> {
|
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash: *self.messages_source.source_client.genesis_hash(),
|
|
||||||
signer: self.messages_source.transaction_params.signer.clone(),
|
|
||||||
},
|
|
||||||
move |best_block_id, transaction_nonce| {
|
|
||||||
Ok(UnsignedTransaction::new(batch_call.into(), transaction_nonce).era(
|
|
||||||
TransactionEra::new(
|
|
||||||
best_block_id,
|
|
||||||
self.messages_source.transaction_params.mortality,
|
|
||||||
),
|
|
||||||
))
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Ensure that the messages pallet at source chain is active.
|
/// Ensure that the messages pallet at source chain is active.
|
||||||
pub(crate) async fn ensure_messages_pallet_active<AtChain, WithChain>(
|
pub(crate) async fn ensure_messages_pallet_active<AtChain, WithChain>(
|
||||||
client: &Client<AtChain>,
|
client: &Client<AtChain>,
|
||||||
@@ -462,22 +397,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make messages delivery proof transaction from given proof.
|
|
||||||
fn make_messages_delivery_proof_transaction<P: SubstrateMessageLane>(
|
|
||||||
source_transaction_params: &TransactionParams<AccountKeyPairOf<P::SourceChain>>,
|
|
||||||
source_best_block_id: HeaderIdOf<P::SourceChain>,
|
|
||||||
transaction_nonce: IndexOf<P::SourceChain>,
|
|
||||||
proof: SubstrateMessagesDeliveryProof<P::TargetChain>,
|
|
||||||
trace_call: bool,
|
|
||||||
) -> Result<UnsignedTransaction<P::SourceChain>, SubstrateError> {
|
|
||||||
let call =
|
|
||||||
P::ReceiveMessagesDeliveryProofCallBuilder::build_receive_messages_delivery_proof_call(
|
|
||||||
proof, trace_call,
|
|
||||||
);
|
|
||||||
Ok(UnsignedTransaction::new(call.into(), transaction_nonce)
|
|
||||||
.era(TransactionEra::new(source_best_block_id, source_transaction_params.mortality)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Read best blocks from given client.
|
/// Read best blocks from given client.
|
||||||
///
|
///
|
||||||
/// This function assumes that the chain that is followed by the `self_client` has
|
/// This function assumes that the chain that is followed by the `self_client` has
|
||||||
|
|||||||
@@ -19,10 +19,13 @@
|
|||||||
//! <BridgedName> chain.
|
//! <BridgedName> chain.
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
messages_lane::{MessageLaneAdapter, ReceiveMessagesProofCallBuilder, SubstrateMessageLane},
|
messages_lane::{
|
||||||
|
BatchProofTransaction, MessageLaneAdapter, ReceiveMessagesProofCallBuilder,
|
||||||
|
SubstrateMessageLane,
|
||||||
|
},
|
||||||
messages_source::{ensure_messages_pallet_active, read_client_state, SubstrateMessagesProof},
|
messages_source::{ensure_messages_pallet_active, read_client_state, SubstrateMessagesProof},
|
||||||
on_demand::OnDemandRelay,
|
on_demand::OnDemandRelay,
|
||||||
BatchCallBuilder, TransactionParams,
|
TransactionParams,
|
||||||
};
|
};
|
||||||
|
|
||||||
use async_std::sync::Arc;
|
use async_std::sync::Arc;
|
||||||
@@ -34,12 +37,11 @@ use bp_messages::{
|
|||||||
use bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof;
|
use bridge_runtime_common::messages::source::FromBridgedChainMessagesDeliveryProof;
|
||||||
use messages_relay::{
|
use messages_relay::{
|
||||||
message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf},
|
message_lane::{MessageLane, SourceHeaderIdOf, TargetHeaderIdOf},
|
||||||
message_lane_loop::{BatchTransaction, NoncesSubmitArtifacts, TargetClient, TargetClientState},
|
message_lane_loop::{NoncesSubmitArtifacts, TargetClient, TargetClientState},
|
||||||
};
|
};
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
AccountIdOf, AccountKeyPairOf, BalanceOf, CallOf, Chain, ChainWithMessages, Client,
|
AccountIdOf, AccountKeyPairOf, BalanceOf, CallOf, Chain, ChainWithMessages, Client,
|
||||||
Error as SubstrateError, HashOf, HeaderIdOf, IndexOf, SignParam, TransactionEra,
|
Error as SubstrateError, HashOf, TransactionEra, TransactionTracker, UnsignedTransaction,
|
||||||
TransactionTracker, UnsignedTransaction,
|
|
||||||
};
|
};
|
||||||
use relay_utils::relay_loop::Client as RelayClient;
|
use relay_utils::relay_loop::Client as RelayClient;
|
||||||
use sp_core::Pair;
|
use sp_core::Pair;
|
||||||
@@ -132,7 +134,8 @@ where
|
|||||||
AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as Pair>::Public>,
|
AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as Pair>::Public>,
|
||||||
BalanceOf<P::SourceChain>: TryFrom<BalanceOf<P::TargetChain>>,
|
BalanceOf<P::SourceChain>: TryFrom<BalanceOf<P::TargetChain>>,
|
||||||
{
|
{
|
||||||
type BatchTransaction = BatchDeliveryTransaction<P>;
|
type BatchTransaction =
|
||||||
|
BatchProofTransaction<P::TargetChain, P::SourceChain, P::TargetBatchCallBuilder>;
|
||||||
type TransactionTracker = TransactionTracker<P::TargetChain, Client<P::TargetChain>>;
|
type TransactionTracker = TransactionTracker<P::TargetChain, Client<P::TargetChain>>;
|
||||||
|
|
||||||
async fn state(&self) -> Result<TargetClientState<MessageLaneAdapter<P>>, SubstrateError> {
|
async fn state(&self) -> Result<TargetClientState<MessageLaneAdapter<P>>, SubstrateError> {
|
||||||
@@ -232,36 +235,30 @@ where
|
|||||||
|
|
||||||
async fn submit_messages_proof(
|
async fn submit_messages_proof(
|
||||||
&self,
|
&self,
|
||||||
|
maybe_batch_tx: Option<Self::BatchTransaction>,
|
||||||
_generated_at_header: SourceHeaderIdOf<MessageLaneAdapter<P>>,
|
_generated_at_header: SourceHeaderIdOf<MessageLaneAdapter<P>>,
|
||||||
nonces: RangeInclusive<MessageNonce>,
|
nonces: RangeInclusive<MessageNonce>,
|
||||||
proof: <MessageLaneAdapter<P> as MessageLane>::MessagesProof,
|
proof: <MessageLaneAdapter<P> as MessageLane>::MessagesProof,
|
||||||
) -> Result<NoncesSubmitArtifacts<Self::TransactionTracker>, SubstrateError> {
|
) -> Result<NoncesSubmitArtifacts<Self::TransactionTracker>, SubstrateError> {
|
||||||
let genesis_hash = *self.target_client.genesis_hash();
|
let messages_proof_call = make_messages_delivery_call::<P>(
|
||||||
|
self.relayer_id_at_source.clone(),
|
||||||
|
proof.1.nonces_start..=proof.1.nonces_end,
|
||||||
|
proof,
|
||||||
|
maybe_batch_tx.is_none(),
|
||||||
|
);
|
||||||
|
let final_call = match maybe_batch_tx {
|
||||||
|
Some(batch_tx) => batch_tx.append_call_and_build(messages_proof_call),
|
||||||
|
None => messages_proof_call,
|
||||||
|
};
|
||||||
|
|
||||||
let transaction_params = self.transaction_params.clone();
|
let transaction_params = self.transaction_params.clone();
|
||||||
let relayer_id_at_source = self.relayer_id_at_source.clone();
|
|
||||||
let nonces_clone = nonces.clone();
|
|
||||||
let (spec_version, transaction_version) =
|
|
||||||
self.target_client.simple_runtime_version().await?;
|
|
||||||
let tx_tracker = self
|
let tx_tracker = self
|
||||||
.target_client
|
.target_client
|
||||||
.submit_and_watch_signed_extrinsic(
|
.submit_and_watch_signed_extrinsic(
|
||||||
self.transaction_params.signer.public().into(),
|
&self.transaction_params.signer,
|
||||||
SignParam::<P::TargetChain> {
|
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash,
|
|
||||||
signer: self.transaction_params.signer.clone(),
|
|
||||||
},
|
|
||||||
move |best_block_id, transaction_nonce| {
|
move |best_block_id, transaction_nonce| {
|
||||||
make_messages_delivery_transaction::<P>(
|
Ok(UnsignedTransaction::new(final_call.into(), transaction_nonce)
|
||||||
&transaction_params,
|
.era(TransactionEra::new(best_block_id, transaction_params.mortality)))
|
||||||
best_block_id,
|
|
||||||
transaction_nonce,
|
|
||||||
relayer_id_at_source,
|
|
||||||
nonces_clone,
|
|
||||||
proof,
|
|
||||||
true,
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
@@ -273,14 +270,10 @@ where
|
|||||||
id: SourceHeaderIdOf<MessageLaneAdapter<P>>,
|
id: SourceHeaderIdOf<MessageLaneAdapter<P>>,
|
||||||
) -> Result<Option<Self::BatchTransaction>, SubstrateError> {
|
) -> Result<Option<Self::BatchTransaction>, SubstrateError> {
|
||||||
if let Some(ref source_to_target_headers_relay) = self.source_to_target_headers_relay {
|
if let Some(ref source_to_target_headers_relay) = self.source_to_target_headers_relay {
|
||||||
if P::TargetBatchCallBuilder::BATCH_CALL_SUPPORTED {
|
if let Some(batch_tx) =
|
||||||
let (proved_header, prove_calls) =
|
BatchProofTransaction::new(source_to_target_headers_relay.clone(), id.0).await?
|
||||||
source_to_target_headers_relay.prove_header(id.0).await?;
|
{
|
||||||
return Ok(Some(BatchDeliveryTransaction {
|
return Ok(Some(batch_tx))
|
||||||
messages_target: self.clone(),
|
|
||||||
proved_header,
|
|
||||||
prove_calls,
|
|
||||||
}))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
source_to_target_headers_relay.require_more_headers(id.0).await;
|
source_to_target_headers_relay.require_more_headers(id.0).await;
|
||||||
@@ -290,66 +283,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Batch transaction that brings target headers + and delivery confirmations to the source node.
|
|
||||||
pub struct BatchDeliveryTransaction<P: SubstrateMessageLane> {
|
|
||||||
messages_target: SubstrateMessagesTarget<P>,
|
|
||||||
proved_header: SourceHeaderIdOf<MessageLaneAdapter<P>>,
|
|
||||||
prove_calls: Vec<CallOf<P::TargetChain>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
impl<P: SubstrateMessageLane>
|
|
||||||
BatchTransaction<
|
|
||||||
SourceHeaderIdOf<MessageLaneAdapter<P>>,
|
|
||||||
<MessageLaneAdapter<P> as MessageLane>::MessagesProof,
|
|
||||||
TransactionTracker<P::TargetChain, Client<P::TargetChain>>,
|
|
||||||
SubstrateError,
|
|
||||||
> for BatchDeliveryTransaction<P>
|
|
||||||
where
|
|
||||||
AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as Pair>::Public>,
|
|
||||||
{
|
|
||||||
fn required_header_id(&self) -> SourceHeaderIdOf<MessageLaneAdapter<P>> {
|
|
||||||
self.proved_header
|
|
||||||
}
|
|
||||||
|
|
||||||
async fn append_proof_and_send(
|
|
||||||
self,
|
|
||||||
proof: <MessageLaneAdapter<P> as MessageLane>::MessagesProof,
|
|
||||||
) -> Result<TransactionTracker<P::TargetChain, Client<P::TargetChain>>, SubstrateError> {
|
|
||||||
let mut calls = self.prove_calls;
|
|
||||||
calls.push(make_messages_delivery_call::<P>(
|
|
||||||
self.messages_target.relayer_id_at_source,
|
|
||||||
proof.1.nonces_start..=proof.1.nonces_end,
|
|
||||||
proof,
|
|
||||||
false,
|
|
||||||
));
|
|
||||||
let batch_call = P::TargetBatchCallBuilder::build_batch_call(calls)?;
|
|
||||||
|
|
||||||
let (spec_version, transaction_version) =
|
|
||||||
self.messages_target.target_client.simple_runtime_version().await?;
|
|
||||||
self.messages_target
|
|
||||||
.target_client
|
|
||||||
.submit_and_watch_signed_extrinsic(
|
|
||||||
self.messages_target.transaction_params.signer.public().into(),
|
|
||||||
SignParam::<P::TargetChain> {
|
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash: *self.messages_target.target_client.genesis_hash(),
|
|
||||||
signer: self.messages_target.transaction_params.signer.clone(),
|
|
||||||
},
|
|
||||||
move |best_block_id, transaction_nonce| {
|
|
||||||
Ok(UnsignedTransaction::new(batch_call.into(), transaction_nonce).era(
|
|
||||||
TransactionEra::new(
|
|
||||||
best_block_id,
|
|
||||||
self.messages_target.transaction_params.mortality,
|
|
||||||
),
|
|
||||||
))
|
|
||||||
},
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Make messages delivery call from given proof.
|
/// Make messages delivery call from given proof.
|
||||||
fn make_messages_delivery_call<P: SubstrateMessageLane>(
|
fn make_messages_delivery_call<P: SubstrateMessageLane>(
|
||||||
relayer_id_at_source: AccountIdOf<P::SourceChain>,
|
relayer_id_at_source: AccountIdOf<P::SourceChain>,
|
||||||
@@ -367,18 +300,3 @@ fn make_messages_delivery_call<P: SubstrateMessageLane>(
|
|||||||
trace_call,
|
trace_call,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Make messages delivery transaction from given proof.
|
|
||||||
fn make_messages_delivery_transaction<P: SubstrateMessageLane>(
|
|
||||||
target_transaction_params: &TransactionParams<AccountKeyPairOf<P::TargetChain>>,
|
|
||||||
target_best_block_id: HeaderIdOf<P::TargetChain>,
|
|
||||||
transaction_nonce: IndexOf<P::TargetChain>,
|
|
||||||
relayer_id_at_source: AccountIdOf<P::SourceChain>,
|
|
||||||
nonces: RangeInclusive<MessageNonce>,
|
|
||||||
proof: SubstrateMessagesProof<P::SourceChain>,
|
|
||||||
trace_call: bool,
|
|
||||||
) -> Result<UnsignedTransaction<P::TargetChain>, SubstrateError> {
|
|
||||||
let call = make_messages_delivery_call::<P>(relayer_id_at_source, nonces, proof, trace_call);
|
|
||||||
Ok(UnsignedTransaction::new(call.into(), transaction_nonce)
|
|
||||||
.era(TransactionEra::new(target_best_block_id, target_transaction_params.mortality)))
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ use parachains_relay::{
|
|||||||
};
|
};
|
||||||
use relay_substrate_client::{
|
use relay_substrate_client::{
|
||||||
AccountIdOf, AccountKeyPairOf, BlockNumberOf, Chain, Client, Error as SubstrateError, HashOf,
|
AccountIdOf, AccountKeyPairOf, BlockNumberOf, Chain, Client, Error as SubstrateError, HashOf,
|
||||||
HeaderIdOf, RelayChain, SignParam, TransactionEra, TransactionTracker, UnsignedTransaction,
|
HeaderIdOf, RelayChain, TransactionEra, TransactionTracker, UnsignedTransaction,
|
||||||
};
|
};
|
||||||
use relay_utils::{relay_loop::Client as RelayClient, HeaderId};
|
use relay_utils::{relay_loop::Client as RelayClient, HeaderId};
|
||||||
use sp_core::{Bytes, Pair};
|
use sp_core::{Bytes, Pair};
|
||||||
@@ -172,9 +172,7 @@ where
|
|||||||
updated_parachains: Vec<(ParaId, ParaHash)>,
|
updated_parachains: Vec<(ParaId, ParaHash)>,
|
||||||
proof: ParaHeadsProof,
|
proof: ParaHeadsProof,
|
||||||
) -> Result<Self::TransactionTracker, Self::Error> {
|
) -> Result<Self::TransactionTracker, Self::Error> {
|
||||||
let genesis_hash = *self.client.genesis_hash();
|
|
||||||
let transaction_params = self.transaction_params.clone();
|
let transaction_params = self.transaction_params.clone();
|
||||||
let (spec_version, transaction_version) = self.client.simple_runtime_version().await?;
|
|
||||||
let call = P::SubmitParachainHeadsCallBuilder::build_submit_parachain_heads_call(
|
let call = P::SubmitParachainHeadsCallBuilder::build_submit_parachain_heads_call(
|
||||||
at_relay_block,
|
at_relay_block,
|
||||||
updated_parachains,
|
updated_parachains,
|
||||||
@@ -182,13 +180,7 @@ where
|
|||||||
);
|
);
|
||||||
self.client
|
self.client
|
||||||
.submit_and_watch_signed_extrinsic(
|
.submit_and_watch_signed_extrinsic(
|
||||||
self.transaction_params.signer.public().into(),
|
&transaction_params.signer,
|
||||||
SignParam::<P::TargetChain> {
|
|
||||||
spec_version,
|
|
||||||
transaction_version,
|
|
||||||
genesis_hash,
|
|
||||||
signer: transaction_params.signer,
|
|
||||||
},
|
|
||||||
move |best_block_id, transaction_nonce| {
|
move |best_block_id, transaction_nonce| {
|
||||||
Ok(UnsignedTransaction::new(call.into(), transaction_nonce)
|
Ok(UnsignedTransaction::new(call.into(), transaction_nonce)
|
||||||
.era(TransactionEra::new(best_block_id, transaction_params.mortality)))
|
.era(TransactionEra::new(best_block_id, transaction_params.mortality)))
|
||||||
|
|||||||
@@ -111,26 +111,17 @@ pub struct NoncesSubmitArtifacts<T> {
|
|||||||
|
|
||||||
/// Batch transaction that already submit some headers and needs to be extended with
|
/// Batch transaction that already submit some headers and needs to be extended with
|
||||||
/// messages/delivery proof before sending.
|
/// messages/delivery proof before sending.
|
||||||
#[async_trait]
|
pub trait BatchTransaction<HeaderId>: Send {
|
||||||
pub trait BatchTransaction<HeaderId, Proof, TransactionTracker, Error>: Send {
|
|
||||||
/// Header that was required in the original call and which is bundled within this
|
/// Header that was required in the original call and which is bundled within this
|
||||||
/// batch transaction.
|
/// batch transaction.
|
||||||
fn required_header_id(&self) -> HeaderId;
|
fn required_header_id(&self) -> HeaderId;
|
||||||
|
|
||||||
/// Append proof and send transaction to the connected node.
|
|
||||||
async fn append_proof_and_send(self, proof: Proof) -> Result<TransactionTracker, Error>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Source client trait.
|
/// Source client trait.
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait SourceClient<P: MessageLane>: RelayClient {
|
pub trait SourceClient<P: MessageLane>: RelayClient {
|
||||||
/// Type of batch transaction that submits finality and message receiving proof.
|
/// Type of batch transaction that submits finality and message receiving proof.
|
||||||
type BatchTransaction: BatchTransaction<
|
type BatchTransaction: BatchTransaction<TargetHeaderIdOf<P>>;
|
||||||
TargetHeaderIdOf<P>,
|
|
||||||
P::MessagesReceivingProof,
|
|
||||||
Self::TransactionTracker,
|
|
||||||
Self::Error,
|
|
||||||
>;
|
|
||||||
/// Transaction tracker to track submitted transactions.
|
/// Transaction tracker to track submitted transactions.
|
||||||
type TransactionTracker: TransactionTracker<HeaderId = SourceHeaderIdOf<P>>;
|
type TransactionTracker: TransactionTracker<HeaderId = SourceHeaderIdOf<P>>;
|
||||||
|
|
||||||
@@ -170,6 +161,7 @@ pub trait SourceClient<P: MessageLane>: RelayClient {
|
|||||||
/// Submit messages receiving proof.
|
/// Submit messages receiving proof.
|
||||||
async fn submit_messages_receiving_proof(
|
async fn submit_messages_receiving_proof(
|
||||||
&self,
|
&self,
|
||||||
|
maybe_batch_tx: Option<Self::BatchTransaction>,
|
||||||
generated_at_block: TargetHeaderIdOf<P>,
|
generated_at_block: TargetHeaderIdOf<P>,
|
||||||
proof: P::MessagesReceivingProof,
|
proof: P::MessagesReceivingProof,
|
||||||
) -> Result<Self::TransactionTracker, Self::Error>;
|
) -> Result<Self::TransactionTracker, Self::Error>;
|
||||||
@@ -194,12 +186,7 @@ pub trait SourceClient<P: MessageLane>: RelayClient {
|
|||||||
#[async_trait]
|
#[async_trait]
|
||||||
pub trait TargetClient<P: MessageLane>: RelayClient {
|
pub trait TargetClient<P: MessageLane>: RelayClient {
|
||||||
/// Type of batch transaction that submits finality and messages proof.
|
/// Type of batch transaction that submits finality and messages proof.
|
||||||
type BatchTransaction: BatchTransaction<
|
type BatchTransaction: BatchTransaction<SourceHeaderIdOf<P>>;
|
||||||
SourceHeaderIdOf<P>,
|
|
||||||
P::MessagesProof,
|
|
||||||
Self::TransactionTracker,
|
|
||||||
Self::Error,
|
|
||||||
>;
|
|
||||||
/// Transaction tracker to track submitted transactions.
|
/// Transaction tracker to track submitted transactions.
|
||||||
type TransactionTracker: TransactionTracker<HeaderId = TargetHeaderIdOf<P>>;
|
type TransactionTracker: TransactionTracker<HeaderId = TargetHeaderIdOf<P>>;
|
||||||
|
|
||||||
@@ -233,6 +220,7 @@ pub trait TargetClient<P: MessageLane>: RelayClient {
|
|||||||
/// Submit messages proof.
|
/// Submit messages proof.
|
||||||
async fn submit_messages_proof(
|
async fn submit_messages_proof(
|
||||||
&self,
|
&self,
|
||||||
|
maybe_batch_tx: Option<Self::BatchTransaction>,
|
||||||
generated_at_header: SourceHeaderIdOf<P>,
|
generated_at_header: SourceHeaderIdOf<P>,
|
||||||
nonces: RangeInclusive<MessageNonce>,
|
nonces: RangeInclusive<MessageNonce>,
|
||||||
proof: P::MessagesProof,
|
proof: P::MessagesProof,
|
||||||
@@ -533,57 +521,26 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TestMessagesBatchTransaction {
|
pub struct TestMessagesBatchTransaction {
|
||||||
data: Arc<Mutex<TestClientData>>,
|
|
||||||
required_header_id: TestSourceHeaderId,
|
required_header_id: TestSourceHeaderId,
|
||||||
tx_tracker: TestTransactionTracker,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl BatchTransaction<TestSourceHeaderId, TestMessagesProof, TestTransactionTracker, TestError>
|
impl BatchTransaction<TestSourceHeaderId> for TestMessagesBatchTransaction {
|
||||||
for TestMessagesBatchTransaction
|
|
||||||
{
|
|
||||||
fn required_header_id(&self) -> TestSourceHeaderId {
|
fn required_header_id(&self) -> TestSourceHeaderId {
|
||||||
self.required_header_id
|
self.required_header_id
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn append_proof_and_send(
|
|
||||||
self,
|
|
||||||
proof: TestMessagesProof,
|
|
||||||
) -> Result<TestTransactionTracker, TestError> {
|
|
||||||
let mut data = self.data.lock();
|
|
||||||
data.receive_messages(proof);
|
|
||||||
Ok(self.tx_tracker)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TestConfirmationBatchTransaction {
|
pub struct TestConfirmationBatchTransaction {
|
||||||
data: Arc<Mutex<TestClientData>>,
|
|
||||||
required_header_id: TestTargetHeaderId,
|
required_header_id: TestTargetHeaderId,
|
||||||
tx_tracker: TestTransactionTracker,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
#[async_trait]
|
||||||
impl
|
impl BatchTransaction<TestTargetHeaderId> for TestConfirmationBatchTransaction {
|
||||||
BatchTransaction<
|
|
||||||
TestTargetHeaderId,
|
|
||||||
TestMessagesReceivingProof,
|
|
||||||
TestTransactionTracker,
|
|
||||||
TestError,
|
|
||||||
> for TestConfirmationBatchTransaction
|
|
||||||
{
|
|
||||||
fn required_header_id(&self) -> TestTargetHeaderId {
|
fn required_header_id(&self) -> TestTargetHeaderId {
|
||||||
self.required_header_id
|
self.required_header_id
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn append_proof_and_send(
|
|
||||||
self,
|
|
||||||
proof: TestMessagesReceivingProof,
|
|
||||||
) -> Result<TestTransactionTracker, TestError> {
|
|
||||||
let mut data = self.data.lock();
|
|
||||||
data.receive_messages_delivery_proof(proof);
|
|
||||||
Ok(self.tx_tracker)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
@@ -800,6 +757,7 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
async fn submit_messages_receiving_proof(
|
async fn submit_messages_receiving_proof(
|
||||||
&self,
|
&self,
|
||||||
|
_maybe_batch_tx: Option<Self::BatchTransaction>,
|
||||||
_generated_at_block: TargetHeaderIdOf<TestMessageLane>,
|
_generated_at_block: TargetHeaderIdOf<TestMessageLane>,
|
||||||
proof: TestMessagesReceivingProof,
|
proof: TestMessagesReceivingProof,
|
||||||
) -> Result<Self::TransactionTracker, TestError> {
|
) -> Result<Self::TransactionTracker, TestError> {
|
||||||
@@ -924,6 +882,7 @@ pub(crate) mod tests {
|
|||||||
|
|
||||||
async fn submit_messages_proof(
|
async fn submit_messages_proof(
|
||||||
&self,
|
&self,
|
||||||
|
_maybe_batch_tx: Option<Self::BatchTransaction>,
|
||||||
_generated_at_header: SourceHeaderIdOf<TestMessageLane>,
|
_generated_at_header: SourceHeaderIdOf<TestMessageLane>,
|
||||||
nonces: RangeInclusive<MessageNonce>,
|
nonces: RangeInclusive<MessageNonce>,
|
||||||
proof: TestMessagesProof,
|
proof: TestMessagesProof,
|
||||||
@@ -1287,8 +1246,6 @@ pub(crate) mod tests {
|
|||||||
target_latest_received_nonce: 0,
|
target_latest_received_nonce: 0,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}));
|
}));
|
||||||
let target_original_data = original_data.clone();
|
|
||||||
let source_original_data = original_data.clone();
|
|
||||||
let result = run_loop_test(
|
let result = run_loop_test(
|
||||||
original_data,
|
original_data,
|
||||||
Arc::new(|_| {}),
|
Arc::new(|_| {}),
|
||||||
@@ -1298,9 +1255,7 @@ pub(crate) mod tests {
|
|||||||
{
|
{
|
||||||
data.target_to_source_batch_transaction =
|
data.target_to_source_batch_transaction =
|
||||||
Some(TestConfirmationBatchTransaction {
|
Some(TestConfirmationBatchTransaction {
|
||||||
data: source_original_data.clone(),
|
|
||||||
required_header_id: target_to_source_header_required,
|
required_header_id: target_to_source_header_required,
|
||||||
tx_tracker: TestTransactionTracker::default(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@@ -1310,9 +1265,7 @@ pub(crate) mod tests {
|
|||||||
data.source_to_target_header_required.take()
|
data.source_to_target_header_required.take()
|
||||||
{
|
{
|
||||||
data.source_to_target_batch_transaction = Some(TestMessagesBatchTransaction {
|
data.source_to_target_batch_transaction = Some(TestMessagesBatchTransaction {
|
||||||
data: target_original_data.clone(),
|
|
||||||
required_header_id: source_to_target_header_required,
|
required_header_id: source_to_target_header_required,
|
||||||
tx_tracker: TestTransactionTracker::default(),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -214,11 +214,14 @@ where
|
|||||||
|
|
||||||
async fn submit_proof(
|
async fn submit_proof(
|
||||||
&self,
|
&self,
|
||||||
|
maybe_batch_tx: Option<Self::BatchTransaction>,
|
||||||
generated_at_block: SourceHeaderIdOf<P>,
|
generated_at_block: SourceHeaderIdOf<P>,
|
||||||
nonces: RangeInclusive<MessageNonce>,
|
nonces: RangeInclusive<MessageNonce>,
|
||||||
proof: P::MessagesProof,
|
proof: P::MessagesProof,
|
||||||
) -> Result<NoncesSubmitArtifacts<Self::TransactionTracker>, Self::Error> {
|
) -> Result<NoncesSubmitArtifacts<Self::TransactionTracker>, Self::Error> {
|
||||||
self.client.submit_messages_proof(generated_at_block, nonces, proof).await
|
self.client
|
||||||
|
.submit_messages_proof(maybe_batch_tx, generated_at_block, nonces, proof)
|
||||||
|
.await
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -128,12 +128,7 @@ pub trait TargetClient<P: MessageRace> {
|
|||||||
/// Type of the additional data from the target client, used by the race.
|
/// Type of the additional data from the target client, used by the race.
|
||||||
type TargetNoncesData: std::fmt::Debug;
|
type TargetNoncesData: std::fmt::Debug;
|
||||||
/// Type of batch transaction that submits finality and proof to the target node.
|
/// Type of batch transaction that submits finality and proof to the target node.
|
||||||
type BatchTransaction: BatchTransaction<
|
type BatchTransaction: BatchTransaction<P::SourceHeaderId>;
|
||||||
P::SourceHeaderId,
|
|
||||||
P::Proof,
|
|
||||||
Self::TransactionTracker,
|
|
||||||
Self::Error,
|
|
||||||
>;
|
|
||||||
/// Transaction tracker to track submitted transactions.
|
/// Transaction tracker to track submitted transactions.
|
||||||
type TransactionTracker: TransactionTracker<HeaderId = P::TargetHeaderId>;
|
type TransactionTracker: TransactionTracker<HeaderId = P::TargetHeaderId>;
|
||||||
|
|
||||||
@@ -160,6 +155,7 @@ pub trait TargetClient<P: MessageRace> {
|
|||||||
/// Submit proof to the target client.
|
/// Submit proof to the target client.
|
||||||
async fn submit_proof(
|
async fn submit_proof(
|
||||||
&self,
|
&self,
|
||||||
|
maybe_batch_tx: Option<Self::BatchTransaction>,
|
||||||
generated_at_block: P::SourceHeaderId,
|
generated_at_block: P::SourceHeaderId,
|
||||||
nonces: RangeInclusive<MessageNonce>,
|
nonces: RangeInclusive<MessageNonce>,
|
||||||
proof: P::Proof,
|
proof: P::Proof,
|
||||||
@@ -575,41 +571,30 @@ pub async fn run<P: MessageRace, SC: SourceClient<P>, TC: TargetClient<P>>(
|
|||||||
target_client_is_online = false;
|
target_client_is_online = false;
|
||||||
|
|
||||||
if let Some((at_block, nonces_range, proof)) = race_state.nonces_to_submit.as_ref() {
|
if let Some((at_block, nonces_range, proof)) = race_state.nonces_to_submit.as_ref() {
|
||||||
if let Some(target_batch_transaction) = target_batch_transaction.take() {
|
log::debug!(
|
||||||
|
target: "bridge",
|
||||||
|
"Going to submit proof of messages in range {:?} to {} node",
|
||||||
|
nonces_range,
|
||||||
|
P::target_name(),
|
||||||
|
);
|
||||||
|
if let Some(ref target_batch_transaction) = target_batch_transaction {
|
||||||
log::debug!(
|
log::debug!(
|
||||||
target: "bridge",
|
target: "bridge",
|
||||||
"Going to submit batch transaction with header {:?} and proof of messages in range {:?} to {} node",
|
"This transaction is batched with sending the proof for header {:?}.",
|
||||||
target_batch_transaction.required_header_id(),
|
target_batch_transaction.required_header_id(),
|
||||||
nonces_range,
|
|
||||||
P::target_name(),
|
|
||||||
);
|
|
||||||
|
|
||||||
let nonces = nonces_range.clone();
|
|
||||||
target_submit_proof.set(
|
|
||||||
target_batch_transaction
|
|
||||||
.append_proof_and_send(proof.clone())
|
|
||||||
.map(|result| {
|
|
||||||
result
|
|
||||||
.map(|tx_tracker| NoncesSubmitArtifacts { nonces, tx_tracker })
|
|
||||||
})
|
|
||||||
.left_future()
|
|
||||||
.fuse(),
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
log::debug!(
|
|
||||||
target: "bridge",
|
|
||||||
"Going to submit proof of messages in range {:?} to {} node",
|
|
||||||
nonces_range,
|
|
||||||
P::target_name(),
|
|
||||||
);
|
|
||||||
|
|
||||||
target_submit_proof.set(
|
|
||||||
race_target
|
|
||||||
.submit_proof(at_block.clone(), nonces_range.clone(), proof.clone())
|
|
||||||
.right_future()
|
|
||||||
.fuse(),
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
target_submit_proof.set(
|
||||||
|
race_target
|
||||||
|
.submit_proof(
|
||||||
|
target_batch_transaction.take(),
|
||||||
|
at_block.clone(),
|
||||||
|
nonces_range.clone(),
|
||||||
|
proof.clone(),
|
||||||
|
)
|
||||||
|
.fuse(),
|
||||||
|
);
|
||||||
} else if let Some(source_required_header) = source_required_header.clone() {
|
} else if let Some(source_required_header) = source_required_header.clone() {
|
||||||
log::debug!(target: "bridge", "Going to require {} header {:?} at {}", P::source_name(), source_required_header, P::target_name());
|
log::debug!(target: "bridge", "Going to require {} header {:?} at {}", P::source_name(), source_required_header, P::target_name());
|
||||||
target_require_source_header
|
target_require_source_header
|
||||||
|
|||||||
@@ -182,12 +182,15 @@ where
|
|||||||
|
|
||||||
async fn submit_proof(
|
async fn submit_proof(
|
||||||
&self,
|
&self,
|
||||||
|
maybe_batch_tx: Option<Self::BatchTransaction>,
|
||||||
generated_at_block: TargetHeaderIdOf<P>,
|
generated_at_block: TargetHeaderIdOf<P>,
|
||||||
nonces: RangeInclusive<MessageNonce>,
|
nonces: RangeInclusive<MessageNonce>,
|
||||||
proof: P::MessagesReceivingProof,
|
proof: P::MessagesReceivingProof,
|
||||||
) -> Result<NoncesSubmitArtifacts<Self::TransactionTracker>, Self::Error> {
|
) -> Result<NoncesSubmitArtifacts<Self::TransactionTracker>, Self::Error> {
|
||||||
let tx_tracker =
|
let tx_tracker = self
|
||||||
self.client.submit_messages_receiving_proof(generated_at_block, proof).await?;
|
.client
|
||||||
|
.submit_messages_receiving_proof(maybe_batch_tx, generated_at_block, proof)
|
||||||
|
.await?;
|
||||||
Ok(NoncesSubmitArtifacts { nonces, tx_tracker })
|
Ok(NoncesSubmitArtifacts { nonces, tx_tracker })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user