Skip to content

Commit

Permalink
fix(actuators): mimic Math.pow precision in java8
Browse files Browse the repository at this point in the history
Fix #36
  • Loading branch information
andelf committed Oct 29, 2020
1 parent 72dc899 commit 6e6d957
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 5 deletions.
1 change: 1 addition & 0 deletions opentron/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#![recursion_limit = "2048"]
#![feature(asm)]

pub mod channel;
pub mod commands;
Expand Down
35 changes: 30 additions & 5 deletions opentron/src/manager/executor/actuators/exchange.rs
Original file line number Diff line number Diff line change
Expand Up @@ -508,22 +508,21 @@ impl BuiltinContractExecutorExt for contract_pb::ExchangeTransactionContract {
}

// NOTE: Sell and buy are different tokens.
// exchange(long sellTokenBalance, long buyTokenBalance, long sellTokenQuant)
/// Returns: buy token amount(buyTokenQuant).
fn exchange(mut supply: i64, sell_balance: i64, buy_balance: i64, sell_amount: i64) -> i64 {
// exchangeToSupply(sellTokenBalance, sellTokenQuant)
log::trace!("balance: {}", sell_balance);
let new_balance = (sell_balance + sell_amount) as f64;
let new_balance = sell_balance + sell_amount;

let issued_supply = -supply as f64 * (1.0 - (1.0 + sell_amount as f64 / new_balance).powf(0.0005));
log::trace!("issued supply: {}", issued_supply);
let issued_supply = -supply as f64 * (1.0 - java8_math_pow(1.0 + sell_amount as f64 / new_balance as f64, 0.0005));

let relay = issued_supply as i64;
supply += relay;

// exchangeFromSupply(buyTokenBalance, relay)
supply -= relay;
// NOTE: OK to use Rust `f64::powf`, for X > 1.
let exchange_balance = buy_balance as f64 * ((1.0 + relay as f64 / supply as f64).powf(2000.0) - 1.0);
log::trace!("exchange balance: {}", exchange_balance);

exchange_balance as i64
}
Expand All @@ -541,3 +540,29 @@ fn get_exchange_token_id(manager: &Manager, token_id: &str) -> Result<i64, Strin
.ok_or_else(|| "invalid token name".into())
}
}

/// Java8 version of `Math.pow()` under x86.
///
/// See-also: https://github.com/opentron/opentron/issues/36
///
/// NOTE: This is a partial implementation, only operates on -1<=X<=1.
#[inline]
fn java8_math_pow(x: f64, y: f64) -> f64 {
let mut ret = 0_f64;
unsafe {
asm!(
"fld qword ptr [{y}]",
"fld qword ptr [{x}]",
"fyl2x",
"f2xm1",
"fld1",
"faddp st(1), st(0)",
"fstp qword ptr [{v}]",
x = in(reg) &x,
y = in(reg) &y,
v = in(reg) &mut ret,
options(nostack)
);
}
ret
}

0 comments on commit 6e6d957

Please sign in to comment.