diff --git a/core/src/main/java/haveno/core/trade/HavenoUtils.java b/core/src/main/java/haveno/core/trade/HavenoUtils.java index fcd5c556e1..d238d78843 100644 --- a/core/src/main/java/haveno/core/trade/HavenoUtils.java +++ b/core/src/main/java/haveno/core/trade/HavenoUtils.java @@ -71,6 +71,7 @@ import javax.sound.sampled.SourceDataLine; import lombok.extern.slf4j.Slf4j; import monero.common.MoneroRpcConnection; +import monero.common.MoneroUtils; import monero.daemon.model.MoneroOutput; import monero.wallet.model.MoneroDestination; import monero.wallet.model.MoneroTxWallet; @@ -204,11 +205,11 @@ public class HavenoUtils { } public static double atomicUnitsToXmr(BigInteger atomicUnits) { - return new BigDecimal(atomicUnits).divide(new BigDecimal(XMR_AU_MULTIPLIER)).doubleValue(); + return MoneroUtils.atomicUnitsToXmr(atomicUnits); } public static BigInteger xmrToAtomicUnits(double xmr) { - return new BigDecimal(xmr).multiply(new BigDecimal(XMR_AU_MULTIPLIER)).toBigInteger(); + return MoneroUtils.xmrToAtomicUnits(xmr); } public static long xmrToCentineros(double xmr) { @@ -220,11 +221,11 @@ public class HavenoUtils { } public static double divide(BigInteger auDividend, BigInteger auDivisor) { - return atomicUnitsToXmr(auDividend) / atomicUnitsToXmr(auDivisor); + return MoneroUtils.divide(auDividend, auDivisor); } public static BigInteger multiply(BigInteger amount1, double amount2) { - return amount1 == null ? null : new BigDecimal(amount1).multiply(BigDecimal.valueOf(amount2)).toBigInteger(); + return MoneroUtils.multiply(amount1, amount2); } // ------------------------- FORMAT UTILS --------------------------------- diff --git a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java index 4c45907720..8432da2aed 100644 --- a/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java +++ b/core/src/main/java/haveno/core/xmr/wallet/XmrWalletService.java @@ -781,11 +781,23 @@ public class XmrWalletService extends XmrWalletBase { BigInteger actualSendAmount = transferCheck.getReceivedAmount(); // verify trade fee amount - if (!actualTradeFee.equals(tradeFeeAmount)) throw new RuntimeException("Invalid trade fee amount, expected " + tradeFeeAmount + " but was " + actualTradeFee); + if (!actualTradeFee.equals(tradeFeeAmount)) { + if (equalsWithinFractionError(actualTradeFee, tradeFeeAmount)) { + log.warn("Trade tx fee amount is within fraction error, expected " + tradeFeeAmount + " but was " + actualTradeFee); + } else { + throw new RuntimeException("Invalid trade fee amount, expected " + tradeFeeAmount + " but was " + actualTradeFee); + } + } // verify send amount BigInteger expectedSendAmount = sendAmount.subtract(tx.getFee()); - if (!actualSendAmount.equals(expectedSendAmount)) throw new RuntimeException("Invalid send amount, expected " + expectedSendAmount + " but was " + actualSendAmount + " with tx fee " + tx.getFee()); + if (!actualSendAmount.equals(expectedSendAmount)) { + if (equalsWithinFractionError(actualSendAmount, expectedSendAmount)) { + log.warn("Trade tx send amount is within fraction error, expected " + expectedSendAmount + " but was " + actualSendAmount + " with tx fee " + tx.getFee()); + } else { + throw new RuntimeException("Invalid send amount, expected " + expectedSendAmount + " but was " + actualSendAmount + " with tx fee " + tx.getFee()); + } + } return tx; } catch (Exception e) { log.warn("Error verifying trade tx with offer id=" + offerId + (tx == null ? "" : ", tx=\n" + tx) + ": " + e.getMessage()); @@ -801,6 +813,11 @@ public class XmrWalletService extends XmrWalletBase { } } + // TODO: old bug in atomic unit conversion could cause fractional difference error, remove this in future release, maybe re-sign all offers then + private static boolean equalsWithinFractionError(BigInteger a, BigInteger b) { + return a.subtract(b).abs().compareTo(new BigInteger("1")) <= 0; + } + /** * Get the tx fee estimate based on its weight. *