Emit mortal transactions from relay (#1073)

* mortal relay transactions

* sign block hash for mortal transactions

* TransactionEraOf

* add explanation

* enable mortal transactions for Westend -> Millau headers relay

* clippy

* spellcheck
This commit is contained in:
Svyatoslav Nikolsky
2021-09-02 10:55:57 +03:00
committed by Bastian Köcher
parent 8b52cd2593
commit 864c830618
33 changed files with 249 additions and 73 deletions
+9 -9
View File
@@ -235,26 +235,26 @@ impl<Call> parity_scale_codec::Decode for SignedExtensions<Call> {
impl<Call> SignedExtensions<Call> { impl<Call> SignedExtensions<Call> {
pub fn new( pub fn new(
version: sp_version::RuntimeVersion, version: sp_version::RuntimeVersion,
era: sp_runtime::generic::Era, era: bp_runtime::TransactionEraOf<PolkadotLike>,
genesis_hash: Hash, genesis_hash: Hash,
nonce: Nonce, nonce: Nonce,
tip: Balance, tip: Balance,
) -> Self { ) -> Self {
Self { Self {
encode_payload: ( encode_payload: (
(), // spec version (), // spec version
(), // tx version (), // tx version
(), // genesis (), // genesis
era, // era era.frame_era(), // era
nonce.into(), // nonce (compact encoding) nonce.into(), // nonce (compact encoding)
(), // Check weight (), // Check weight
tip.into(), // transaction payment / tip (compact encoding) tip.into(), // transaction payment / tip (compact encoding)
), ),
additional_signed: ( additional_signed: (
version.spec_version, version.spec_version,
version.transaction_version, version.transaction_version,
genesis_hash, genesis_hash,
genesis_hash, era.signed_payload(genesis_hash),
(), (),
(), (),
(), (),
+7 -1
View File
@@ -42,7 +42,10 @@ pub trait Chain: Send + Sync + 'static {
+ FromStr + FromStr
+ MaybeMallocSizeOf + MaybeMallocSizeOf
+ AsPrimitive<usize> + AsPrimitive<usize>
+ Default; + Default
// original `sp_runtime::traits::Header::BlockNumber` doesn't have this trait, but
// `sp_runtime::generic::Era` requires block number -> `u64` conversion.
+ Into<u64>;
/// A type that fulfills the abstract idea of what a Substrate hash is. /// A type that fulfills the abstract idea of what a Substrate hash is.
// Constraits come from the associated Hash type of `sp_runtime::traits::Header` // Constraits come from the associated Hash type of `sp_runtime::traits::Header`
@@ -85,3 +88,6 @@ pub type HasherOf<C> = <C as Chain>::Hasher;
/// Header type used by the chain. /// Header type used by the chain.
pub type HeaderOf<C> = <C as Chain>::Header; pub type HeaderOf<C> = <C as Chain>::Header;
/// Transaction era used by the chain.
pub type TransactionEraOf<C> = crate::TransactionEra<BlockNumberOf<C>, HashOf<C>>;
+43 -1
View File
@@ -19,11 +19,12 @@
#![cfg_attr(not(feature = "std"), no_std)] #![cfg_attr(not(feature = "std"), no_std)]
use codec::Encode; use codec::Encode;
use frame_support::RuntimeDebug;
use sp_core::hash::H256; use sp_core::hash::H256;
use sp_io::hashing::blake2_256; use sp_io::hashing::blake2_256;
use sp_std::convert::TryFrom; use sp_std::convert::TryFrom;
pub use chain::{BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf}; pub use chain::{BlockNumberOf, Chain, HashOf, HasherOf, HeaderOf, TransactionEraOf};
pub use storage_proof::{Error as StorageProofError, StorageProofChecker}; pub use storage_proof::{Error as StorageProofError, StorageProofChecker};
#[cfg(feature = "std")] #[cfg(feature = "std")]
@@ -138,3 +139,44 @@ impl Size for PreComputedSize {
u32::try_from(self.0).unwrap_or(u32::MAX) u32::try_from(self.0).unwrap_or(u32::MAX)
} }
} }
/// Era of specific transaction.
#[derive(RuntimeDebug, Clone, Copy)]
pub enum TransactionEra<BlockNumber, BlockHash> {
/// Transaction is immortal.
Immortal,
/// Transaction is valid for given number of blocks, starting from given block.
Mortal(BlockNumber, BlockHash, u32),
}
impl<BlockNumber: Copy + Into<u64>, BlockHash: Copy> TransactionEra<BlockNumber, BlockHash> {
/// Prepare transaction era, based on mortality period and current best block number.
pub fn new(best_block_number: BlockNumber, best_block_hash: BlockHash, mortality_period: Option<u32>) -> Self {
mortality_period
.map(|mortality_period| TransactionEra::Mortal(best_block_number, best_block_hash, mortality_period))
.unwrap_or(TransactionEra::Immortal)
}
/// Create new immortal transaction era.
pub fn immortal() -> Self {
TransactionEra::Immortal
}
/// Returns era that is used by FRAME-based runtimes.
pub fn frame_era(&self) -> sp_runtime::generic::Era {
match *self {
TransactionEra::Immortal => sp_runtime::generic::Era::immortal(),
TransactionEra::Mortal(header_number, _, period) => {
sp_runtime::generic::Era::mortal(period as _, header_number.into())
}
}
}
/// Returns header hash that needs to be included in the signature payload.
pub fn signed_payload(&self, genesis_hash: BlockHash) -> BlockHash {
match *self {
TransactionEra::Immortal => genesis_hash,
TransactionEra::Mortal(_, header_hash, _) => header_hash,
}
}
}
@@ -157,11 +157,12 @@ impl SubmitEthereumHeaders for SubstrateClient<Rialto> {
let ids = headers.iter().map(|header| header.id()).collect(); let ids = headers.iter().map(|header| header.id()).collect();
let genesis_hash = *self.genesis_hash(); let genesis_hash = *self.genesis_hash();
let submission_result = async { let submission_result = async {
self.submit_signed_extrinsic((*params.public().as_array_ref()).into(), move |transaction_nonce| { self.submit_signed_extrinsic((*params.public().as_array_ref()).into(), move |_, transaction_nonce| {
Bytes( Bytes(
Rialto::sign_transaction( Rialto::sign_transaction(
genesis_hash, genesis_hash,
&params, &params,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce, transaction_nonce,
instance.build_signed_header_call(headers), instance.build_signed_header_call(headers),
) )
@@ -259,11 +260,12 @@ impl SubmitEthereumExchangeTransactionProof for SubstrateClient<Rialto> {
proof: rialto_runtime::exchange::EthereumTransactionInclusionProof, proof: rialto_runtime::exchange::EthereumTransactionInclusionProof,
) -> RpcResult<()> { ) -> RpcResult<()> {
let genesis_hash = *self.genesis_hash(); let genesis_hash = *self.genesis_hash();
self.submit_signed_extrinsic((*params.public().as_array_ref()).into(), move |transaction_nonce| { self.submit_signed_extrinsic((*params.public().as_array_ref()).into(), move |_, transaction_nonce| {
Bytes( Bytes(
Rialto::sign_transaction( Rialto::sign_transaction(
genesis_hash, genesis_hash,
&params, &params,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce, transaction_nonce,
instance.build_currency_exchange_call(proof), instance.build_currency_exchange_call(proof),
) )
@@ -54,6 +54,7 @@ impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto {
fn make_submit_finality_proof_transaction( fn make_submit_finality_proof_transaction(
&self, &self,
era: bp_runtime::TransactionEraOf<Rialto>,
transaction_nonce: <Rialto as Chain>::Index, transaction_nonce: <Rialto as Chain>::Index,
header: MillauSyncHeader, header: MillauSyncHeader,
proof: GrandpaJustification<bp_millau::Header>, proof: GrandpaJustification<bp_millau::Header>,
@@ -64,6 +65,7 @@ impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto {
let transaction = Rialto::sign_transaction( let transaction = Rialto::sign_transaction(
genesis_hash, genesis_hash,
&self.finality_pipeline.target_sign, &self.finality_pipeline.target_sign,
era,
transaction_nonce, transaction_nonce,
call, call,
); );
@@ -82,8 +82,13 @@ impl SubstrateMessageLane for MillauMessagesToRialto {
millau_runtime::MessagesCall::receive_messages_delivery_proof(proof, relayers_state).into(); millau_runtime::MessagesCall::receive_messages_delivery_proof(proof, relayers_state).into();
let call_weight = call.get_dispatch_info().weight; let call_weight = call.get_dispatch_info().weight;
let genesis_hash = *self.message_lane.source_client.genesis_hash(); let genesis_hash = *self.message_lane.source_client.genesis_hash();
let transaction = let transaction = Millau::sign_transaction(
Millau::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call); genesis_hash,
&self.message_lane.source_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!( log::trace!(
target: "bridge", target: "bridge",
"Prepared Rialto -> Millau confirmation transaction. Weight: {}/{}, size: {}/{}", "Prepared Rialto -> Millau confirmation transaction. Weight: {}/{}, size: {}/{}",
@@ -122,8 +127,13 @@ impl SubstrateMessageLane for MillauMessagesToRialto {
.into(); .into();
let call_weight = call.get_dispatch_info().weight; let call_weight = call.get_dispatch_info().weight;
let genesis_hash = *self.message_lane.target_client.genesis_hash(); let genesis_hash = *self.message_lane.target_client.genesis_hash();
let transaction = let transaction = Rialto::sign_transaction(
Rialto::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call); genesis_hash,
&self.message_lane.target_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!( log::trace!(
target: "bridge", target: "bridge",
"Prepared Millau -> Rialto delivery transaction. Weight: {}/{}, size: {}/{}", "Prepared Millau -> Rialto delivery transaction. Weight: {}/{}, size: {}/{}",
@@ -214,6 +214,7 @@ mod tests {
let rialto_tx = Rialto::sign_transaction( let rialto_tx = Rialto::sign_transaction(
Default::default(), Default::default(),
&sp_keyring::AccountKeyring::Alice.pair(), &sp_keyring::AccountKeyring::Alice.pair(),
relay_substrate_client::TransactionEra::immortal(),
0, 0,
rialto_call.clone(), rialto_call.clone(),
); );
@@ -232,6 +233,7 @@ mod tests {
let millau_tx = Millau::sign_transaction( let millau_tx = Millau::sign_transaction(
Default::default(), Default::default(),
&sp_keyring::AccountKeyring::Alice.pair(), &sp_keyring::AccountKeyring::Alice.pair(),
relay_substrate_client::TransactionEra::immortal(),
0, 0,
millau_call.clone(), millau_call.clone(),
); );
@@ -55,6 +55,7 @@ impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau {
fn make_submit_finality_proof_transaction( fn make_submit_finality_proof_transaction(
&self, &self,
era: bp_runtime::TransactionEraOf<Millau>,
transaction_nonce: <Millau as Chain>::Index, transaction_nonce: <Millau as Chain>::Index,
header: RialtoSyncHeader, header: RialtoSyncHeader,
proof: GrandpaJustification<bp_rialto::Header>, proof: GrandpaJustification<bp_rialto::Header>,
@@ -69,6 +70,7 @@ impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau {
let transaction = Millau::sign_transaction( let transaction = Millau::sign_transaction(
genesis_hash, genesis_hash,
&self.finality_pipeline.target_sign, &self.finality_pipeline.target_sign,
era,
transaction_nonce, transaction_nonce,
call, call,
); );
@@ -82,8 +82,13 @@ impl SubstrateMessageLane for RialtoMessagesToMillau {
rialto_runtime::MessagesCall::receive_messages_delivery_proof(proof, relayers_state).into(); rialto_runtime::MessagesCall::receive_messages_delivery_proof(proof, relayers_state).into();
let call_weight = call.get_dispatch_info().weight; let call_weight = call.get_dispatch_info().weight;
let genesis_hash = *self.message_lane.source_client.genesis_hash(); let genesis_hash = *self.message_lane.source_client.genesis_hash();
let transaction = let transaction = Rialto::sign_transaction(
Rialto::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call); genesis_hash,
&self.message_lane.source_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!( log::trace!(
target: "bridge", target: "bridge",
"Prepared Millau -> Rialto confirmation transaction. Weight: {}/{}, size: {}/{}", "Prepared Millau -> Rialto confirmation transaction. Weight: {}/{}, size: {}/{}",
@@ -122,8 +127,13 @@ impl SubstrateMessageLane for RialtoMessagesToMillau {
.into(); .into();
let call_weight = call.get_dispatch_info().weight; let call_weight = call.get_dispatch_info().weight;
let genesis_hash = *self.message_lane.target_client.genesis_hash(); let genesis_hash = *self.message_lane.target_client.genesis_hash();
let transaction = let transaction = Millau::sign_transaction(
Millau::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call); genesis_hash,
&self.message_lane.target_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!( log::trace!(
target: "bridge", target: "bridge",
"Prepared Rialto -> Millau delivery transaction. Weight: {}/{}, size: {}/{}", "Prepared Rialto -> Millau delivery transaction. Weight: {}/{}, size: {}/{}",
@@ -77,6 +77,7 @@ impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo {
fn make_submit_finality_proof_transaction( fn make_submit_finality_proof_transaction(
&self, &self,
era: bp_runtime::TransactionEraOf<Wococo>,
transaction_nonce: <Wococo as Chain>::Index, transaction_nonce: <Wococo as Chain>::Index,
header: RococoSyncHeader, header: RococoSyncHeader,
proof: GrandpaJustification<bp_rococo::Header>, proof: GrandpaJustification<bp_rococo::Header>,
@@ -88,6 +89,7 @@ impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo {
let transaction = Wococo::sign_transaction( let transaction = Wococo::sign_transaction(
genesis_hash, genesis_hash,
&self.finality_pipeline.target_sign, &self.finality_pipeline.target_sign,
era,
transaction_nonce, transaction_nonce,
call, call,
); );
@@ -84,8 +84,13 @@ impl SubstrateMessageLane for RococoMessagesToWococo {
), ),
); );
let genesis_hash = *self.message_lane.source_client.genesis_hash(); let genesis_hash = *self.message_lane.source_client.genesis_hash();
let transaction = let transaction = Rococo::sign_transaction(
Rococo::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call); genesis_hash,
&self.message_lane.source_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!( log::trace!(
target: "bridge", target: "bridge",
"Prepared Wococo -> Rococo confirmation transaction. Weight: <unknown>/{}, size: {}/{}", "Prepared Wococo -> Rococo confirmation transaction. Weight: <unknown>/{}, size: {}/{}",
@@ -124,8 +129,13 @@ impl SubstrateMessageLane for RococoMessagesToWococo {
), ),
); );
let genesis_hash = *self.message_lane.target_client.genesis_hash(); let genesis_hash = *self.message_lane.target_client.genesis_hash();
let transaction = let transaction = Wococo::sign_transaction(
Wococo::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call); genesis_hash,
&self.message_lane.target_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!( log::trace!(
target: "bridge", target: "bridge",
"Prepared Rococo -> Wococo delivery transaction. Weight: <unknown>/{}, size: {}/{}", "Prepared Rococo -> Wococo delivery transaction. Weight: <unknown>/{}, size: {}/{}",
@@ -63,6 +63,7 @@ impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau {
fn make_submit_finality_proof_transaction( fn make_submit_finality_proof_transaction(
&self, &self,
era: bp_runtime::TransactionEraOf<Millau>,
transaction_nonce: <Millau as Chain>::Index, transaction_nonce: <Millau as Chain>::Index,
header: WestendSyncHeader, header: WestendSyncHeader,
proof: GrandpaJustification<bp_westend::Header>, proof: GrandpaJustification<bp_westend::Header>,
@@ -77,6 +78,7 @@ impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau {
let transaction = Millau::sign_transaction( let transaction = Millau::sign_transaction(
genesis_hash, genesis_hash,
&self.finality_pipeline.target_sign, &self.finality_pipeline.target_sign,
era,
transaction_nonce, transaction_nonce,
call, call,
); );
@@ -82,6 +82,7 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo {
fn make_submit_finality_proof_transaction( fn make_submit_finality_proof_transaction(
&self, &self,
era: bp_runtime::TransactionEraOf<Rococo>,
transaction_nonce: <Rococo as Chain>::Index, transaction_nonce: <Rococo as Chain>::Index,
header: WococoSyncHeader, header: WococoSyncHeader,
proof: GrandpaJustification<bp_wococo::Header>, proof: GrandpaJustification<bp_wococo::Header>,
@@ -93,6 +94,7 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo {
let transaction = Rococo::sign_transaction( let transaction = Rococo::sign_transaction(
genesis_hash, genesis_hash,
&self.finality_pipeline.target_sign, &self.finality_pipeline.target_sign,
era,
transaction_nonce, transaction_nonce,
call, call,
); );
@@ -83,8 +83,13 @@ impl SubstrateMessageLane for WococoMessagesToRococo {
), ),
); );
let genesis_hash = *self.message_lane.source_client.genesis_hash(); let genesis_hash = *self.message_lane.source_client.genesis_hash();
let transaction = let transaction = Wococo::sign_transaction(
Wococo::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call); genesis_hash,
&self.message_lane.source_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!( log::trace!(
target: "bridge", target: "bridge",
"Prepared Rococo -> Wococo confirmation transaction. Weight: <unknown>/{}, size: {}/{}", "Prepared Rococo -> Wococo confirmation transaction. Weight: <unknown>/{}, size: {}/{}",
@@ -123,8 +128,13 @@ impl SubstrateMessageLane for WococoMessagesToRococo {
), ),
); );
let genesis_hash = *self.message_lane.target_client.genesis_hash(); let genesis_hash = *self.message_lane.target_client.genesis_hash();
let transaction = let transaction = Rococo::sign_transaction(
Rococo::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call); genesis_hash,
&self.message_lane.target_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!( log::trace!(
target: "bridge", target: "bridge",
"Prepared Wococo -> Rococo delivery transaction. Weight: <unknown>/{}, size: {}/{}", "Prepared Wococo -> Rococo delivery transaction. Weight: <unknown>/{}, size: {}/{}",
@@ -150,6 +150,7 @@ impl InitBridge {
Target::sign_transaction( Target::sign_transaction(
*target_client.genesis_hash(), *target_client.genesis_hash(),
&target_sign, &target_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce, transaction_nonce,
encode_init_bridge(initialization_data), encode_init_bridge(initialization_data),
) )
@@ -389,6 +389,10 @@ macro_rules! declare_chain_options {
#[doc = "Path to the file, that password for the SURI of secret key to use when transactions are submitted to the " $chain " node. Can be overridden with " $chain_prefix "_signer_password option."] #[doc = "Path to the file, that password for the SURI of secret key to use when transactions are submitted to the " $chain " node. Can be overridden with " $chain_prefix "_signer_password option."]
#[structopt(long)] #[structopt(long)]
pub [<$chain_prefix _signer_password_file>]: Option<std::path::PathBuf>, pub [<$chain_prefix _signer_password_file>]: Option<std::path::PathBuf>,
#[doc = "Transactions mortality period, in blocks. MUST be a power of two in [4; 65536] range. MAY NOT be larger than `BlockHashCount` parameter of the chain system module."]
#[structopt(long)]
pub [<$chain_prefix _transactions_mortality>]: Option<u32>,
} }
#[doc = "Parameters required to sign transaction on behalf of owner of the messages pallet at " $chain "."] #[doc = "Parameters required to sign transaction on behalf of owner of the messages pallet at " $chain "."]
@@ -403,6 +407,25 @@ macro_rules! declare_chain_options {
} }
impl [<$chain SigningParams>] { impl [<$chain SigningParams>] {
/// Return transactions mortality.
#[allow(dead_code)]
pub fn transactions_mortality(&self) -> anyhow::Result<Option<u32>> {
self.[<$chain_prefix _transactions_mortality>]
.map(|transactions_mortality| {
if !(4..=65536).contains(&transactions_mortality)
|| !transactions_mortality.is_power_of_two()
{
Err(anyhow::format_err!(
"Transactions mortality {} is not a power of two in a [4; 65536] range",
transactions_mortality,
))
} else {
Ok(transactions_mortality)
}
})
.transpose()
}
/// Parse signing params into chain-specific KeyPair. /// Parse signing params into chain-specific KeyPair.
pub fn to_keypair<Chain: CliChain>(&self) -> anyhow::Result<Chain::KeyPair> { pub fn to_keypair<Chain: CliChain>(&self) -> anyhow::Result<Chain::KeyPair> {
let suri = match (self.[<$chain_prefix _signer>].as_ref(), self.[<$chain_prefix _signer_file>].as_ref()) { let suri = match (self.[<$chain_prefix _signer>].as_ref(), self.[<$chain_prefix _signer_file>].as_ref()) {
@@ -550,6 +573,8 @@ mod tests {
target_signer_file: None, target_signer_file: None,
target_signer_password_file: None, target_signer_password_file: None,
target_transactions_mortality: None,
} }
.to_keypair::<relay_rialto_client::Rialto>() .to_keypair::<relay_rialto_client::Rialto>()
.map(|p| p.public()) .map(|p| p.public())
@@ -565,6 +590,8 @@ mod tests {
target_signer_file: Some(suri_file_path.clone()), target_signer_file: Some(suri_file_path.clone()),
target_signer_password_file: Some(password_file_path.clone()), target_signer_password_file: Some(password_file_path.clone()),
target_transactions_mortality: None,
} }
.to_keypair::<relay_rialto_client::Rialto>() .to_keypair::<relay_rialto_client::Rialto>()
.map(|p| p.public()) .map(|p| p.public())
@@ -580,6 +607,8 @@ mod tests {
target_signer_file: Some(suri_file_path.clone()), target_signer_file: Some(suri_file_path.clone()),
target_signer_password_file: Some(password_file_path.clone()), target_signer_password_file: Some(password_file_path.clone()),
target_transactions_mortality: None,
} }
.to_keypair::<relay_rialto_client::Rialto>() .to_keypair::<relay_rialto_client::Rialto>()
.map(|p| p.public()) .map(|p| p.public())
@@ -595,6 +624,8 @@ mod tests {
target_signer_file: Some(suri_file_path), target_signer_file: Some(suri_file_path),
target_signer_password_file: Some(password_file_path), target_signer_password_file: Some(password_file_path),
target_transactions_mortality: None,
} }
.to_keypair::<relay_rialto_client::Rialto>() .to_keypair::<relay_rialto_client::Rialto>()
.map(|p| p.public()) .map(|p| p.public())
@@ -99,6 +99,7 @@ impl RelayHeaders {
select_bridge!(self.bridge, { select_bridge!(self.bridge, {
let source_client = self.source.to_client::<Source>().await?; let source_client = self.source.to_client::<Source>().await?;
let target_client = self.target.to_client::<Target>().await?; let target_client = self.target.to_client::<Target>().await?;
let target_transactions_mortality = self.target_sign.target_transactions_mortality;
let target_sign = self.target_sign.to_keypair::<Target>()?; let target_sign = self.target_sign.to_keypair::<Target>()?;
let metrics_params = Finality::customize_metrics(self.prometheus_params.into())?; let metrics_params = Finality::customize_metrics(self.prometheus_params.into())?;
let finality = Finality::new(target_client.clone(), target_sign); let finality = Finality::new(target_client.clone(), target_sign);
@@ -109,6 +110,7 @@ impl RelayHeaders {
source_client, source_client,
target_client, target_client,
self.only_mandatory_headers, self.only_mandatory_headers,
target_transactions_mortality,
metrics_params, metrics_params,
) )
.await .await
@@ -188,9 +188,11 @@ impl RelayHeadersAndMessages {
let params: Params = self.into(); let params: Params = self.into();
let left_client = params.left.to_client::<Left>().await?; let left_client = params.left.to_client::<Left>().await?;
let left_transactions_mortality = params.left_sign.transactions_mortality()?;
let left_sign = params.left_sign.to_keypair::<Left>()?; let left_sign = params.left_sign.to_keypair::<Left>()?;
let left_messages_pallet_owner = params.left_messages_pallet_owner.to_keypair::<Left>()?; let left_messages_pallet_owner = params.left_messages_pallet_owner.to_keypair::<Left>()?;
let right_client = params.right.to_client::<Right>().await?; let right_client = params.right.to_client::<Right>().await?;
let right_transactions_mortality = params.right_sign.transactions_mortality()?;
let right_sign = params.right_sign.to_keypair::<Right>()?; let right_sign = params.right_sign.to_keypair::<Right>()?;
let right_messages_pallet_owner = params.right_messages_pallet_owner.to_keypair::<Right>()?; let right_messages_pallet_owner = params.right_messages_pallet_owner.to_keypair::<Right>()?;
@@ -273,12 +275,14 @@ impl RelayHeadersAndMessages {
let left_to_right_on_demand_headers = OnDemandHeadersRelay::new( let left_to_right_on_demand_headers = OnDemandHeadersRelay::new(
left_client.clone(), left_client.clone(),
right_client.clone(), right_client.clone(),
right_transactions_mortality,
LeftToRightFinality::new(right_client.clone(), right_sign.clone()), LeftToRightFinality::new(right_client.clone(), right_sign.clone()),
MAX_MISSING_LEFT_HEADERS_AT_RIGHT, MAX_MISSING_LEFT_HEADERS_AT_RIGHT,
); );
let right_to_left_on_demand_headers = OnDemandHeadersRelay::new( let right_to_left_on_demand_headers = OnDemandHeadersRelay::new(
right_client.clone(), right_client.clone(),
left_client.clone(), left_client.clone(),
left_transactions_mortality,
RightToLeftFinality::new(left_client.clone(), left_sign.clone()), RightToLeftFinality::new(left_client.clone(), left_sign.clone()),
MAX_MISSING_RIGHT_HEADERS_AT_LEFT, MAX_MISSING_RIGHT_HEADERS_AT_LEFT,
); );
@@ -178,10 +178,11 @@ impl SendMessage {
let source_genesis_hash = *source_client.genesis_hash(); let source_genesis_hash = *source_client.genesis_hash();
source_client source_client
.submit_signed_extrinsic(source_sign.public().into(), move |transaction_nonce| { .submit_signed_extrinsic(source_sign.public().into(), move |_, transaction_nonce| {
let signed_source_call = Source::sign_transaction( let signed_source_call = Source::sign_transaction(
source_genesis_hash, source_genesis_hash,
&source_sign, &source_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce, transaction_nonce,
send_message_call, send_message_call,
) )
+3 -2
View File
@@ -66,6 +66,7 @@ impl TransactionSignScheme for Millau {
fn sign_transaction( fn sign_transaction(
genesis_hash: <Self::Chain as ChainBase>::Hash, genesis_hash: <Self::Chain as ChainBase>::Hash,
signer: &Self::AccountKeyPair, signer: &Self::AccountKeyPair,
era: relay_substrate_client::TransactionEraOf<Self::Chain>,
signer_nonce: <Self::Chain as Chain>::Index, signer_nonce: <Self::Chain as Chain>::Index,
call: <Self::Chain as Chain>::Call, call: <Self::Chain as Chain>::Call,
) -> Self::SignedTransaction { ) -> Self::SignedTransaction {
@@ -75,7 +76,7 @@ impl TransactionSignScheme for Millau {
frame_system::CheckSpecVersion::<millau_runtime::Runtime>::new(), frame_system::CheckSpecVersion::<millau_runtime::Runtime>::new(),
frame_system::CheckTxVersion::<millau_runtime::Runtime>::new(), frame_system::CheckTxVersion::<millau_runtime::Runtime>::new(),
frame_system::CheckGenesis::<millau_runtime::Runtime>::new(), frame_system::CheckGenesis::<millau_runtime::Runtime>::new(),
frame_system::CheckEra::<millau_runtime::Runtime>::from(sp_runtime::generic::Era::Immortal), frame_system::CheckEra::<millau_runtime::Runtime>::from(era.frame_era()),
frame_system::CheckNonce::<millau_runtime::Runtime>::from(signer_nonce), frame_system::CheckNonce::<millau_runtime::Runtime>::from(signer_nonce),
frame_system::CheckWeight::<millau_runtime::Runtime>::new(), frame_system::CheckWeight::<millau_runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<millau_runtime::Runtime>::from(0), pallet_transaction_payment::ChargeTransactionPayment::<millau_runtime::Runtime>::from(0),
@@ -84,7 +85,7 @@ impl TransactionSignScheme for Millau {
millau_runtime::VERSION.spec_version, millau_runtime::VERSION.spec_version,
millau_runtime::VERSION.transaction_version, millau_runtime::VERSION.transaction_version,
genesis_hash, genesis_hash,
genesis_hash, era.signed_payload(genesis_hash),
(), (),
(), (),
(), (),
+3 -2
View File
@@ -66,6 +66,7 @@ impl TransactionSignScheme for Rialto {
fn sign_transaction( fn sign_transaction(
genesis_hash: <Self::Chain as ChainBase>::Hash, genesis_hash: <Self::Chain as ChainBase>::Hash,
signer: &Self::AccountKeyPair, signer: &Self::AccountKeyPair,
era: relay_substrate_client::TransactionEraOf<Self::Chain>,
signer_nonce: <Self::Chain as Chain>::Index, signer_nonce: <Self::Chain as Chain>::Index,
call: <Self::Chain as Chain>::Call, call: <Self::Chain as Chain>::Call,
) -> Self::SignedTransaction { ) -> Self::SignedTransaction {
@@ -75,7 +76,7 @@ impl TransactionSignScheme for Rialto {
frame_system::CheckSpecVersion::<rialto_runtime::Runtime>::new(), frame_system::CheckSpecVersion::<rialto_runtime::Runtime>::new(),
frame_system::CheckTxVersion::<rialto_runtime::Runtime>::new(), frame_system::CheckTxVersion::<rialto_runtime::Runtime>::new(),
frame_system::CheckGenesis::<rialto_runtime::Runtime>::new(), frame_system::CheckGenesis::<rialto_runtime::Runtime>::new(),
frame_system::CheckEra::<rialto_runtime::Runtime>::from(sp_runtime::generic::Era::Immortal), frame_system::CheckEra::<rialto_runtime::Runtime>::from(era.frame_era()),
frame_system::CheckNonce::<rialto_runtime::Runtime>::from(signer_nonce), frame_system::CheckNonce::<rialto_runtime::Runtime>::from(signer_nonce),
frame_system::CheckWeight::<rialto_runtime::Runtime>::new(), frame_system::CheckWeight::<rialto_runtime::Runtime>::new(),
pallet_transaction_payment::ChargeTransactionPayment::<rialto_runtime::Runtime>::from(0), pallet_transaction_payment::ChargeTransactionPayment::<rialto_runtime::Runtime>::from(0),
@@ -84,7 +85,7 @@ impl TransactionSignScheme for Rialto {
rialto_runtime::VERSION.spec_version, rialto_runtime::VERSION.spec_version,
rialto_runtime::VERSION.transaction_version, rialto_runtime::VERSION.transaction_version,
genesis_hash, genesis_hash,
genesis_hash, era.signed_payload(genesis_hash),
(), (),
(), (),
(), (),
+2 -7
View File
@@ -68,18 +68,13 @@ impl TransactionSignScheme for Rococo {
fn sign_transaction( fn sign_transaction(
genesis_hash: <Self::Chain as ChainBase>::Hash, genesis_hash: <Self::Chain as ChainBase>::Hash,
signer: &Self::AccountKeyPair, signer: &Self::AccountKeyPair,
era: relay_substrate_client::TransactionEraOf<Self::Chain>,
signer_nonce: <Self::Chain as Chain>::Index, signer_nonce: <Self::Chain as Chain>::Index,
call: <Self::Chain as Chain>::Call, call: <Self::Chain as Chain>::Call,
) -> Self::SignedTransaction { ) -> Self::SignedTransaction {
let raw_payload = SignedPayload::new( let raw_payload = SignedPayload::new(
call, call,
bp_rococo::SignedExtensions::new( bp_rococo::SignedExtensions::new(bp_rococo::VERSION, era, genesis_hash, signer_nonce, 0),
bp_rococo::VERSION,
sp_runtime::generic::Era::Immortal,
genesis_hash,
signer_nonce,
0,
),
) )
.expect("SignedExtension never fails."); .expect("SignedExtension never fails.");
@@ -107,6 +107,7 @@ pub trait TransactionSignScheme {
fn sign_transaction( fn sign_transaction(
genesis_hash: <Self::Chain as ChainBase>::Hash, genesis_hash: <Self::Chain as ChainBase>::Hash,
signer: &Self::AccountKeyPair, signer: &Self::AccountKeyPair,
era: bp_runtime::TransactionEraOf<Self::Chain>,
signer_nonce: <Self::Chain as Chain>::Index, signer_nonce: <Self::Chain as Chain>::Index,
call: <Self::Chain as Chain>::Call, call: <Self::Chain as Chain>::Call,
) -> Self::SignedTransaction; ) -> Self::SignedTransaction;
@@ -18,7 +18,7 @@
use crate::chain::{Chain, ChainWithBalances}; use crate::chain::{Chain, ChainWithBalances};
use crate::rpc::Substrate; use crate::rpc::Substrate;
use crate::{ConnectionParams, Error, Result}; use crate::{ConnectionParams, Error, HeaderIdOf, Result};
use async_std::sync::{Arc, Mutex}; use async_std::sync::{Arc, Mutex};
use codec::Decode; use codec::Decode;
@@ -29,8 +29,9 @@ use jsonrpsee_ws_client::{WsClient as RpcClient, WsClientBuilder as RpcClientBui
use num_traits::{Bounded, Zero}; use num_traits::{Bounded, Zero};
use pallet_balances::AccountData; use pallet_balances::AccountData;
use pallet_transaction_payment::InclusionFee; use pallet_transaction_payment::InclusionFee;
use relay_utils::relay_loop::RECONNECT_DELAY; use relay_utils::{relay_loop::RECONNECT_DELAY, HeaderId};
use sp_core::{storage::StorageKey, Bytes}; use sp_core::{storage::StorageKey, Bytes};
use sp_runtime::traits::Header as HeaderT;
use sp_trie::StorageProof; use sp_trie::StorageProof;
use sp_version::RuntimeVersion; use sp_version::RuntimeVersion;
use std::{convert::TryFrom, future::Future}; use std::{convert::TryFrom, future::Future};
@@ -293,12 +294,14 @@ impl<C: Chain> Client<C> {
pub async fn submit_signed_extrinsic( pub async fn submit_signed_extrinsic(
&self, &self,
extrinsic_signer: C::AccountId, extrinsic_signer: C::AccountId,
prepare_extrinsic: impl FnOnce(C::Index) -> Bytes + Send + 'static, prepare_extrinsic: impl FnOnce(HeaderIdOf<C>, C::Index) -> Bytes + Send + 'static,
) -> Result<C::Hash> { ) -> Result<C::Hash> {
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(extrinsic_signer).await?;
let best_header = self.best_header().await?;
let best_header_id = HeaderId(*best_header.number(), best_header.hash());
self.jsonrpsee_execute(move |client| async move { self.jsonrpsee_execute(move |client| async move {
let extrinsic = prepare_extrinsic(transaction_nonce); let extrinsic = prepare_extrinsic(best_header_id, transaction_nonce);
let tx_hash = Substrate::<C>::author_submit_extrinsic(&*client, extrinsic).await?; let tx_hash = Substrate::<C>::author_submit_extrinsic(&*client, extrinsic).await?;
log::trace!(target: "bridge", "Sent transaction to {} node: {:?}", C::NAME, tx_hash); log::trace!(target: "bridge", "Sent transaction to {} node: {:?}", C::NAME, tx_hash);
Ok(tx_hash) Ok(tx_hash)
+14 -1
View File
@@ -29,11 +29,13 @@ pub mod guard;
pub mod headers_source; pub mod headers_source;
pub mod metrics; pub mod metrics;
use std::time::Duration;
pub use crate::chain::{BlockWithJustification, Chain, ChainWithBalances, TransactionSignScheme}; pub use crate::chain::{BlockWithJustification, Chain, ChainWithBalances, TransactionSignScheme};
pub use crate::client::{Client, JustificationsSubscription, OpaqueGrandpaAuthoritiesSet}; pub use crate::client::{Client, JustificationsSubscription, OpaqueGrandpaAuthoritiesSet};
pub use crate::error::{Error, Result}; pub use crate::error::{Error, Result};
pub use crate::sync_header::SyncHeader; pub use crate::sync_header::SyncHeader;
pub use bp_runtime::{BlockNumberOf, Chain as ChainBase, HashOf, HeaderOf}; pub use bp_runtime::{BlockNumberOf, Chain as ChainBase, HashOf, HeaderOf, TransactionEra, TransactionEraOf};
/// Header id used by the chain. /// Header id used by the chain.
pub type HeaderIdOf<C> = relay_utils::HeaderId<HashOf<C>, BlockNumberOf<C>>; pub type HeaderIdOf<C> = relay_utils::HeaderId<HashOf<C>, BlockNumberOf<C>>;
@@ -58,3 +60,14 @@ impl Default for ConnectionParams {
} }
} }
} }
/// Returns stall timeout for relay loop.
///
/// Relay considers himself stalled if he has submitted transaction to the node, but it has not
/// been mined for this period.
///
/// Returns `None` if mortality period is `None`
pub fn transaction_stall_timeout(mortality_period: Option<u32>, average_block_interval: Duration) -> Option<Duration> {
// 1 extra block for transaction to reach the pool && 1 for relayer to awake after it is mined
mortality_period.map(|mortality_period| average_block_interval.saturating_mul(mortality_period + 1 + 1))
}
+2 -7
View File
@@ -66,18 +66,13 @@ impl TransactionSignScheme for Westend {
fn sign_transaction( fn sign_transaction(
genesis_hash: <Self::Chain as ChainBase>::Hash, genesis_hash: <Self::Chain as ChainBase>::Hash,
signer: &Self::AccountKeyPair, signer: &Self::AccountKeyPair,
era: relay_substrate_client::TransactionEraOf<Self::Chain>,
signer_nonce: <Self::Chain as Chain>::Index, signer_nonce: <Self::Chain as Chain>::Index,
call: <Self::Chain as Chain>::Call, call: <Self::Chain as Chain>::Call,
) -> Self::SignedTransaction { ) -> Self::SignedTransaction {
let raw_payload = SignedPayload::new( let raw_payload = SignedPayload::new(
call, call,
bp_westend::SignedExtensions::new( bp_westend::SignedExtensions::new(bp_westend::VERSION, era, genesis_hash, signer_nonce, 0),
bp_westend::VERSION,
sp_runtime::generic::Era::Immortal,
genesis_hash,
signer_nonce,
0,
),
) )
.expect("SignedExtension never fails."); .expect("SignedExtension never fails.");
+2 -7
View File
@@ -68,18 +68,13 @@ impl TransactionSignScheme for Wococo {
fn sign_transaction( fn sign_transaction(
genesis_hash: <Self::Chain as ChainBase>::Hash, genesis_hash: <Self::Chain as ChainBase>::Hash,
signer: &Self::AccountKeyPair, signer: &Self::AccountKeyPair,
era: bp_runtime::TransactionEraOf<Self::Chain>,
signer_nonce: <Self::Chain as Chain>::Index, signer_nonce: <Self::Chain as Chain>::Index,
call: <Self::Chain as Chain>::Call, call: <Self::Chain as Chain>::Call,
) -> Self::SignedTransaction { ) -> Self::SignedTransaction {
let raw_payload = SignedPayload::new( let raw_payload = SignedPayload::new(
call, call,
bp_wococo::SignedExtensions::new( bp_wococo::SignedExtensions::new(bp_wococo::VERSION, era, genesis_hash, signer_nonce, 0),
bp_wococo::VERSION,
sp_runtime::generic::Era::Immortal,
genesis_hash,
signer_nonce,
0,
),
) )
.expect("SignedExtension never fails."); .expect("SignedExtension never fails.");
@@ -25,8 +25,14 @@ use relay_utils::{metrics::MetricsParams, BlockNumberBase};
use sp_core::Bytes; use sp_core::Bytes;
use std::{fmt::Debug, marker::PhantomData, time::Duration}; use std::{fmt::Debug, marker::PhantomData, time::Duration};
/// Default synchronization loop timeout. /// Default synchronization loop timeout. If transactions generated by relay are immortal, then
pub(crate) const STALL_TIMEOUT: Duration = Duration::from_secs(120); /// this timeout is used.
///
/// There are no any strict requirements on block time in Substrate. But we assume here that all
/// Substrate-based chains will be designed to produce relatively fast (compared to slowest
/// blockchains) blocks. So 1 hour seems to be a good guess for (even congested) chains to mine
/// transaction, or remove it from the pool.
pub(crate) const STALL_TIMEOUT: Duration = Duration::from_secs(60 * 60);
/// Default limit of recent finality proofs. /// Default limit of recent finality proofs.
/// ///
/// Finality delay of 4096 blocks is unlikely to happen in practice in /// Finality delay of 4096 blocks is unlikely to happen in practice in
@@ -62,6 +68,7 @@ pub trait SubstrateFinalitySyncPipeline: 'static + Clone + Debug + Send + Sync {
/// Make submit header transaction. /// Make submit header transaction.
fn make_submit_finality_proof_transaction( fn make_submit_finality_proof_transaction(
&self, &self,
era: bp_runtime::TransactionEraOf<Self::TargetChain>,
transaction_nonce: <Self::TargetChain as Chain>::Index, transaction_nonce: <Self::TargetChain as Chain>::Index,
header: <Self::FinalitySyncPipeline as FinalitySyncPipeline>::Header, header: <Self::FinalitySyncPipeline as FinalitySyncPipeline>::Header,
proof: <Self::FinalitySyncPipeline as FinalitySyncPipeline>::FinalityProof, proof: <Self::FinalitySyncPipeline as FinalitySyncPipeline>::FinalityProof,
@@ -123,6 +130,7 @@ pub async fn run<SourceChain, TargetChain, P>(
source_client: Client<SourceChain>, source_client: Client<SourceChain>,
target_client: Client<TargetChain>, target_client: Client<TargetChain>,
only_mandatory_headers: bool, only_mandatory_headers: bool,
transactions_mortality: Option<u32>,
metrics_params: MetricsParams, metrics_params: MetricsParams,
) -> anyhow::Result<()> ) -> anyhow::Result<()>
where where
@@ -146,11 +154,15 @@ where
finality_relay::run( finality_relay::run(
FinalitySource::new(source_client, None), FinalitySource::new(source_client, None),
SubstrateFinalityTarget::new(target_client, pipeline), SubstrateFinalityTarget::new(target_client, pipeline, transactions_mortality),
FinalitySyncParams { FinalitySyncParams {
tick: std::cmp::max(SourceChain::AVERAGE_BLOCK_INTERVAL, TargetChain::AVERAGE_BLOCK_INTERVAL), tick: std::cmp::max(SourceChain::AVERAGE_BLOCK_INTERVAL, TargetChain::AVERAGE_BLOCK_INTERVAL),
recent_finality_proofs_limit: RECENT_FINALITY_PROOFS_LIMIT, recent_finality_proofs_limit: RECENT_FINALITY_PROOFS_LIMIT,
stall_timeout: STALL_TIMEOUT, stall_timeout: relay_substrate_client::transaction_stall_timeout(
transactions_mortality,
TargetChain::AVERAGE_BLOCK_INTERVAL,
)
.unwrap_or(STALL_TIMEOUT),
only_mandatory_headers, only_mandatory_headers,
}, },
metrics_params, metrics_params,
@@ -30,12 +30,17 @@ use relay_utils::relay_loop::Client as RelayClient;
pub struct SubstrateFinalityTarget<C: Chain, P> { pub struct SubstrateFinalityTarget<C: Chain, P> {
client: Client<C>, client: Client<C>,
pipeline: P, pipeline: P,
transactions_mortality: Option<u32>,
} }
impl<C: Chain, P> SubstrateFinalityTarget<C, P> { impl<C: Chain, P> SubstrateFinalityTarget<C, P> {
/// Create new Substrate headers target. /// Create new Substrate headers target.
pub fn new(client: Client<C>, pipeline: P) -> Self { pub fn new(client: Client<C>, pipeline: P, transactions_mortality: Option<u32>) -> Self {
SubstrateFinalityTarget { client, pipeline } SubstrateFinalityTarget {
client,
pipeline,
transactions_mortality,
}
} }
} }
@@ -44,6 +49,7 @@ impl<C: Chain, P: SubstrateFinalitySyncPipeline> Clone for SubstrateFinalityTarg
SubstrateFinalityTarget { SubstrateFinalityTarget {
client: self.client.clone(), client: self.client.clone(),
pipeline: self.pipeline.clone(), pipeline: self.pipeline.clone(),
transactions_mortality: self.transactions_mortality,
} }
} }
} }
@@ -89,9 +95,19 @@ where
) -> Result<(), SubstrateError> { ) -> Result<(), SubstrateError> {
let transactions_author = self.pipeline.transactions_author(); let transactions_author = self.pipeline.transactions_author();
let pipeline = self.pipeline.clone(); let pipeline = self.pipeline.clone();
let transactions_mortality = self.transactions_mortality;
self.client self.client
.submit_signed_extrinsic(transactions_author, move |transaction_nonce| { .submit_signed_extrinsic(transactions_author, move |best_block_id, transaction_nonce| {
pipeline.make_submit_finality_proof_transaction(transaction_nonce, header, proof) pipeline.make_submit_finality_proof_transaction(
relay_substrate_client::TransactionEra::new(
best_block_id.0,
best_block_id.1,
transactions_mortality,
),
transaction_nonce,
header,
proof,
)
}) })
.await .await
.map(drop) .map(drop)
@@ -88,7 +88,7 @@ async fn do_initialize<SourceChain: Chain, TargetChain: Chain>(
); );
let initialization_tx_hash = target_client let initialization_tx_hash = target_client
.submit_signed_extrinsic(target_transactions_signer, move |transaction_nonce| { .submit_signed_extrinsic(target_transactions_signer, move |_, transaction_nonce| {
prepare_initialize_transaction(transaction_nonce, initialization_data) prepare_initialize_transaction(transaction_nonce, initialization_data)
}) })
.await .await
@@ -246,7 +246,7 @@ where
) -> Result<(), SubstrateError> { ) -> Result<(), SubstrateError> {
let lane = self.lane.clone(); let lane = self.lane.clone();
self.client self.client
.submit_signed_extrinsic(self.lane.source_transactions_author(), move |transaction_nonce| { .submit_signed_extrinsic(self.lane.source_transactions_author(), move |_, transaction_nonce| {
lane.make_messages_receiving_proof_transaction(transaction_nonce, generated_at_block, proof) lane.make_messages_receiving_proof_transaction(transaction_nonce, generated_at_block, proof)
}) })
.await?; .await?;
@@ -229,7 +229,7 @@ where
let lane = self.lane.clone(); let lane = self.lane.clone();
let nonces_clone = nonces.clone(); let nonces_clone = nonces.clone();
self.client self.client
.submit_signed_extrinsic(self.lane.target_transactions_author(), move |transaction_nonce| { .submit_signed_extrinsic(self.lane.target_transactions_author(), move |_, transaction_nonce| {
lane.make_messages_delivery_transaction(transaction_nonce, generated_at_header, nonces_clone, proof) lane.make_messages_delivery_transaction(transaction_nonce, generated_at_header, nonces_clone, proof)
}) })
.await?; .await?;
@@ -56,6 +56,7 @@ impl<SourceChain: Chain> OnDemandHeadersRelay<SourceChain> {
pub fn new<TargetChain: Chain, TargetSign, P>( pub fn new<TargetChain: Chain, TargetSign, P>(
source_client: Client<SourceChain>, source_client: Client<SourceChain>,
target_client: Client<TargetChain>, target_client: Client<TargetChain>,
target_transactions_mortality: Option<u32>,
pipeline: P, pipeline: P,
maximal_headers_difference: SourceChain::BlockNumber, maximal_headers_difference: SourceChain::BlockNumber,
) -> Self ) -> Self
@@ -79,6 +80,7 @@ impl<SourceChain: Chain> OnDemandHeadersRelay<SourceChain> {
background_task( background_task(
source_client, source_client,
target_client, target_client,
target_transactions_mortality,
pipeline, pipeline,
maximal_headers_difference, maximal_headers_difference,
required_header_number, required_header_number,
@@ -110,7 +112,7 @@ impl<SourceChain: Chain> OnDemandHeadersRelay<SourceChain> {
async fn background_task<SourceChain, TargetChain, TargetSign, P>( async fn background_task<SourceChain, TargetChain, TargetSign, P>(
source_client: Client<SourceChain>, source_client: Client<SourceChain>,
target_client: Client<TargetChain>, target_client: Client<TargetChain>,
// pipeline: SubstrateFinalityToSubstrate<SourceChain, TargetChain, TargetSign>, target_transactions_mortality: Option<u32>,
pipeline: P, pipeline: P,
maximal_headers_difference: SourceChain::BlockNumber, maximal_headers_difference: SourceChain::BlockNumber,
required_header_number: RequiredHeaderNumberRef<SourceChain>, required_header_number: RequiredHeaderNumberRef<SourceChain>,
@@ -130,7 +132,8 @@ async fn background_task<SourceChain, TargetChain, TargetSign, P>(
_, _,
SubstrateFinalityToSubstrate<SourceChain, TargetChain, TargetSign>, SubstrateFinalityToSubstrate<SourceChain, TargetChain, TargetSign>,
>::new(source_client.clone(), Some(required_header_number.clone())); >::new(source_client.clone(), Some(required_header_number.clone()));
let mut finality_target = SubstrateFinalityTarget::new(target_client.clone(), pipeline.clone()); let mut finality_target =
SubstrateFinalityTarget::new(target_client.clone(), pipeline.clone(), target_transactions_mortality);
let mut latest_non_mandatory_at_source = Zero::zero(); let mut latest_non_mandatory_at_source = Zero::zero();
let mut restart_relay = true; let mut restart_relay = true;