Skip to content

Commit d227963

Browse files
committed
improvement(exchange-rate): make the scale conversion after the exchange rate is applied
1 parent 449e4a6 commit d227963

File tree

1 file changed

+22
-10
lines changed

1 file changed

+22
-10
lines changed

crates/interledger-service-util/src/exchange_rates_service.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -90,32 +90,44 @@ where
9090
.build()));
9191
};
9292

93-
// Note that this is not an overflow safe operation. Given realistic
94-
// assumptions, the asset scale will be <=18 and >=1.
95-
// It is doubtful that the exchange rate between two assets,
96-
// multiplied by 18 would exceed std::f64::MAX
97-
let scaled_rate = rate.normalize_scale(ConvertDetails {
93+
// Can we overflow here?
94+
let outgoing_amount = (request.prepare.amount() as f64) * rate;
95+
let outgoing_amount = outgoing_amount.normalize_scale(ConvertDetails {
9896
from: request.from.asset_scale(),
9997
to: request.to.asset_scale(),
10098
});
10199

102-
match scaled_rate {
103-
Ok(scaled_rate) => {
104-
let outgoing_amount = (request.prepare.amount() as f64) * scaled_rate;
100+
match outgoing_amount {
101+
Ok(outgoing_amount) => {
102+
// f64 which cannot fit in u64 gets cast as 0
103+
if outgoing_amount != 0.0 && outgoing_amount as u64 == 0 {
104+
return Box::new(err(RejectBuilder {
105+
code: ErrorCode::F08_AMOUNT_TOO_LARGE,
106+
message: format!(
107+
"Could not cast outgoing amount to u64 {}",
108+
outgoing_amount,
109+
)
110+
.as_bytes(),
111+
triggered_by: Some(&self.ilp_address),
112+
data: &[],
113+
}
114+
.build()));
115+
}
105116
request.prepare.set_amount(outgoing_amount as u64);
106117
trace!("Converted incoming amount of: {} {} (scale {}) from account {} to outgoing amount of: {} {} (scale {}) for account {}",
107118
request.original_amount, request.from.asset_code(), request.from.asset_scale(), request.from.id(),
108119
outgoing_amount, request.to.asset_code(), request.to.asset_scale(), request.to.id());
109120
}
110121
Err(_) => {
111122
return Box::new(err(RejectBuilder {
112-
code: ErrorCode::F02_UNREACHABLE,
123+
code: ErrorCode::F08_AMOUNT_TOO_LARGE,
113124
message: format!(
114-
"Could not convert exchange rate from {}:{} to: {}:{}",
125+
"Could not convert exchange rate from {}:{} to: {}:{}. Got incoming amount: {}",
115126
request.from.asset_code(),
116127
request.from.asset_scale(),
117128
request.to.asset_code(),
118129
request.to.asset_scale(),
130+
request.prepare.amount(),
119131
)
120132
.as_bytes(),
121133
triggered_by: Some(&self.ilp_address),

0 commit comments

Comments
 (0)