cache wallet state to avoid requests on main thread

This commit is contained in:
woodser 2024-02-18 14:56:21 -05:00
parent d8ef7e82d4
commit eaf096adeb
4 changed files with 76 additions and 100 deletions

View file

@ -32,7 +32,6 @@ import javafx.beans.property.StringProperty;
import javafx.scene.control.Tooltip;
import lombok.extern.slf4j.Slf4j;
import monero.daemon.model.MoneroTx;
import monero.wallet.model.MoneroSubaddress;
import monero.wallet.model.MoneroTxWallet;
import java.math.BigInteger;
@ -57,14 +56,14 @@ class DepositListItem {
return lazyFieldsSupplier.get();
}
DepositListItem(XmrAddressEntry addressEntry, XmrWalletService xmrWalletService, CoinFormatter formatter, List<MoneroTxWallet> cachedTxs, List<MoneroSubaddress> cachedSubaddresses) {
DepositListItem(XmrAddressEntry addressEntry, XmrWalletService xmrWalletService, CoinFormatter formatter) {
this.xmrWalletService = xmrWalletService;
this.addressEntry = addressEntry;
balanceAsBI = xmrWalletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex(), cachedSubaddresses);
balanceAsBI = xmrWalletService.getBalanceForSubaddress(addressEntry.getSubaddressIndex());
balance.set(HavenoUtils.formatXmr(balanceAsBI));
updateUsage(addressEntry.getSubaddressIndex(), cachedTxs, cachedSubaddresses);
updateUsage(addressEntry.getSubaddressIndex());
// confidence
lazyFieldsSupplier = Suppliers.memoize(() -> new LazyFields() {{
@ -73,7 +72,7 @@ class DepositListItem {
tooltip = new Tooltip(Res.get("shared.notUsedYet"));
txConfidenceIndicator.setProgress(0);
txConfidenceIndicator.setTooltip(tooltip);
MoneroTx tx = getTxWithFewestConfirmations(cachedTxs);
MoneroTx tx = getTxWithFewestConfirmations();
if (tx == null) {
txConfidenceIndicator.setVisible(false);
} else {
@ -83,8 +82,8 @@ class DepositListItem {
}});
}
private void updateUsage(int subaddressIndex, List<MoneroTxWallet> cachedTxs, List<MoneroSubaddress> cachedSubaddresses) {
numTxsWithOutputs = xmrWalletService.getNumTxsWithIncomingOutputs(addressEntry.getSubaddressIndex(), cachedTxs, cachedSubaddresses);
private void updateUsage(int subaddressIndex) {
numTxsWithOutputs = xmrWalletService.getNumTxsWithIncomingOutputs(addressEntry.getSubaddressIndex());
switch (addressEntry.getContext()) {
case BASE_ADDRESS:
usage = Res.get("funds.deposit.baseAddress");
@ -138,15 +137,15 @@ class DepositListItem {
return numTxsWithOutputs;
}
public long getNumConfirmationsSinceFirstUsed(List<MoneroTxWallet> incomingTxs) {
MoneroTx tx = getTxWithFewestConfirmations(incomingTxs);
public long getNumConfirmationsSinceFirstUsed() {
MoneroTx tx = getTxWithFewestConfirmations();
return tx == null ? 0 : tx.getNumConfirmations();
}
private MoneroTxWallet getTxWithFewestConfirmations(List<MoneroTxWallet> allIncomingTxs) {
private MoneroTxWallet getTxWithFewestConfirmations() {
// get txs with incoming outputs to subaddress index
List<MoneroTxWallet> txs = xmrWalletService.getTxsWithIncomingOutputs(addressEntry.getSubaddressIndex(), allIncomingTxs);
List<MoneroTxWallet> txs = xmrWalletService.getTxsWithIncomingOutputs(addressEntry.getSubaddressIndex());
// get tx with fewest confirmations
MoneroTxWallet highestTx = null;

View file

@ -76,9 +76,7 @@ import javafx.scene.layout.GridPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.util.Callback;
import monero.wallet.model.MoneroSubaddress;
import monero.wallet.model.MoneroTxConfig;
import monero.wallet.model.MoneroTxWallet;
import monero.wallet.model.MoneroWalletListener;
import net.glxn.qrgen.QRCode;
import net.glxn.qrgen.image.ImageType;
@ -127,7 +125,6 @@ public class DepositView extends ActivatableView<VBox, Void> {
private Subscription amountTextFieldSubscription;
private ChangeListener<DepositListItem> tableViewSelectionListener;
private int gridRow = 0;
List<MoneroTxWallet> txsWithIncomingOutputs;
///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, lifecycle
@ -151,15 +148,9 @@ public class DepositView extends ActivatableView<VBox, Void> {
confirmationsColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.confirmations")));
usageColumn.setGraphic(new AutoTooltipLabel(Res.get("shared.usage")));
// try to initialize with wallet txs
// trigger creation of at least 1 address
try {
// prefetch to avoid query per subaddress
txsWithIncomingOutputs = xmrWalletService.getTxsWithIncomingOutputs();
List<MoneroSubaddress> subaddresses = xmrWalletService.getWallet().getSubaddresses(0);
// trigger creation of at least 1 address
xmrWalletService.getFreshAddressEntry(txsWithIncomingOutputs, subaddresses);
xmrWalletService.getFreshAddressEntry();
} catch (Exception e) {
log.warn("Failed to get wallet txs to initialize DepositView");
e.printStackTrace();
@ -181,7 +172,7 @@ public class DepositView extends ActivatableView<VBox, Void> {
addressColumn.setComparator(Comparator.comparing(DepositListItem::getAddressString));
balanceColumn.setComparator(Comparator.comparing(DepositListItem::getBalanceAsBI));
confirmationsColumn.setComparator(Comparator.comparingLong(o -> o.getNumConfirmationsSinceFirstUsed(txsWithIncomingOutputs)));
confirmationsColumn.setComparator(Comparator.comparingLong(o -> o.getNumConfirmationsSinceFirstUsed()));
usageColumn.setComparator(Comparator.comparing(DepositListItem::getUsage));
tableView.getSortOrder().add(usageColumn);
tableView.setItems(sortedList);
@ -334,17 +325,13 @@ public class DepositView extends ActivatableView<VBox, Void> {
///////////////////////////////////////////////////////////////////////////////////////////
private void updateList() {
// cache incoming txs
txsWithIncomingOutputs = xmrWalletService.getTxsWithIncomingOutputs();
List<MoneroSubaddress> subaddresses = xmrWalletService.getWallet().getSubaddresses(0);
// create deposit list items
List<XmrAddressEntry> addressEntries = xmrWalletService.getAddressEntries();
List<DepositListItem> items = new ArrayList<>();
for (XmrAddressEntry addressEntry : addressEntries) {
if (addressEntry.isTrade()) continue; // skip reserved for trade
items.add(new DepositListItem(addressEntry, xmrWalletService, formatter, txsWithIncomingOutputs, subaddresses));
items.add(new DepositListItem(addressEntry, xmrWalletService, formatter));
}
// update list

View file

@ -375,6 +375,8 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
advancedOptionsBox.setVisible(false);
advancedOptionsBox.setManaged(false);
updateQrCode();
model.onShowPayFundsScreen(() -> {
if (!DevEnv.isDevMode()) {
String key = "createOfferFundWalletInfo";
@ -755,14 +757,7 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
missingCoinListener = (observable, oldValue, newValue) -> {
if (!newValue.toString().equals("")) {
final byte[] imageBytes = QRCode
.from(getMoneroURI())
.withSize(300, 300)
.to(ImageType.PNG)
.stream()
.toByteArray();
Image qrImage = new Image(new ByteArrayInputStream(imageBytes));
qrCodeImageView.setImage(qrImage);
//updateQrCode(); // disabled to avoid wallet requests on key strokes
}
};
@ -810,6 +805,17 @@ public abstract class MutableOfferView<M extends MutableOfferViewModel<?>> exten
});
}
private void updateQrCode() {
final byte[] imageBytes = QRCode
.from(getMoneroURI())
.withSize(300, 300)
.to(ImageType.PNG)
.stream()
.toByteArray();
Image qrImage = new Image(new ByteArrayInputStream(imageBytes));
qrCodeImageView.setImage(qrImage);
}
private void closeAndGoToOpenOffers() {
//go to open offers
UserThread.runAfter(() ->