diff --git a/bridges/relays/messages/src/relay_strategy/altruistic_strategy.rs b/bridges/relays/messages/src/relay_strategy/altruistic_strategy.rs index b66129117873e..7e00678e1317f 100644 --- a/bridges/relays/messages/src/relay_strategy/altruistic_strategy.rs +++ b/bridges/relays/messages/src/relay_strategy/altruistic_strategy.rs @@ -23,7 +23,7 @@ use crate::{ message_lane_loop::{ SourceClient as MessageLaneSourceClient, TargetClient as MessageLaneTargetClient, }, - relay_strategy::{RationalStrategy, RelayReference, RelayStrategy}, + relay_strategy::{RelayReference, RelayStrategy}, }; /// The relayer doesn't care about rewards. @@ -40,13 +40,20 @@ impl RelayStrategy for AltruisticStrategy { &mut self, reference: &mut RelayReference
, ) -> bool { - // we don't care about costs and rewards, but we want to report unprofitable transactions - // => let rational strategy fill required fields - let _ = RationalStrategy.decide(reference).await; + // We don't care about costs and rewards, but we want to report unprofitable transactions. + if let Err(e) = reference.update_cost_and_reward().await { + log::debug!( + target: "bridge", + "Failed to update transaction cost and reward: {:?}. \ + The `unprofitable_delivery_transactions` metric will be inaccurate", + e, + ); + } + true } - async fn final_decision< + fn on_final_decision< P: MessageLane, SourceClient: MessageLaneSourceClient
, TargetClient: MessageLaneTargetClient
, @@ -55,10 +62,11 @@ impl RelayStrategy for AltruisticStrategy { reference: &RelayReference
,
) {
if let Some(ref metrics) = reference.metrics {
- if reference.total_cost > reference.total_reward {
+ if !reference.is_profitable() {
log::debug!(
target: "bridge",
- "The relayer has submitted unprofitable {} -> {} message delivery trabsaction with {} messages: total cost = {:?}, total reward = {:?}",
+ "The relayer has submitted unprofitable {} -> {} message delivery transaction \
+ with {} messages: total cost = {:?}, total reward = {:?}",
P::SOURCE_NAME,
P::TARGET_NAME,
reference.index + 1,
diff --git a/bridges/relays/messages/src/relay_strategy/enforcement_strategy.rs b/bridges/relays/messages/src/relay_strategy/enforcement_strategy.rs
index 5d231462e86d9..bb4192d45ab05 100644
--- a/bridges/relays/messages/src/relay_strategy/enforcement_strategy.rs
+++ b/bridges/relays/messages/src/relay_strategy/enforcement_strategy.rs
@@ -214,7 +214,7 @@ impl ,
TargetClient: MessageLaneTargetClient ,
@@ -65,8 +65,8 @@ impl RelayStrategy for MixStrategy {
reference: &RelayReference ,
) {
match self.relayer_mode {
- RelayerMode::Altruistic => AltruisticStrategy.final_decision(reference).await,
- RelayerMode::Rational => RationalStrategy.final_decision(reference).await,
+ RelayerMode::Altruistic => AltruisticStrategy.on_final_decision(reference),
+ RelayerMode::Rational => RationalStrategy.on_final_decision(reference),
}
}
}
diff --git a/bridges/relays/messages/src/relay_strategy/mod.rs b/bridges/relays/messages/src/relay_strategy/mod.rs
index da615f34e8659..7bfd74c4790f8 100644
--- a/bridges/relays/messages/src/relay_strategy/mod.rs
+++ b/bridges/relays/messages/src/relay_strategy/mod.rs
@@ -18,6 +18,7 @@
use async_trait::async_trait;
use bp_messages::{MessageNonce, Weight};
+use sp_arithmetic::traits::Saturating;
use std::ops::Range;
use crate::{
@@ -56,7 +57,7 @@ pub trait RelayStrategy: 'static + Clone + Send + Sync {
) -> bool;
/// Notification that the following maximal nonce has been selected for the delivery.
- async fn final_decision<
+ fn on_final_decision<
P: MessageLane,
SourceClient: MessageLaneSourceClient ,
TargetClient: MessageLaneTargetClient ,
@@ -66,6 +67,14 @@ pub trait RelayStrategy: 'static + Clone + Send + Sync {
);
}
+/// Total cost of mesage delivery and confirmation.
+struct MessagesDeliveryCost ,
+ TargetClient: MessageLaneTargetClient ,
+ > RelayReference
+{
+ /// Returns whether the current `RelayReference` is profitable.
+ pub fn is_profitable(&self) -> bool {
+ self.total_reward >= self.total_cost
+ }
+
+ async fn estimate_messages_delivery_cost(
+ &self,
+ ) -> Result ,
) -> bool {
- let total_cost = match estimate_messages_delivery_cost(reference).await {
- Ok(total_cost) => total_cost,
- Err(err) => {
- log::debug!(
- target: "bridge",
- "Failed to estimate delivery transaction cost: {:?}. No nonces selected for delivery",
- err,
- );
-
- return false
- },
- };
-
- // if it is the first message that makes reward less than cost, let's log it
- // if this message makes batch profitable again, let's log it
- let MessagesDeliveryCost { confirmation_transaction_cost, delivery_transaction_cost } =
- total_cost;
- let is_total_reward_less_than_cost = reference.total_reward < reference.total_cost;
- let prev_total_cost = reference.total_cost;
- let prev_total_reward = reference.total_reward;
- reference.total_confirmations_cost = reference
- .total_confirmations_cost
- .saturating_add(&confirmation_transaction_cost);
- reference.total_reward = reference.total_reward.saturating_add(&reference.details.reward);
- reference.total_cost =
- reference.total_confirmations_cost.saturating_add(&delivery_transaction_cost);
- if !is_total_reward_less_than_cost && reference.total_reward < reference.total_cost {
+ if let Err(e) = reference.update_cost_and_reward().await {
log::debug!(
target: "bridge",
- "Message with nonce {} (reward = {:?}) changes total cost {:?}->{:?} and makes it larger than \
- total reward {:?}->{:?}",
- reference.nonce,
- reference.details.reward,
- prev_total_cost,
- reference.total_cost,
- prev_total_reward,
- reference.total_reward,
- );
- } else if is_total_reward_less_than_cost && reference.total_reward >= reference.total_cost {
- log::debug!(
- target: "bridge",
- "Message with nonce {} (reward = {:?}) changes total cost {:?}->{:?} and makes it less than or \
- equal to the total reward {:?}->{:?} (again)",
- reference.nonce,
- reference.details.reward,
- prev_total_cost,
- reference.total_cost,
- prev_total_reward,
- reference.total_reward,
+ "Failed to update transaction cost and reward: {:?}. No nonces selected for delivery",
+ e,
);
+
+ return false
}
- // Rational relayer never want to lose his funds
- if reference.total_reward >= reference.total_cost {
+ // Rational relayer never wants to lose his funds.
+ if reference.is_profitable() {
reference.selected_reward = reference.total_reward;
reference.selected_cost = reference.total_cost;
return true
@@ -106,7 +61,7 @@ impl RelayStrategy for RationalStrategy {
false
}
- async fn final_decision<
+ fn on_final_decision<
P: MessageLane,
SourceClient: MessageLaneSourceClient ,
TargetClient: MessageLaneTargetClient ,
@@ -118,40 +73,3 @@ impl RelayStrategy for RationalStrategy {
// anything here
}
}
-
-/// Total cost of mesage delivery and confirmation.
-struct MessagesDeliveryCost ,
- TargetClient: MessageLaneTargetClient ,
->(
- reference: &RelayReference ,
-) -> Result