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
This commit is contained in:
Svyatoslav Nikolsky
2022-03-04 16:03:19 +03:00
committed by Bastian Köcher
parent e822bbf8ab
commit 9b4d44bcfa
4 changed files with 79 additions and 41 deletions
@@ -15,7 +15,10 @@
// along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>. // along with Parity Bridges Common. If not, see <http://www.gnu.org/licenses/>.
use crate::{ 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, select_full_bridge,
}; };
use bp_runtime::BalanceOf; 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 // lane. So we MUST use the larger of two fees - one computed with stored fee and the one
// computed with actual fee. // computed with actual fee.
let conversion_rate_override = match ( let conversion_rate_override =
conversion_rate_override, match (conversion_rate_override, Source::TOKEN_ID, Target::TOKEN_ID) {
Source::TOKEN_ID,
Target::TOKEN_ID,
) {
(Some(ConversionRateOverride::Explicit(v)), _, _) => { (Some(ConversionRateOverride::Explicit(v)), _, _) => {
let conversion_rate_override = FixedU128::from_float(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()); log::info!(
target: "bridge",
"{} -> {} conversion rate override: {:?} (explicit)",
Target::NAME,
Source::NAME,
conversion_rate_override.to_float(),
);
Some(conversion_rate_override) Some(conversion_rate_override)
}, },
(Some(ConversionRateOverride::Metric), Some(source_token_id), Some(target_token_id)) => { (
let conversion_rate_override = FixedU128::from_float( Some(ConversionRateOverride::Metric),
tokens_conversion_rate_from_metrics(target_token_id, source_token_id).await?, 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: {:?} (from metric)", Target::NAME, Source::NAME, conversion_rate_override.to_float()); log::info!(
Some(conversion_rate_override) 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, _ => None,
}; };
Ok(std::cmp::max( let without_override = do_estimate_message_delivery_and_dispatch_fee(
do_estimate_message_delivery_and_dispatch_fee(
client, client,
estimate_fee_method, estimate_fee_method,
lane, lane,
payload.clone(), payload.clone(),
None, None,
) )
.await?, .await?;
do_estimate_message_delivery_and_dispatch_fee( let with_override = do_estimate_message_delivery_and_dispatch_fee(
client, client,
estimate_fee_method, estimate_fee_method,
lane, lane,
payload.clone(), payload.clone(),
conversion_rate_override, 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. /// Estimate message delivery and dispatch fee with given conversion rate override.
@@ -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), /// 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 /// then rational relayers may stop relaying messages because they were submitted using
/// lesser conversion rate. /// 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. /// Start headers+messages relayer process.
#[derive(StructOpt)] #[derive(StructOpt)]
@@ -190,6 +190,7 @@ impl SendMessage {
), ),
}; };
let dispatch_weight = payload.weight; let dispatch_weight = payload.weight;
let payload_len = payload.encode().len();
let send_message_call = Source::encode_call(&encode_call::Call::BridgeSendMessage { let send_message_call = Source::encode_call(&encode_call::Call::BridgeSendMessage {
bridge_instance_index: self.bridge.bridge_instance_index(), bridge_instance_index: self.bridge.bridge_instance_index(),
lane: self.lane, lane: self.lane,
@@ -230,7 +231,7 @@ impl SendMessage {
"Sending message to {}. Lane: {:?}. Size: {}. Dispatch weight: {}. Fee: {}", "Sending message to {}. Lane: {:?}. Size: {}. Dispatch weight: {}. Fee: {}",
Target::NAME, Target::NAME,
lane, lane,
signed_source_call.len(), payload_len,
dispatch_weight, dispatch_weight,
fee, fee,
); );
@@ -363,7 +363,7 @@ impl SwapTokens {
// //
if is_transfer_succeeded { 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 // prepare `claim_swap` message that will be sent over the bridge
let claim_swap_call: CallOf<Source> = let claim_swap_call: CallOf<Source> =