Skip to content

Commit 41c58dd

Browse files
svyatonikTarekkMA
authored andcommitted
Bridge: add subcommand to relay messages delivery confirmation (paritytech#4453)
related to paritytech/parity-bridges-common#2962 on top of paritytech#4383 Example: ```sh RUST_LOG=runtime=trace,rpc=trace,bridge=trace \ ./target/release/substrate-relay relay-messages-delivery-confirmation bridge-hub-rococo-to-bridge-hub-westend \ --source-host localhost \ --source-port 8943 \ --source-version-mode Auto \ --source-signer //Eve \ --source-transactions-mortality 4 \ --target-host localhost \ --target-port 8945 \ --target-version-mode Auto \ --lane 00000002 \ --at-target-block 49 ```
1 parent 95ea631 commit 41c58dd

File tree

5 files changed

+143
-9
lines changed

5 files changed

+143
-9
lines changed

bridges/relays/lib-substrate-relay/src/cli/relay_messages.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,24 @@ pub struct RelayMessagesRangeParams {
8080
target_sign: TargetSigningParams,
8181
}
8282

83+
/// Messages delivery confirmation relaying params.
84+
#[derive(StructOpt)]
85+
pub struct RelayMessagesDeliveryConfirmationParams {
86+
/// Number of the target chain header that we will use to prepare a messages
87+
/// delivery proof. This header must be previously proved to the source chain.
88+
#[structopt(long)]
89+
at_target_block: u128,
90+
/// Hex-encoded lane id that should be served by the relay. Defaults to `00000000`.
91+
#[structopt(long, default_value = "00000000")]
92+
lane: HexLaneId,
93+
#[structopt(flatten)]
94+
source: SourceConnectionParams,
95+
#[structopt(flatten)]
96+
source_sign: SourceSigningParams,
97+
#[structopt(flatten)]
98+
target: TargetConnectionParams,
99+
}
100+
83101
/// Trait used for relaying messages between 2 chains.
84102
#[async_trait]
85103
pub trait MessagesRelayer: MessagesCliBridge
@@ -154,4 +172,37 @@ where
154172
)
155173
.await
156174
}
175+
176+
/// Relay a messages delivery confirmation.
177+
async fn relay_messages_delivery_confirmation(
178+
data: RelayMessagesDeliveryConfirmationParams,
179+
) -> anyhow::Result<()> {
180+
let source_client = data.source.into_client::<Self::Source>().await?;
181+
let target_client = data.target.into_client::<Self::Target>().await?;
182+
let source_sign = data.source_sign.to_keypair::<Self::Source>()?;
183+
let source_transactions_mortality = data.source_sign.transactions_mortality()?;
184+
185+
let at_target_block = target_client
186+
.header_by_number(data.at_target_block.unique_saturated_into())
187+
.await
188+
.map_err(|e| {
189+
log::trace!(
190+
target: "bridge",
191+
"Failed to read {} header with number {}: {e:?}",
192+
Self::Target::NAME,
193+
data.at_target_block,
194+
);
195+
anyhow::format_err!("The command has failed")
196+
})?
197+
.id();
198+
199+
crate::messages_lane::relay_messages_delivery_confirmation::<Self::MessagesLane>(
200+
source_client,
201+
target_client,
202+
TransactionParams { signer: source_sign, mortality: source_transactions_mortality },
203+
at_target_block,
204+
data.lane.into(),
205+
)
206+
.await
207+
}
157208
}

bridges/relays/lib-substrate-relay/src/messages_lane.rs

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,7 @@ where
262262
source_client,
263263
params.lane_id,
264264
relayer_id_at_source,
265-
params.target_transaction_params,
265+
Some(params.target_transaction_params),
266266
params.source_to_target_headers_relay,
267267
),
268268
{
@@ -307,7 +307,7 @@ where
307307
source_client,
308308
lane_id,
309309
relayer_id_at_source,
310-
target_transaction_params,
310+
Some(target_transaction_params),
311311
None,
312312
),
313313
at_source_block,
@@ -318,6 +318,44 @@ where
318318
.map_err(|_| anyhow::format_err!("The command has failed"))
319319
}
320320

