update state from wallet notifications on UserThread
This commit is contained in:
parent
a6f6f5c00a
commit
c28ffb70ff
@ -17,6 +17,7 @@
|
||||
|
||||
package haveno.core.xmr;
|
||||
|
||||
import haveno.common.UserThread;
|
||||
import haveno.core.offer.OpenOffer;
|
||||
import haveno.core.offer.OpenOfferManager;
|
||||
import haveno.core.support.dispute.Dispute;
|
||||
@ -86,67 +87,47 @@ public class Balances {
|
||||
}
|
||||
|
||||
private void updateBalances() {
|
||||
if (!xmrWalletService.isWalletAvailable()) return;
|
||||
try {
|
||||
updateAvailableBalance();
|
||||
updatePendingBalance();
|
||||
updateReservedOfferBalance();
|
||||
updateReservedTradeBalance();
|
||||
updateReservedBalance();
|
||||
} catch (Exception e) {
|
||||
if (xmrWalletService.isWalletAvailable()) throw e; // ignore exception if wallet isn't ready
|
||||
}
|
||||
}
|
||||
|
||||
// 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() {
|
||||
availableBalance.set(xmrWalletService.getWallet() == null ? BigInteger.ZERO : xmrWalletService.getWallet().getUnlockedBalance(0));
|
||||
}
|
||||
|
||||
private void updatePendingBalance() {
|
||||
// get wallet balances
|
||||
BigInteger balance = xmrWalletService.getWallet() == null ? BigInteger.ZERO : xmrWalletService.getWallet().getBalance(0);
|
||||
BigInteger unlockedBalance = xmrWalletService.getWallet() == null ? BigInteger.ZERO : xmrWalletService.getWallet().getUnlockedBalance(0);
|
||||
BigInteger pendingBalanceSum = balance.subtract(unlockedBalance);
|
||||
|
||||
// add frozen trade balances - reserved amounts
|
||||
// calculate pending balance by adding frozen trade balances - reserved amounts
|
||||
BigInteger pendingBalance = balance.subtract(unlockedBalance);
|
||||
List<Trade> trades = tradeManager.getTradesStreamWithFundsLockedIn().collect(Collectors.toList());
|
||||
for (Trade trade : trades) {
|
||||
if (trade.getFrozenAmount().equals(new BigInteger("0"))) continue;
|
||||
BigInteger tradeFee = trade instanceof MakerTrade ? trade.getMakerFee() : trade.getTakerFee();
|
||||
pendingBalanceSum = pendingBalanceSum.add(trade.getFrozenAmount()).subtract(trade.getReservedAmount()).subtract(tradeFee).subtract(trade.getSelf().getDepositTxFee());
|
||||
pendingBalance = pendingBalance.add(trade.getFrozenAmount()).subtract(trade.getReservedAmount()).subtract(tradeFee).subtract(trade.getSelf().getDepositTxFee());
|
||||
}
|
||||
|
||||
// add frozen offer balances
|
||||
pendingBalance.set(pendingBalanceSum);
|
||||
}
|
||||
|
||||
private void updateReservedOfferBalance() {
|
||||
BigInteger sum = BigInteger.ZERO;
|
||||
// calculate reserved offer balance
|
||||
BigInteger reservedOfferBalance = BigInteger.ZERO;
|
||||
if (xmrWalletService.getWallet() != null) {
|
||||
List<MoneroOutputWallet> frozenOutputs = xmrWalletService.getWallet().getOutputs(new MoneroOutputQuery().setIsFrozen(true).setIsSpent(false));
|
||||
for (MoneroOutputWallet frozenOutput : frozenOutputs) sum = sum.add(frozenOutput.getAmount());
|
||||
for (MoneroOutputWallet frozenOutput : frozenOutputs) reservedOfferBalance = reservedOfferBalance.add(frozenOutput.getAmount());
|
||||
}
|
||||
|
||||
// subtract frozen trade balances
|
||||
List<Trade> trades = tradeManager.getTradesStreamWithFundsLockedIn().collect(Collectors.toList());
|
||||
for (Trade trade : trades) {
|
||||
sum = sum.subtract(trade.getFrozenAmount());
|
||||
reservedOfferBalance = reservedOfferBalance.subtract(trade.getFrozenAmount()); // subtract frozen trade balances
|
||||
}
|
||||
|
||||
reservedOfferBalance.set(sum);
|
||||
}
|
||||
|
||||
private void updateReservedTradeBalance() {
|
||||
BigInteger sum = BigInteger.ZERO;
|
||||
List<Trade> trades = tradeManager.getTradesStreamWithFundsLockedIn().collect(Collectors.toList());
|
||||
// calculate reserved trade balance
|
||||
BigInteger reservedTradeBalance = BigInteger.ZERO;
|
||||
for (Trade trade : trades) {
|
||||
sum = sum.add(trade.getReservedAmount());
|
||||
}
|
||||
reservedTradeBalance.set(sum);
|
||||
reservedTradeBalance = reservedTradeBalance.add(trade.getReservedAmount());
|
||||
}
|
||||
|
||||
private void updateReservedBalance() {
|
||||
reservedBalance.set(reservedOfferBalance.get().add(reservedTradeBalance.get()));
|
||||
// set balances
|
||||
setBalances(balance, unlockedBalance, pendingBalance, reservedOfferBalance, reservedTradeBalance);
|
||||
}
|
||||
|
||||
private void setBalances(BigInteger balance, BigInteger unlockedBalance, BigInteger pendingBalance, BigInteger reservedOfferBalance, BigInteger reservedTradeBalance) {
|
||||
UserThread.execute(() -> {
|
||||
this.availableBalance.set(unlockedBalance);
|
||||
this.pendingBalance.set(pendingBalance);
|
||||
this.reservedOfferBalance.set(reservedOfferBalance);
|
||||
this.reservedTradeBalance.set(reservedTradeBalance);
|
||||
this.reservedBalance.set(reservedOfferBalance.add(reservedTradeBalance));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -1297,13 +1297,17 @@ public class XmrWalletService {
|
||||
}
|
||||
|
||||
public void addWalletListener(MoneroWalletListenerI listener) {
|
||||
synchronized (walletListeners) {
|
||||
walletListeners.add(listener);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeWalletListener(MoneroWalletListenerI listener) {
|
||||
synchronized (walletListeners) {
|
||||
if (!walletListeners.contains(listener)) throw new RuntimeException("Listener is not registered with wallet");
|
||||
walletListeners.remove(listener);
|
||||
}
|
||||
}
|
||||
|
||||
// TODO (woodser): update balance and other listening
|
||||
public void addBalanceListener(XmrBalanceListener listener) {
|
||||
|
@ -20,11 +20,9 @@ package haveno.desktop.main.funds.deposit;
|
||||
import com.google.common.base.Supplier;
|
||||
import com.google.common.base.Suppliers;
|
||||
|
||||
import haveno.common.UserThread;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.util.coin.CoinFormatter;
|
||||
import haveno.core.xmr.listeners.XmrBalanceListener;
|
||||
import haveno.core.xmr.model.XmrAddressEntry;
|
||||
import haveno.core.xmr.wallet.XmrWalletService;
|
||||
import haveno.desktop.components.indicator.TxConfidenceIndicator;
|
||||
@ -46,7 +44,6 @@ class DepositListItem {
|
||||
private final XmrWalletService xmrWalletService;
|
||||
private BigInteger balanceAsBI;
|
||||
private String usage = "-";
|
||||
private XmrBalanceListener balanceListener;
|
||||
private int numTxsWithOutputs = 0;
|
||||
private final Supplier<LazyFields> lazyFieldsSupplier;
|
||||
|
||||
@ -63,18 +60,6 @@ class DepositListItem {
|
||||
this.xmrWalletService = xmrWalletService;
|
||||
this.addressEntry = addressEntry;
|
||||
|
||||
balanceListener = new XmrBalanceListener(addressEntry.getSubaddressIndex()) {
|
||||
@Override
|
||||
public void onBalanceChanged(BigInteger balance) {
|
||||
UserThread.execute(() -> {
|
||||
DepositListItem.this.balanceAsBI = balance;
|
||||
DepositListItem.this.balance.set(HavenoUtils.formatXmr(balanceAsBI));
|
||||
updateUsage(addressEntry.getSubaddressIndex(), null);
|
||||
});
|
||||
}
|
||||
};
|
||||
xmrWalletService.addBalanceListener(balanceListener);
|
||||
|
||||
balanceAsBI = xmrWalletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex());
|
||||
balance.set(HavenoUtils.formatXmr(balanceAsBI));
|
||||
|
||||
@ -118,7 +103,6 @@ class DepositListItem {
|
||||
}
|
||||
|
||||
public void cleanup() {
|
||||
xmrWalletService.removeBalanceListener(balanceListener);
|
||||
}
|
||||
|
||||
public TxConfidenceIndicator getTxConfidenceIndicator() {
|
||||
|
@ -73,6 +73,7 @@ import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
@ -214,10 +215,12 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
||||
} else {
|
||||
XmrAddressEntry newSavingsAddressEntry = xmrWalletService.getNewAddressEntry();
|
||||
updateList();
|
||||
UserThread.execute(() -> {
|
||||
observableList.stream()
|
||||
.filter(depositListItem -> depositListItem.getAddressString().equals(newSavingsAddressEntry.getAddressString()))
|
||||
.findAny()
|
||||
.ifPresent(depositListItem -> tableView.getSelectionModel().select(depositListItem));
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
@ -316,15 +319,22 @@ public class DepositView extends ActivatableView<VBox, Void> {
|
||||
// cache incoming txs
|
||||
txsWithIncomingOutputs = xmrWalletService.getTxsWithIncomingOutputs();
|
||||
|
||||
// clear existing items
|
||||
// create deposit list items
|
||||
List<XmrAddressEntry> addressEntries = xmrWalletService.getAddressEntries();
|
||||
List<DepositListItem> items = new ArrayList<>();
|
||||
for (XmrAddressEntry addressEntry : addressEntries) {
|
||||
if (addressEntry.getContext().isReserved()) continue;
|
||||
items.add(new DepositListItem(addressEntry, xmrWalletService, formatter, txsWithIncomingOutputs));
|
||||
}
|
||||
|
||||
// update list
|
||||
UserThread.execute(() -> {
|
||||
observableList.forEach(DepositListItem::cleanup);
|
||||
observableList.clear();
|
||||
|
||||
// add non-reserved address entries
|
||||
for (XmrAddressEntry addressEntry : xmrWalletService.getAddressEntries()) {
|
||||
if (addressEntry.getContext().isReserved()) continue;
|
||||
observableList.add(new DepositListItem(addressEntry, xmrWalletService, formatter, txsWithIncomingOutputs));
|
||||
for (DepositListItem item : items) {
|
||||
observableList.add(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private Coin getAmount() {
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package haveno.desktop.main.funds.transactions;
|
||||
|
||||
import haveno.common.UserThread;
|
||||
import haveno.core.trade.Tradable;
|
||||
import haveno.core.xmr.wallet.XmrWalletService;
|
||||
import monero.wallet.model.MoneroTxWallet;
|
||||
@ -42,9 +43,10 @@ class DisplayedTransactions extends ObservableListDecorator<TransactionsListItem
|
||||
|
||||
void update() {
|
||||
List<TransactionsListItem> transactionsListItems = getTransactionListItems();
|
||||
// are sorted by getRecentTransactions
|
||||
UserThread.execute(() -> {
|
||||
forEach(TransactionsListItem::cleanup);
|
||||
setAll(transactionsListItems);
|
||||
});
|
||||
}
|
||||
|
||||
private List<TransactionsListItem> getTransactionListItems() {
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package haveno.desktop.main.funds.withdrawal;
|
||||
|
||||
import haveno.common.UserThread;
|
||||
import haveno.core.locale.Res;
|
||||
import haveno.core.trade.HavenoUtils;
|
||||
import haveno.core.util.coin.CoinFormatter;
|
||||
@ -68,8 +69,9 @@ class WithdrawalListItem {
|
||||
|
||||
private void updateBalance() {
|
||||
balance = walletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex());
|
||||
if (balance != null)
|
||||
balanceLabel.setText(HavenoUtils.formatXmr(this.balance));
|
||||
if (balance != null) {
|
||||
UserThread.execute(() -> balanceLabel.setText(HavenoUtils.formatXmr(this.balance)));
|
||||
}
|
||||
}
|
||||
|
||||
public final String getLabel() {
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package haveno.desktop.main.offer;
|
||||
|
||||
import haveno.common.UserThread;
|
||||
import haveno.core.offer.OfferUtil;
|
||||
import haveno.core.xmr.model.XmrAddressEntry;
|
||||
import haveno.core.xmr.wallet.XmrWalletService;
|
||||
@ -66,28 +67,35 @@ public abstract class OfferDataModel extends ActivatableDataModel {
|
||||
|
||||
protected void updateBalance() {
|
||||
updateBalances();
|
||||
UserThread.await(() -> {
|
||||
missingCoin.set(offerUtil.getBalanceShortage(totalToPay.get(), balance.get()));
|
||||
isXmrWalletFunded.set(offerUtil.isBalanceSufficient(totalToPay.get(), balance.get()));
|
||||
if (totalToPay.get() != null && isXmrWalletFunded.get() && !showWalletFundedNotification.get()) {
|
||||
showWalletFundedNotification.set(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void updateAvailableBalance() {
|
||||
updateBalances();
|
||||
UserThread.await(() -> {
|
||||
missingCoin.set(offerUtil.getBalanceShortage(totalToPay.get(), availableBalance.get()));
|
||||
isXmrWalletFunded.set(offerUtil.isBalanceSufficient(totalToPay.get(), availableBalance.get()));
|
||||
if (totalToPay.get() != null && isXmrWalletFunded.get() && !showWalletFundedNotification.get()) {
|
||||
showWalletFundedNotification.set(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateBalances() {
|
||||
BigInteger tradeWalletBalance = xmrWalletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex());
|
||||
BigInteger tradeWalletAvailableBalance = xmrWalletService.getAvailableBalanceForSubaddress(addressEntry.getSubaddressIndex());
|
||||
BigInteger walletBalance = xmrWalletService.getBalance();
|
||||
BigInteger walletAvailableBalance = xmrWalletService.getAvailableBalance();
|
||||
UserThread.await(() -> {
|
||||
if (useSavingsWallet) {
|
||||
totalBalance = xmrWalletService.getBalance();
|
||||
totalAvailableBalance = xmrWalletService.getAvailableBalance();
|
||||
totalBalance = walletBalance;
|
||||
totalAvailableBalance = walletAvailableBalance;
|
||||
if (totalToPay.get() != null) {
|
||||
balance.set(totalToPay.get().min(totalBalance));
|
||||
availableBalance.set(totalToPay.get().min(totalAvailableBalance));
|
||||
@ -96,5 +104,7 @@ public abstract class OfferDataModel extends ActivatableDataModel {
|
||||
balance.set(tradeWalletBalance);
|
||||
availableBalance.set(tradeWalletAvailableBalance);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user