transition Balances to use native xmr atomic units

This commit is contained in:
woodser 2023-03-06 19:38:57 -05:00
parent 74cd910705
commit ab0b9e3b77
5 changed files with 24 additions and 63 deletions

View file

@ -133,16 +133,14 @@ class CoreWalletsService {
verifyWalletCurrencyCodeIsValid(currencyCode); verifyWalletCurrencyCodeIsValid(currencyCode);
verifyWalletsAreAvailable(); verifyWalletsAreAvailable();
verifyEncryptedWalletIsUnlocked(); verifyEncryptedWalletIsUnlocked();
if (balances.getAvailableBalance().get() == null) if (balances.getAvailableBalance().get() == null) throw new IllegalStateException("balance is not yet available");
throw new IllegalStateException("balance is not yet available");
switch (currencyCode.trim().toUpperCase()) { switch (currencyCode.trim().toUpperCase()) {
case "BTC": case "":
return new BalancesInfo(getBtcBalances(), XmrBalanceInfo.EMPTY);
case "XMR": case "XMR":
return new BalancesInfo(BtcBalanceInfo.EMPTY, getXmrBalances()); return new BalancesInfo(BtcBalanceInfo.EMPTY, getXmrBalances());
default: default:
return new BalancesInfo(getBtcBalances(), getXmrBalances()); throw new IllegalStateException("Unsupported currency code: " + currencyCode.trim().toUpperCase());
} }
} }
@ -472,30 +470,6 @@ class CoreWalletsService {
} }
} }
// TODO (woodser): delete this since it's serving XMR balances
private BtcBalanceInfo getBtcBalances() {
verifyWalletsAreAvailable();
verifyEncryptedWalletIsUnlocked();
var availableBalance = balances.getAvailableBalance().get();
if (availableBalance == null)
throw new IllegalStateException("balance is not yet available");
var reservedBalance = balances.getReservedBalance().get();
if (reservedBalance == null)
throw new IllegalStateException("reserved balance is not yet available");
var pendingBalance = balances.getPendingBalance().get();
if (pendingBalance == null)
throw new IllegalStateException("locked balance is not yet available");
return new BtcBalanceInfo(availableBalance.value,
reservedBalance.value,
availableBalance.add(reservedBalance).value,
pendingBalance.value);
}
private XmrBalanceInfo getXmrBalances() { private XmrBalanceInfo getXmrBalances() {
verifyWalletsAreAvailable(); verifyWalletsAreAvailable();
verifyEncryptedWalletIsUnlocked(); verifyEncryptedWalletIsUnlocked();

View file

@ -25,7 +25,6 @@ import bisq.core.offer.OpenOfferManager;
import bisq.core.support.dispute.Dispute; import bisq.core.support.dispute.Dispute;
import bisq.core.support.dispute.refund.RefundManager; import bisq.core.support.dispute.refund.RefundManager;
import bisq.core.trade.ClosedTradableManager; import bisq.core.trade.ClosedTradableManager;
import bisq.core.trade.HavenoUtils;
import bisq.core.trade.Trade; import bisq.core.trade.Trade;
import bisq.core.trade.TradeManager; import bisq.core.trade.TradeManager;
import bisq.core.trade.failed.FailedTradesManager; import bisq.core.trade.failed.FailedTradesManager;
@ -43,7 +42,6 @@ import monero.common.MoneroError;
import monero.wallet.model.MoneroOutputQuery; import monero.wallet.model.MoneroOutputQuery;
import monero.wallet.model.MoneroOutputWallet; import monero.wallet.model.MoneroOutputWallet;
import monero.wallet.model.MoneroTxWallet; import monero.wallet.model.MoneroTxWallet;
import org.bitcoinj.core.Coin;
@Slf4j @Slf4j
public class Balances { public class Balances {
@ -53,15 +51,15 @@ public class Balances {
private final RefundManager refundManager; private final RefundManager refundManager;
@Getter @Getter
private final ObjectProperty<Coin> availableBalance = new SimpleObjectProperty<>(); private final ObjectProperty<BigInteger> availableBalance = new SimpleObjectProperty<>();
@Getter @Getter
private final ObjectProperty<Coin> pendingBalance = new SimpleObjectProperty<>(); private final ObjectProperty<BigInteger> pendingBalance = new SimpleObjectProperty<>();
@Getter @Getter
private final ObjectProperty<Coin> reservedOfferBalance = new SimpleObjectProperty<>(); private final ObjectProperty<BigInteger> reservedOfferBalance = new SimpleObjectProperty<>();
@Getter @Getter
private final ObjectProperty<Coin> reservedTradeBalance = new SimpleObjectProperty<>(); private final ObjectProperty<BigInteger> reservedTradeBalance = new SimpleObjectProperty<>();
@Getter @Getter
private final ObjectProperty<Coin> reservedBalance = new SimpleObjectProperty<>(); // TODO (woodser): this balance is sum of reserved funds for offers and trade multisigs; remove? private final ObjectProperty<BigInteger> reservedBalance = new SimpleObjectProperty<>(); // TODO (woodser): this balance is sum of reserved funds for offers and trade multisigs; remove?
@Inject @Inject
public Balances(TradeManager tradeManager, public Balances(TradeManager tradeManager,
@ -105,26 +103,26 @@ public class Balances {
// TODO (woodser): converting to long should generally be avoided since can lose precision, but in practice these amounts are below max value // TODO (woodser): converting to long should generally be avoided since can lose precision, but in practice these amounts are below max value
private void updateAvailableBalance() { private void updateAvailableBalance() {
availableBalance.set(Coin.valueOf(xmrWalletService.getWallet() == null ? 0 : xmrWalletService.getWallet().getUnlockedBalance(0).longValueExact())); availableBalance.set(xmrWalletService.getWallet() == null ? BigInteger.valueOf(0) : xmrWalletService.getWallet().getUnlockedBalance(0));
} }
private void updatePendingBalance() { private void updatePendingBalance() {
BigInteger balance = xmrWalletService.getWallet() == null ? new BigInteger("0") : xmrWalletService.getWallet().getBalance(0); BigInteger balance = xmrWalletService.getWallet() == null ? BigInteger.valueOf(0) : xmrWalletService.getWallet().getBalance(0);
BigInteger unlockedBalance = xmrWalletService.getWallet() == null ? new BigInteger("0") : xmrWalletService.getWallet().getUnlockedBalance(0); BigInteger unlockedBalance = xmrWalletService.getWallet() == null ? BigInteger.valueOf(0) : xmrWalletService.getWallet().getUnlockedBalance(0);
pendingBalance.set(Coin.valueOf(balance.subtract(unlockedBalance).longValueExact())); pendingBalance.set(balance.subtract(unlockedBalance));
} }
private void updateReservedOfferBalance() { private void updateReservedOfferBalance() {
Coin sum = Coin.valueOf(0); BigInteger sum = BigInteger.valueOf(0);
if (xmrWalletService.getWallet() != null) { if (xmrWalletService.getWallet() != null) {
List<MoneroOutputWallet> frozenOutputs = xmrWalletService.getWallet().getOutputs(new MoneroOutputQuery().setIsFrozen(true).setIsSpent(false)); List<MoneroOutputWallet> frozenOutputs = xmrWalletService.getWallet().getOutputs(new MoneroOutputQuery().setIsFrozen(true).setIsSpent(false));
for (MoneroOutputWallet frozenOutput : frozenOutputs) sum = sum.add(Coin.valueOf(frozenOutput.getAmount().longValueExact())); for (MoneroOutputWallet frozenOutput : frozenOutputs) sum = sum.add(frozenOutput.getAmount());
} }
reservedOfferBalance.set(sum); reservedOfferBalance.set(sum);
} }
private void updateReservedTradeBalance() { private void updateReservedTradeBalance() {
Coin sum = Coin.valueOf(0); BigInteger sum = BigInteger.valueOf(0);
List<Trade> openTrades = tradeManager.getTradesStreamWithFundsLockedIn().collect(Collectors.toList()); List<Trade> openTrades = tradeManager.getTradesStreamWithFundsLockedIn().collect(Collectors.toList());
for (Trade trade : openTrades) { for (Trade trade : openTrades) {
try { try {
@ -141,7 +139,7 @@ public class Balances {
} else { } else {
reservedAmt = trade.getContract().isMyRoleBuyer(tradeManager.getKeyRing().getPubKeyRing()) ? offerPayload.getBuyerSecurityDeposit() : offerPayload.getAmount() + offerPayload.getSellerSecurityDeposit(); reservedAmt = trade.getContract().isMyRoleBuyer(tradeManager.getKeyRing().getPubKeyRing()) ? offerPayload.getBuyerSecurityDeposit() : offerPayload.getAmount() + offerPayload.getSellerSecurityDeposit();
} }
sum = sum.add(Coin.valueOf(HavenoUtils.centinerosToAtomicUnits(reservedAmt).longValueExact())); sum = sum.add(BigInteger.valueOf(reservedAmt));
} }
reservedTradeBalance.set(sum); reservedTradeBalance.set(sum);
} }

View file

@ -831,7 +831,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
// get earliest unscheduled txs with sufficient incoming amount // get earliest unscheduled txs with sufficient incoming amount
List<String> scheduledTxHashes = new ArrayList<String>(); List<String> scheduledTxHashes = new ArrayList<String>();
BigInteger scheduledAmount = new BigInteger("0"); BigInteger scheduledAmount = BigInteger.valueOf(0);
for (MoneroTxWallet lockedTx : lockedTxs) { for (MoneroTxWallet lockedTx : lockedTxs) {
if (isTxScheduled(openOffers, lockedTx.getHash())) continue; if (isTxScheduled(openOffers, lockedTx.getHash())) continue;
if (lockedTx.getIncomingTransfers() == null || lockedTx.getIncomingTransfers().isEmpty()) continue; if (lockedTx.getIncomingTransfers() == null || lockedTx.getIncomingTransfers().isEmpty()) continue;
@ -859,7 +859,7 @@ public class OpenOfferManager implements PeerManager.Listener, DecryptedDirectMe
} }
private BigInteger getScheduledAmount(List<OpenOffer> openOffers) { private BigInteger getScheduledAmount(List<OpenOffer> openOffers) {
BigInteger scheduledAmount = new BigInteger("0"); BigInteger scheduledAmount = BigInteger.valueOf(0);
for (OpenOffer openOffer : openOffers) { for (OpenOffer openOffer : openOffers) {
if (openOffer.getState() != OpenOffer.State.SCHEDULED) continue; if (openOffer.getState() != OpenOffer.State.SCHEDULED) continue;
if (openOffer.getScheduledTxHashes() == null) continue; if (openOffer.getScheduledTxHashes() == null) continue;

View file

@ -19,20 +19,18 @@ package bisq.core.presentation;
import bisq.common.UserThread; import bisq.common.UserThread;
import bisq.core.btc.Balances; import bisq.core.btc.Balances;
import bisq.core.trade.HavenoUtils;
import javax.inject.Inject; import javax.inject.Inject;
import javafx.beans.property.SimpleStringProperty; import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty; import javafx.beans.property.StringProperty;
import java.math.BigInteger;
import lombok.Getter; import lombok.Getter;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
@Slf4j @Slf4j
public class BalancePresentation { public class BalancePresentation {
private static final BigInteger AU_PER_XMR = new BigInteger("1000000000000");
@Getter @Getter
private final StringProperty availableBalance = new SimpleStringProperty(); private final StringProperty availableBalance = new SimpleStringProperty();
@ -44,22 +42,13 @@ public class BalancePresentation {
@Inject @Inject
public BalancePresentation(Balances balances) { public BalancePresentation(Balances balances) {
balances.getAvailableBalance().addListener((observable, oldValue, newValue) -> { balances.getAvailableBalance().addListener((observable, oldValue, newValue) -> {
UserThread.execute(() -> availableBalance.set(longToXmr(newValue.value))); UserThread.execute(() -> availableBalance.set(HavenoUtils.formatToXmrWithCode(newValue)));
}); });
balances.getPendingBalance().addListener((observable, oldValue, newValue) -> { balances.getPendingBalance().addListener((observable, oldValue, newValue) -> {
UserThread.execute(() -> pendingBalance.set(longToXmr(newValue.value))); UserThread.execute(() -> pendingBalance.set(HavenoUtils.formatToXmrWithCode(newValue)));
}); });
balances.getReservedBalance().addListener((observable, oldValue, newValue) -> { balances.getReservedBalance().addListener((observable, oldValue, newValue) -> {
UserThread.execute(() -> reservedBalance.set(longToXmr(newValue.value))); UserThread.execute(() -> reservedBalance.set(HavenoUtils.formatToXmrWithCode(newValue)));
}); });
} }
// TODO: truncate full precision with ellipses to not break layout?
// TODO (woodser): formatting utils in monero-java
private static String longToXmr(long amt) {
BigInteger auAmt = BigInteger.valueOf(amt);
BigInteger[] quotientAndRemainder = auAmt.divideAndRemainder(AU_PER_XMR);
double decimalRemainder = quotientAndRemainder[1].doubleValue() / AU_PER_XMR.doubleValue();
return quotientAndRemainder[0].doubleValue() + decimalRemainder + " XMR";
}
} }

View file

@ -85,8 +85,8 @@ class TransactionsListItem {
Optional<Tradable> optionalTradable = Optional.ofNullable(transactionAwareTradable) Optional<Tradable> optionalTradable = Optional.ofNullable(transactionAwareTradable)
.map(TransactionAwareTradable::asTradable); .map(TransactionAwareTradable::asTradable);
BigInteger valueSentToMe = tx.getIncomingAmount() == null ? new BigInteger("0") : tx.getIncomingAmount(); BigInteger valueSentToMe = tx.getIncomingAmount() == null ? BigInteger.valueOf(0) : tx.getIncomingAmount();
BigInteger valueSentFromMe = tx.getOutgoingAmount() == null ? new BigInteger("0") : tx.getOutgoingAmount(); BigInteger valueSentFromMe = tx.getOutgoingAmount() == null ? BigInteger.valueOf(0) : tx.getOutgoingAmount();
if (tx.getTransfers().get(0).isIncoming()) { if (tx.getTransfers().get(0).isIncoming()) {
addressString = ((MoneroIncomingTransfer) tx.getTransfers().get(0)).getAddress(); addressString = ((MoneroIncomingTransfer) tx.getTransfers().get(0)).getAddress();