321+
/// Relay messages delivery confirmation of Substrate-to-Substrate messages.
322+
/// No checks are made to ensure that transaction will succeed.
323+
pub async fn relay_messages_delivery_confirmation<P: SubstrateMessageLane>(
324+
source_client: Client<P::SourceChain>,
325+
target_client: Client<P::TargetChain>,
326+
source_transaction_params: TransactionParams<AccountKeyPairOf<P::SourceChain>>,
327+
at_target_block: HeaderIdOf<P::TargetChain>,
328+
lane_id: LaneId,
329+
) -> anyhow::Result<()>
330+
where
331+
AccountIdOf<P::SourceChain>: From<<AccountKeyPairOf<P::SourceChain> as Pair>::Public>,
332+
AccountIdOf<P::TargetChain>: From<<AccountKeyPairOf<P::TargetChain> as Pair>::Public>,
333+
BalanceOf<P::SourceChain>: TryFrom<BalanceOf<P::TargetChain>>,
334+
{
335+
let relayer_id_at_source: AccountIdOf<P::SourceChain> =
336+
source_transaction_params.signer.public().into();
337+
messages_relay::relay_messages_delivery_confirmation(
338+
SubstrateMessagesSource::<P>::new(
339+
source_client.clone(),
340+
target_client.clone(),
341+
lane_id,
342+
source_transaction_params,
343+
None,
344+
),
345+
SubstrateMessagesTarget::<P>::new(
346+
target_client,
347+
source_client,
348+
lane_id,
349+
relayer_id_at_source,
350+
None,
351+
None,
352+
),
353+
at_target_block,
354+
)
355+
.await
356+
.map_err(|_| anyhow::format_err!("The command has failed"))
357+
}
358+
321359
/// Different ways of building `receive_messages_proof` calls.
322360
pub trait ReceiveMessagesProofCallBuilder<P: SubstrateMessageLane> {
323361
/// Given messages proof, build call of `receive_messages_proof` function of bridge

bridges/relays/lib-substrate-relay/src/messages_target.rs

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ use messages_relay::{
4040
message_lane_loop::{NoncesSubmitArtifacts, TargetClient, TargetClientState},
4141
};
4242
use relay_substrate_client::{
43-
AccountIdOf, AccountKeyPairOf, BalanceOf, CallOf, Client, Error as SubstrateError, HashOf,
44-
TransactionEra, TransactionTracker, UnsignedTransaction,
43+
AccountIdOf, AccountKeyPairOf, BalanceOf, CallOf, Chain, Client, Error as SubstrateError,
44+
HashOf, TransactionEra, TransactionTracker, UnsignedTransaction,
4545
};
4646
use relay_utils::relay_loop::Client as RelayClient;
4747
use sp_core::Pair;
@@ -57,7 +57,7 @@ pub struct SubstrateMessagesTarget<P: SubstrateMessageLane> {
5757
source_client: Client<P::SourceChain>,
5858
lane_id: LaneId,
5959
relayer_id_at_source: AccountIdOf<P::SourceChain>,
60-
transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
60+
transaction_params: Option<TransactionParams<AccountKeyPairOf<P::TargetChain>>>,
6161
source_to_target_headers_relay: Option<Arc<dyn OnDemandRelay<P::SourceChain, P::TargetChain>>>,
6262
}
6363

@@ -68,7 +68,7 @@ impl<P: SubstrateMessageLane> SubstrateMessagesTarget<P> {
6868
source_client: Client<P::SourceChain>,
6969
lane_id: LaneId,
7070
relayer_id_at_source: AccountIdOf<P::SourceChain>,
71-
transaction_params: TransactionParams<AccountKeyPairOf<P::TargetChain>>,
71+
transaction_params: Option<TransactionParams<AccountKeyPairOf<P::TargetChain>>>,
7272
source_to_target_headers_relay: Option<
7373
Arc<dyn OnDemandRelay<P::SourceChain, P::TargetChain>>,
7474
>,
@@ -249,11 +249,18 @@ where
249249
None => messages_proof_call,
250250
};
251251

252-
let transaction_params = self.transaction_params.clone();
252+
let transaction_params = self.transaction_params.clone().map(Ok).unwrap_or_else(|| {
253+
// this error shall never happen in practice, so it not deserves
254+
// a separate error variant
255+
Err(SubstrateError::Custom(format!(
256+
"Cannot sign transaction of {} chain",
257+
P::TargetChain::NAME,
258+
)))
259+
})?;
253260
let tx_tracker = self
254261
.target_client
255262
.submit_and_watch_signed_extrinsic(
256-
&self.transaction_params.signer,
263+
&transaction_params.signer,
257264
move |best_block_id, transaction_nonce| {
258265
Ok(UnsignedTransaction::new(final_call.into(), transaction_nonce)
259266
.era(TransactionEra::new(best_block_id, transaction_params.mortality)))

bridges/relays/messages/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,3 +37,4 @@ mod message_race_receiving;
3737
mod message_race_strategy;
3838

3939
pub use message_race_delivery::relay_messages_range;
40+
pub use message_race_receiving::relay_messages_delivery_confirmation;

bridges/relays/messages/src/message_race_receiving.rs

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ use crate::{
3030
use async_trait::async_trait;
3131
use bp_messages::MessageNonce;
3232
use futures::stream::FusedStream;
33-
use relay_utils::FailedClient;
33+
use relay_utils::{FailedClient, TrackedTransactionStatus, TransactionTracker};
3434
use std::{marker::PhantomData, ops::RangeInclusive};
3535

3636
/// Message receiving confirmations delivery strategy.
@@ -69,6 +69,43 @@ pub async fn run<P: MessageLane>(
6969
.await
7070
}
7171

72+
/// Relay messages delivery confirmation.
73+
pub async fn relay_messages_delivery_confirmation<P: MessageLane>(
74+
source_client: impl MessageLaneSourceClient<P>,
75+
target_client: impl MessageLaneTargetClient<P>,
76+
at: TargetHeaderIdOf<P>,
77+
) -> Result<(), ()> {
78+
// prepare messages delivery proof
79+
let (at, proof) = target_client.prove_messages_receiving(at.clone()).await.map_err(|e| {
80+
log::error!(
81+
target: "bridge",
82+
"Failed to generate messages delivery proof at {:?}: {:?}",
83+
at,
84+
e,
85+
);
86+
})?;
87+
// submit messages delivery proof to the source node
88+
let tx_tracker =
89+
source_client
90+
.submit_messages_receiving_proof(None, at, proof)
91+
.await
92+
.map_err(|e| {
93+
log::error!(
94+
target: "bridge",
95+
"Failed to submit messages delivery proof: {:?}",
96+
e,
97+
);
98+
})?;
99+
100+
match tx_tracker.wait().await {
101+
TrackedTransactionStatus::Finalized(_) => Ok(()),
102+
TrackedTransactionStatus::Lost => {
103+
log::error!("Transaction with messages delivery proof is considered lost");
104+
Err(())
105+
},
106+
}
107+
}
108+
72109
/// Messages receiving confirmations race.
73110
struct ReceivingConfirmationsRace<P>(std::marker::PhantomData<P>);
74111

0 commit comments

Comments
 (0)