diff --git a/bridges/relays/bin-substrate/src/cli/estimate_fee.rs b/bridges/relays/bin-substrate/src/cli/estimate_fee.rs
index 1f3e560fc0d03..bab625314e824 100644
--- a/bridges/relays/bin-substrate/src/cli/estimate_fee.rs
+++ b/bridges/relays/bin-substrate/src/cli/estimate_fee.rs
@@ -15,7 +15,10 @@
// along with Parity Bridges Common. If not, see .
use crate::{
- cli::{bridge::FullBridge, Balance, CliChain, HexBytes, HexLaneId, SourceConnectionParams},
+ cli::{
+ bridge::FullBridge, relay_headers_and_messages::CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO,
+ Balance, CliChain, HexBytes, HexLaneId, SourceConnectionParams,
+ },
select_full_bridge,
};
use bp_runtime::BalanceOf;
@@ -116,44 +119,78 @@ pub(crate) async fn estimate_message_delivery_and_dispatch_fee<
// lane. So we MUST use the larger of two fees - one computed with stored fee and the one
// computed with actual fee.
- let conversion_rate_override = match (
+ let conversion_rate_override =
+ match (conversion_rate_override, Source::TOKEN_ID, Target::TOKEN_ID) {
+ (Some(ConversionRateOverride::Explicit(v)), _, _) => {
+ let conversion_rate_override = FixedU128::from_float(v);
+ log::info!(
+ target: "bridge",
+ "{} -> {} conversion rate override: {:?} (explicit)",
+ Target::NAME,
+ Source::NAME,
+ conversion_rate_override.to_float(),
+ );
+ Some(conversion_rate_override)
+ },
+ (
+ Some(ConversionRateOverride::Metric),
+ Some(source_token_id),
+ Some(target_token_id),
+ ) => {
+ let conversion_rate_override =
+ tokens_conversion_rate_from_metrics(target_token_id, source_token_id).await?;
+ // So we have current actual conversion rate and rate that is stored in the runtime.
+ // And we may simply choose the maximal of these. But what if right now there's
+ // rate update transaction on the way, that is updating rate to 10 seconds old
+ // actual rate, which is bigger than the current rate? Then our message will be
+ // rejected.
+ //
+ // So let's increase the actual rate by the same value that the conversion rate
+ // updater is using.
+ let increased_conversion_rate_override = FixedU128::from_float(
+ conversion_rate_override * (1.0 + CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO),
+ );
+ log::info!(
+ target: "bridge",
+ "{} -> {} conversion rate override: {} (value from metric - {})",
+ Target::NAME,
+ Source::NAME,
+ increased_conversion_rate_override.to_float(),
+ conversion_rate_override,
+ );
+ Some(increased_conversion_rate_override)
+ },
+ _ => None,
+ };
+
+ let without_override = do_estimate_message_delivery_and_dispatch_fee(
+ client,
+ estimate_fee_method,
+ lane,
+ payload.clone(),
+ None,
+ )
+ .await?;
+ let with_override = do_estimate_message_delivery_and_dispatch_fee(
+ client,
+ estimate_fee_method,
+ lane,
+ payload.clone(),
conversion_rate_override,
- Source::TOKEN_ID,
- Target::TOKEN_ID,
- ) {
- (Some(ConversionRateOverride::Explicit(v)), _, _) => {
- let conversion_rate_override = FixedU128::from_float(v);
- log::info!(target: "bridge", "{} -> {} conversion rate override: {:?} (explicit)", Target::NAME, Source::NAME, conversion_rate_override.to_float());
- Some(conversion_rate_override)
- },
- (Some(ConversionRateOverride::Metric), Some(source_token_id), Some(target_token_id)) => {
- let conversion_rate_override = FixedU128::from_float(
- tokens_conversion_rate_from_metrics(target_token_id, source_token_id).await?,
- );
- log::info!(target: "bridge", "{} -> {} conversion rate override: {:?} (from metric)", Target::NAME, Source::NAME, conversion_rate_override.to_float());
- Some(conversion_rate_override)
- },
- _ => None,
- };
-
- Ok(std::cmp::max(
- do_estimate_message_delivery_and_dispatch_fee(
- client,
- estimate_fee_method,
- lane,
- payload.clone(),
- None,
- )
- .await?,
- do_estimate_message_delivery_and_dispatch_fee(
- client,
- estimate_fee_method,
- lane,
- payload.clone(),
- conversion_rate_override,
- )
- .await?,
- ))
+ )
+ .await?;
+ let maximal_fee = std::cmp::max(without_override, with_override);
+
+ log::info!(
+ target: "bridge",
+ "Estimated message fee: {:?} = max of {:?} (without rate override) and {:?} (with override to {:?})",
+ maximal_fee,
+ without_override,
+ with_override,
+ conversion_rate_override,
+ );
+
+ Ok(maximal_fee)
}
/// Estimate message delivery and dispatch fee with given conversion rate override.
diff --git a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs
index 86b6da39778db..9f19d82bdd405 100644
--- a/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs
+++ b/bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs
@@ -50,7 +50,7 @@ use crate::{
/// stored and real conversion rates. If it is large enough (e.g. > than 10 percents, which is 0.1),
/// then rational relayers may stop relaying messages because they were submitted using
/// lesser conversion rate.
-const CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO: f64 = 0.05;
+pub(crate) const CONVERSION_RATE_ALLOWED_DIFFERENCE_RATIO: f64 = 0.05;
/// Start headers+messages relayer process.
#[derive(StructOpt)]
diff --git a/bridges/relays/bin-substrate/src/cli/send_message.rs b/bridges/relays/bin-substrate/src/cli/send_message.rs
index b1f9ac7a42ac2..ddb1ff59b5d08 100644
--- a/bridges/relays/bin-substrate/src/cli/send_message.rs
+++ b/bridges/relays/bin-substrate/src/cli/send_message.rs
@@ -190,6 +190,7 @@ impl SendMessage {
),
};
let dispatch_weight = payload.weight;
+ let payload_len = payload.encode().len();
let send_message_call = Source::encode_call(&encode_call::Call::BridgeSendMessage {
bridge_instance_index: self.bridge.bridge_instance_index(),
lane: self.lane,
@@ -230,7 +231,7 @@ impl SendMessage {
"Sending message to {}. Lane: {:?}. Size: {}. Dispatch weight: {}. Fee: {}",
Target::NAME,
lane,
- signed_source_call.len(),
+ payload_len,
dispatch_weight,
fee,
);
diff --git a/bridges/relays/bin-substrate/src/cli/swap_tokens.rs b/bridges/relays/bin-substrate/src/cli/swap_tokens.rs
index 625e3197f809b..0758deddfd103 100644
--- a/bridges/relays/bin-substrate/src/cli/swap_tokens.rs
+++ b/bridges/relays/bin-substrate/src/cli/swap_tokens.rs
@@ -363,7 +363,7 @@ impl SwapTokens {
//
if is_transfer_succeeded {
- log::info!(target: "bridge", "Claiming the swap swap");
+ log::info!(target: "bridge", "Claiming the swap");
// prepare `claim_swap` message that will be sent over the bridge
let claim_swap_call: CallOf