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
@@ -54,6 +54,7 @@ impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto {
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Rialto>,
transaction_nonce: <Rialto as Chain>::Index,
header: MillauSyncHeader,
proof: GrandpaJustification<bp_millau::Header>,
@@ -64,6 +65,7 @@ impl SubstrateFinalitySyncPipeline for MillauFinalityToRialto {
let transaction = Rialto::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
transaction_nonce,
call,
);
@@ -82,8 +82,13 @@ impl SubstrateMessageLane for MillauMessagesToRialto {
millau_runtime::MessagesCall::receive_messages_delivery_proof(proof, relayers_state).into();
let call_weight = call.get_dispatch_info().weight;
let genesis_hash = *self.message_lane.source_client.genesis_hash();
let transaction =
Millau::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call);
let transaction = Millau::sign_transaction(
genesis_hash,
&self.message_lane.source_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!(
target: "bridge",
"Prepared Rialto -> Millau confirmation transaction. Weight: {}/{}, size: {}/{}",
@@ -122,8 +127,13 @@ impl SubstrateMessageLane for MillauMessagesToRialto {
.into();
let call_weight = call.get_dispatch_info().weight;
let genesis_hash = *self.message_lane.target_client.genesis_hash();
let transaction =
Rialto::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call);
let transaction = Rialto::sign_transaction(
genesis_hash,
&self.message_lane.target_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!(
target: "bridge",
"Prepared Millau -> Rialto delivery transaction. Weight: {}/{}, size: {}/{}",
@@ -214,6 +214,7 @@ mod tests {
let rialto_tx = Rialto::sign_transaction(
Default::default(),
&sp_keyring::AccountKeyring::Alice.pair(),
relay_substrate_client::TransactionEra::immortal(),
0,
rialto_call.clone(),
);
@@ -232,6 +233,7 @@ mod tests {
let millau_tx = Millau::sign_transaction(
Default::default(),
&sp_keyring::AccountKeyring::Alice.pair(),
relay_substrate_client::TransactionEra::immortal(),
0,
millau_call.clone(),
);
@@ -55,6 +55,7 @@ impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau {
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Millau>,
transaction_nonce: <Millau as Chain>::Index,
header: RialtoSyncHeader,
proof: GrandpaJustification<bp_rialto::Header>,
@@ -69,6 +70,7 @@ impl SubstrateFinalitySyncPipeline for RialtoFinalityToMillau {
let transaction = Millau::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
transaction_nonce,
call,
);
@@ -82,8 +82,13 @@ impl SubstrateMessageLane for RialtoMessagesToMillau {
rialto_runtime::MessagesCall::receive_messages_delivery_proof(proof, relayers_state).into();
let call_weight = call.get_dispatch_info().weight;
let genesis_hash = *self.message_lane.source_client.genesis_hash();
let transaction =
Rialto::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call);
let transaction = Rialto::sign_transaction(
genesis_hash,
&self.message_lane.source_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!(
target: "bridge",
"Prepared Millau -> Rialto confirmation transaction. Weight: {}/{}, size: {}/{}",
@@ -122,8 +127,13 @@ impl SubstrateMessageLane for RialtoMessagesToMillau {
.into();
let call_weight = call.get_dispatch_info().weight;
let genesis_hash = *self.message_lane.target_client.genesis_hash();
let transaction =
Millau::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call);
let transaction = Millau::sign_transaction(
genesis_hash,
&self.message_lane.target_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!(
target: "bridge",
"Prepared Rialto -> Millau delivery transaction. Weight: {}/{}, size: {}/{}",
@@ -77,6 +77,7 @@ impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo {
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Wococo>,
transaction_nonce: <Wococo as Chain>::Index,
header: RococoSyncHeader,
proof: GrandpaJustification<bp_rococo::Header>,
@@ -88,6 +89,7 @@ impl SubstrateFinalitySyncPipeline for RococoFinalityToWococo {
let transaction = Wococo::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
transaction_nonce,
call,
);
@@ -84,8 +84,13 @@ impl SubstrateMessageLane for RococoMessagesToWococo {
),
);
let genesis_hash = *self.message_lane.source_client.genesis_hash();
let transaction =
Rococo::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call);
let transaction = Rococo::sign_transaction(
genesis_hash,
&self.message_lane.source_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!(
target: "bridge",
"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 transaction =
Wococo::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call);
let transaction = Wococo::sign_transaction(
genesis_hash,
&self.message_lane.target_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!(
target: "bridge",
"Prepared Rococo -> Wococo delivery transaction. Weight: <unknown>/{}, size: {}/{}",
@@ -63,6 +63,7 @@ impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau {
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Millau>,
transaction_nonce: <Millau as Chain>::Index,
header: WestendSyncHeader,
proof: GrandpaJustification<bp_westend::Header>,
@@ -77,6 +78,7 @@ impl SubstrateFinalitySyncPipeline for WestendFinalityToMillau {
let transaction = Millau::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
transaction_nonce,
call,
);
@@ -82,6 +82,7 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo {
fn make_submit_finality_proof_transaction(
&self,
era: bp_runtime::TransactionEraOf<Rococo>,
transaction_nonce: <Rococo as Chain>::Index,
header: WococoSyncHeader,
proof: GrandpaJustification<bp_wococo::Header>,
@@ -93,6 +94,7 @@ impl SubstrateFinalitySyncPipeline for WococoFinalityToRococo {
let transaction = Rococo::sign_transaction(
genesis_hash,
&self.finality_pipeline.target_sign,
era,
transaction_nonce,
call,
);
@@ -83,8 +83,13 @@ impl SubstrateMessageLane for WococoMessagesToRococo {
),
);
let genesis_hash = *self.message_lane.source_client.genesis_hash();
let transaction =
Wococo::sign_transaction(genesis_hash, &self.message_lane.source_sign, transaction_nonce, call);
let transaction = Wococo::sign_transaction(
genesis_hash,
&self.message_lane.source_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!(
target: "bridge",
"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 transaction =
Rococo::sign_transaction(genesis_hash, &self.message_lane.target_sign, transaction_nonce, call);
let transaction = Rococo::sign_transaction(
genesis_hash,
&self.message_lane.target_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
call,
);
log::trace!(
target: "bridge",
"Prepared Wococo -> Rococo delivery transaction. Weight: <unknown>/{}, size: {}/{}",
@@ -150,6 +150,7 @@ impl InitBridge {
Target::sign_transaction(
*target_client.genesis_hash(),
&target_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
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."]
#[structopt(long)]
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 "."]
@@ -403,6 +407,25 @@ macro_rules! declare_chain_options {
}
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.
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()) {
@@ -550,6 +573,8 @@ mod tests {
target_signer_file: None,
target_signer_password_file: None,
target_transactions_mortality: None,
}
.to_keypair::<relay_rialto_client::Rialto>()
.map(|p| p.public())
@@ -565,6 +590,8 @@ mod tests {
target_signer_file: Some(suri_file_path.clone()),
target_signer_password_file: Some(password_file_path.clone()),
target_transactions_mortality: None,
}
.to_keypair::<relay_rialto_client::Rialto>()
.map(|p| p.public())
@@ -580,6 +607,8 @@ mod tests {
target_signer_file: Some(suri_file_path.clone()),
target_signer_password_file: Some(password_file_path.clone()),
target_transactions_mortality: None,
}
.to_keypair::<relay_rialto_client::Rialto>()
.map(|p| p.public())
@@ -595,6 +624,8 @@ mod tests {
target_signer_file: Some(suri_file_path),
target_signer_password_file: Some(password_file_path),
target_transactions_mortality: None,
}
.to_keypair::<relay_rialto_client::Rialto>()
.map(|p| p.public())
@@ -99,6 +99,7 @@ impl RelayHeaders {
select_bridge!(self.bridge, {
let source_client = self.source.to_client::<Source>().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 metrics_params = Finality::customize_metrics(self.prometheus_params.into())?;
let finality = Finality::new(target_client.clone(), target_sign);
@@ -109,6 +110,7 @@ impl RelayHeaders {
source_client,
target_client,
self.only_mandatory_headers,
target_transactions_mortality,
metrics_params,
)
.await
@@ -188,9 +188,11 @@ impl RelayHeadersAndMessages {
let params: Params = self.into();
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_messages_pallet_owner = params.left_messages_pallet_owner.to_keypair::<Left>()?;
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_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(
left_client.clone(),
right_client.clone(),
right_transactions_mortality,
LeftToRightFinality::new(right_client.clone(), right_sign.clone()),
MAX_MISSING_LEFT_HEADERS_AT_RIGHT,
);
let right_to_left_on_demand_headers = OnDemandHeadersRelay::new(
right_client.clone(),
left_client.clone(),
left_transactions_mortality,
RightToLeftFinality::new(left_client.clone(), left_sign.clone()),
MAX_MISSING_RIGHT_HEADERS_AT_LEFT,
);
@@ -178,10 +178,11 @@ impl SendMessage {
let source_genesis_hash = *source_client.genesis_hash();
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(
source_genesis_hash,
&source_sign,
relay_substrate_client::TransactionEra::immortal(),
transaction_nonce,
send_message_call,
)