Skip to content

Commit e822bbf

Browse files
svyatonikbkchr
authored andcommitted
fixed mess with conversion rates (#1338)
1 parent dd7404f commit e822bbf

File tree

5 files changed

+99
-49
lines changed

5 files changed

+99
-49
lines changed

bridges/relays/bin-substrate/src/cli/estimate_fee.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use relay_substrate_client::Chain;
2424
use sp_runtime::FixedU128;
2525
use structopt::StructOpt;
2626
use strum::VariantNames;
27-
use substrate_relay_helper::helpers::target_to_source_conversion_rate;
27+
use substrate_relay_helper::helpers::tokens_conversion_rate_from_metrics;
2828

2929
/// Estimate Delivery & Dispatch Fee command.
3030
#[derive(StructOpt, Debug, PartialEq)]
@@ -98,6 +98,8 @@ impl EstimateFee {
9898
}
9999
}
100100

101+
/// The caller may provide target to source tokens conversion rate override to use in fee
102+
/// computation.
101103
pub(crate) async fn estimate_message_delivery_and_dispatch_fee<
102104
Source: Chain,
103105
Target: Chain,
@@ -121,14 +123,14 @@ pub(crate) async fn estimate_message_delivery_and_dispatch_fee<
121123
) {
122124
(Some(ConversionRateOverride::Explicit(v)), _, _) => {
123125
let conversion_rate_override = FixedU128::from_float(v);
124-
log::info!(target: "bridge", "Conversion rate override: {:?} (explicit)", conversion_rate_override.to_float());
126+
log::info!(target: "bridge", "{} -> {} conversion rate override: {:?} (explicit)", Target::NAME, Source::NAME, conversion_rate_override.to_float());
125127
Some(conversion_rate_override)
126128
},
127129
(Some(ConversionRateOverride::Metric), Some(source_token_id), Some(target_token_id)) => {
128130
let conversion_rate_override = FixedU128::from_float(
129-
target_to_source_conversion_rate(source_token_id, target_token_id).await?,
131+
tokens_conversion_rate_from_metrics(target_token_id, source_token_id).await?,
130132
);
131-
log::info!(target: "bridge", "Conversion rate override: {:?} (from metric)", conversion_rate_override.to_float());
133+
log::info!(target: "bridge", "{} -> {} conversion rate override: {:?} (from metric)", Target::NAME, Source::NAME, conversion_rate_override.to_float());
132134
Some(conversion_rate_override)
133135
},
134136
_ => None,

bridges/relays/bin-substrate/src/cli/relay_headers_and_messages.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -403,13 +403,13 @@ impl RelayHeadersAndMessages {
403403
.as_ref()
404404
.ok_or_else(format_err)?
405405
.shared_value_ref(),
406-
left_to_right_metrics
407-
.source_to_base_conversion_rate
406+
right_to_left_metrics
407+
.target_to_base_conversion_rate
408408
.as_ref()
409409
.ok_or_else(format_err)?
410410
.shared_value_ref(),
411-
left_to_right_metrics
412-
.target_to_base_conversion_rate
411+
right_to_left_metrics
412+
.source_to_base_conversion_rate
413413
.as_ref()
414414
.ok_or_else(format_err)?
415415
.shared_value_ref(),

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

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ async fn maybe_select_new_conversion_rate(
106106
let left_to_base_conversion_rate = (*left_to_base_conversion_rate.read().await)?;
107107
let right_to_base_conversion_rate = (*right_to_base_conversion_rate.read().await)?;
108108
let actual_left_to_right_conversion_rate =
109-
right_to_base_conversion_rate / left_to_base_conversion_rate;
109+
left_to_base_conversion_rate / right_to_base_conversion_rate;
110110

111111
let rate_difference =
112112
(actual_left_to_right_conversion_rate - left_to_right_stored_conversion_rate).abs();
@@ -229,15 +229,27 @@ mod tests {
229229

230230
#[test]
231231
fn transaction_is_submitted_when_difference_is_above_threshold() {
232+
let left_to_right_stored_conversion_rate = 1.0;
233+
let left_to_base_conversion_rate = 18f64;
234+
let right_to_base_conversion_rate = 180f64;
235+
236+
assert!(left_to_base_conversion_rate < right_to_base_conversion_rate);
237+
232238
assert_eq!(
233239
test_maybe_select_new_conversion_rate(
234240
TransactionStatus::Idle,
235-
Some(1.0),
236-
Some(1.0),
237-
Some(1.03),
241+
Some(left_to_right_stored_conversion_rate),
242+
Some(left_to_base_conversion_rate),
243+
Some(right_to_base_conversion_rate),
238244
0.02
239245
),
240-
(Some((1.0, 1.03)), TransactionStatus::Idle),
246+
(
247+
Some((
248+
left_to_right_stored_conversion_rate,
249+
left_to_base_conversion_rate / right_to_base_conversion_rate,
250+
)),
251+
TransactionStatus::Idle
252+
),
241253
);
242254
}
243255
}

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

Lines changed: 66 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -29,26 +29,78 @@ pub fn token_price_metric(token_id: &str) -> Result<FloatJsonValueMetric, Promet
2929
}
3030

3131
/// Compute conversion rate between two tokens immediately, without spawning any metrics.
32-
pub async fn target_to_source_conversion_rate(
33-
source_token_id: &str,
34-
target_token_id: &str,
32+
///
33+
/// Returned rate may be used in expression: `from_tokens * rate -> to_tokens`.
34+
pub async fn tokens_conversion_rate_from_metrics(
35+
from_token_id: &str,
36+
to_token_id: &str,
3537
) -> anyhow::Result<f64> {
36-
let source_token_metric = token_price_metric(source_token_id)?;
37-
source_token_metric.update().await;
38-
let target_token_metric = token_price_metric(target_token_id)?;
39-
target_token_metric.update().await;
38+
let from_token_metric = token_price_metric(from_token_id)?;
39+
from_token_metric.update().await;
40+
let to_token_metric = token_price_metric(to_token_id)?;
41+
to_token_metric.update().await;
4042

41-
let source_token_value = *source_token_metric.shared_value_ref().read().await;
42-
let target_token_value = *target_token_metric.shared_value_ref().read().await;
43+
let from_token_value = *from_token_metric.shared_value_ref().read().await;
44+
let to_token_value = *to_token_metric.shared_value_ref().read().await;
4345
// `FloatJsonValueMetric` guarantees that the value is positive && normal, so no additional
4446
// checks required here
45-
match (source_token_value, target_token_value) {
46-
(Some(source_token_value), Some(target_token_value)) =>
47-
Ok(target_token_value / source_token_value),
47+
match (from_token_value, to_token_value) {
48+
(Some(from_token_value), Some(to_token_value)) =>
49+
Ok(tokens_conversion_rate(from_token_value, to_token_value)),
4850
_ => Err(anyhow::format_err!(
4951
"Failed to compute conversion rate from {} to {}",
50-
target_token_id,
51-
source_token_id,
52+
from_token_id,
53+
to_token_id,
5254
)),
5355
}
5456
}
57+
58+
/// Compute conversion rate between two tokens, given token prices.
59+
///
60+
/// Returned rate may be used in expression: `from_tokens * rate -> to_tokens`.
61+
///
62+
/// Both prices are assumed to be normal and non-negative.
63+
pub fn tokens_conversion_rate(from_token_value: f64, to_token_value: f64) -> f64 {
64+
from_token_value / to_token_value
65+
}
66+
67+
#[cfg(test)]
68+
mod tests {
69+
use super::*;
70+
71+
#[test]
72+
fn rialto_to_millau_conversion_rate_is_correct() {
73+
let rialto_price = 18.18;
74+
let millau_price = 136.35;
75+
assert!(rialto_price < millau_price);
76+
77+
let conversion_rate = tokens_conversion_rate(rialto_price, millau_price);
78+
let rialto_amount = 100.0;
79+
let millau_amount = rialto_amount * conversion_rate;
80+
assert!(
81+
rialto_amount > millau_amount,
82+
"{} RLT * {} = {} MLU",
83+
rialto_amount,
84+
conversion_rate,
85+
millau_amount,
86+
);
87+
}
88+
89+
#[test]
90+
fn millau_to_rialto_conversion_rate_is_correct() {
91+
let rialto_price = 18.18;
92+
let millau_price = 136.35;
93+
assert!(rialto_price < millau_price);
94+
95+
let conversion_rate = tokens_conversion_rate(millau_price, rialto_price);
96+
let millau_amount = 100.0;
97+
let rialto_amount = millau_amount * conversion_rate;
98+
assert!(
99+
rialto_amount > millau_amount,
100+
"{} MLU * {} = {} RLT",
101+
millau_amount,
102+
conversion_rate,
103+
rialto_amount,
104+
);
105+
}
106+
}

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

Lines changed: 6 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616

1717
//! Tools for supporting message lanes between two Substrate-based chains.
1818
19-
use crate::messages_lane::SubstrateMessageLane;
19+
use crate::{helpers::tokens_conversion_rate, messages_lane::SubstrateMessageLane};
2020

2121
use codec::Decode;
2222
use frame_system::AccountInfo;
@@ -119,19 +119,11 @@ impl<SC: Chain, TC: Chain> StandaloneMessagesMetrics<SC, TC> {
119119

120120
/// Return conversion rate from target to source tokens.
121121
pub async fn target_to_source_conversion_rate(&self) -> Option<f64> {
122-
Self::compute_target_to_source_conversion_rate(
123-
*self.target_to_base_conversion_rate.as_ref()?.shared_value_ref().read().await,
124-
*self.source_to_base_conversion_rate.as_ref()?.shared_value_ref().read().await,
125-
)
126-
}
127-
128-
/// Return conversion rate from target to source tokens, given conversion rates from
129-
/// target/source tokens to some base token.
130-
fn compute_target_to_source_conversion_rate(
131-
target_to_base_conversion_rate: Option<f64>,
132-
source_to_base_conversion_rate: Option<f64>,
133-
) -> Option<f64> {
134-
Some(source_to_base_conversion_rate? / target_to_base_conversion_rate?)
122+
let from_token_value =
123+
(*self.target_to_base_conversion_rate.as_ref()?.shared_value_ref().read().await)?;
124+
let to_token_value =
125+
(*self.source_to_base_conversion_rate.as_ref()?.shared_value_ref().read().await)?;
126+
Some(tokens_conversion_rate(from_token_value, to_token_value))
135127
}
136128
}
137129

@@ -379,14 +371,6 @@ mod tests {
379371
use frame_support::storage::generator::StorageValue;
380372
use sp_core::storage::StorageKey;
381373

382-
#[async_std::test]
383-
async fn target_to_source_conversion_rate_works() {
384-
assert_eq!(
385-
StandaloneMessagesMetrics::<relay_rococo_client::Rococo, relay_wococo_client::Wococo>::compute_target_to_source_conversion_rate(Some(183.15), Some(12.32)),
386-
Some(12.32 / 183.15),
387-
);
388-
}
389-
390374
#[test]
391375
fn token_decimals_used_properly() {
392376
let plancks = 425_000_000_000;

0 commit comments

Comments
 (0)