From ed1d278f30b5703b71b93d7c93dee8c01b6f2393 Mon Sep 17 00:00:00 2001 From: Svyatoslav Nikolsky Date: Fri, 4 Mar 2022 16:03:19 +0300 Subject: [PATCH] Increase rate from metric when estimating fee (#1340) * ignore errors when dumping logs and container is missing * fixed typo * print correct payload length * increase conversion rate a bit when estimating fee (to avoid message rejects when rate update tx is active) * fmt --- .../bin-substrate/src/cli/estimate_fee.rs | 113 ++++++++++++------ .../src/cli/relay_headers_and_messages.rs | 2 +- .../bin-substrate/src/cli/send_message.rs | 3 +- .../bin-substrate/src/cli/swap_tokens.rs | 2 +- 4 files changed, 79 insertions(+), 41 deletions(-) diff --git a/bridges/relays/bin-substrate/src/cli/estimate_fee.rs b/bridges/relays/bin-substrate/src/cli/estimate_fee.rs index 1f3e560fc0d0..bab625314e82 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 86b6da39778d..9f19d82bdd40 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 b1f9ac7a42ac..ddb1ff59b5d0 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 625e3197f809..0758deddfd10 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 =