repeat try withdraw tx and fix amount details

This commit is contained in:
woodser 2024-05-05 07:51:40 -04:00
parent ceff34672d
commit f99fab8515
2 changed files with 56 additions and 49 deletions

View file

@ -843,7 +843,7 @@ public abstract class Trade implements Tradable, Model {
public void importMultisigHex() { public void importMultisigHex() {
synchronized (walletLock) { synchronized (walletLock) {
synchronized (HavenoUtils.getDaemonLock()) { // TODO: lock on daemon because wallet2's import_multisig calls refresh: https://github.com/monero-project/monero/issues/9312 synchronized (HavenoUtils.getDaemonLock()) { // lock on daemon because import calls full refresh
for (int i = 0; i < TradeProtocol.MAX_ATTEMPTS; i++) { for (int i = 0; i < TradeProtocol.MAX_ATTEMPTS; i++) {
try { try {
doImportMultisigHex(); doImportMultisigHex();

View file

@ -38,12 +38,11 @@ import com.google.inject.Inject;
import haveno.common.util.Tuple4; import haveno.common.util.Tuple4;
import haveno.core.locale.Res; import haveno.core.locale.Res;
import haveno.core.trade.HavenoUtils; import haveno.core.trade.HavenoUtils;
import haveno.core.trade.Trade;
import haveno.core.trade.TradeManager; import haveno.core.trade.TradeManager;
import haveno.core.trade.protocol.TradeProtocol;
import haveno.core.user.DontShowAgainLookup; import haveno.core.user.DontShowAgainLookup;
import haveno.core.util.validation.BtcAddressValidator; import haveno.core.util.validation.BtcAddressValidator;
import haveno.core.xmr.listeners.XmrBalanceListener; import haveno.core.xmr.listeners.XmrBalanceListener;
import haveno.core.xmr.model.XmrAddressEntry;
import haveno.core.xmr.setup.WalletsSetup; import haveno.core.xmr.setup.WalletsSetup;
import haveno.core.xmr.wallet.XmrWalletService; import haveno.core.xmr.wallet.XmrWalletService;
import haveno.desktop.common.view.ActivatableView; import haveno.desktop.common.view.ActivatableView;
@ -72,9 +71,7 @@ import monero.wallet.model.MoneroTxConfig;
import monero.wallet.model.MoneroTxWallet; import monero.wallet.model.MoneroTxWallet;
import java.math.BigInteger; import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.List;
import static haveno.desktop.util.FormBuilder.addTitledGroupBg; import static haveno.desktop.util.FormBuilder.addTitledGroupBg;
import static haveno.desktop.util.FormBuilder.addTopLabelInputTextField; import static haveno.desktop.util.FormBuilder.addTopLabelInputTextField;
@ -107,6 +104,7 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
private ToggleGroup feeToggleGroup; private ToggleGroup feeToggleGroup;
private boolean feeExcluded; private boolean feeExcluded;
private int rowIndex = 0; private int rowIndex = 0;
private final static int MAX_ATTEMPTS = 3;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// Constructor, lifecycle // Constructor, lifecycle
@ -259,18 +257,45 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
// get withdraw address // get withdraw address
final String withdrawToAddress = withdrawToTextField.getText(); final String withdrawToAddress = withdrawToTextField.getText();
// create tx // check sufficient available balance
if (amount.compareTo(BigInteger.ZERO) <= 0) throw new RuntimeException(Res.get("portfolio.pending.step5_buyer.amountTooLow")); if (amount.compareTo(BigInteger.ZERO) <= 0) throw new RuntimeException(Res.get("portfolio.pending.step5_buyer.amountTooLow"));
// create tx
MoneroTxWallet tx = null;
for (int i = 0; i < MAX_ATTEMPTS; i++) {
try {
log.info("Creating withdraw tx"); log.info("Creating withdraw tx");
long startTime = System.currentTimeMillis(); long startTime = System.currentTimeMillis();
MoneroTxWallet tx = xmrWalletService.createTx(new MoneroTxConfig() tx = xmrWalletService.createTx(new MoneroTxConfig()
.setAccountIndex(0) .setAccountIndex(0)
.setAmount(amount) .setAmount(amount)
.setAddress(withdrawToAddress) .setAddress(withdrawToAddress)
.setSubtractFeeFrom(feeExcluded ? null : Arrays.asList(0))); .setSubtractFeeFrom(feeExcluded ? null : Arrays.asList(0)));
log.info("Done creating withdraw tx in {} ms", System.currentTimeMillis() - startTime); log.info("Done creating withdraw tx in {} ms", System.currentTimeMillis() - startTime);
break;
} catch (Exception e) {
log.warn("Error creating creating withdraw tx, attempt={}/{}, error={}", i + 1, MAX_ATTEMPTS, e.getMessage());
if (i == MAX_ATTEMPTS - 1) throw e;
HavenoUtils.waitFor(TradeProtocol.REPROCESS_DELAY_MS); // wait before retrying
}
}
// popup confirmation message
popupConfirmationMessage(tx);
} catch (Throwable e) {
if (e.getMessage().contains("enough")) new Popup().warning(Res.get("funds.withdrawal.warn.amountExceeds")).show();
else {
e.printStackTrace();
new Popup().warning(e.getMessage()).show();
}
}
}
}
private void popupConfirmationMessage(MoneroTxWallet tx) {
// create confirmation message // create confirmation message
String withdrawToAddress = tx.getOutgoingTransfer().getDestinations().get(0).getAddress();
BigInteger receiverAmount = tx.getOutgoingTransfer().getDestinations().get(0).getAmount(); BigInteger receiverAmount = tx.getOutgoingTransfer().getDestinations().get(0).getAmount();
BigInteger fee = tx.getFee(); BigInteger fee = tx.getFee();
String messageText = Res.get("shared.sendFundsDetailsWithFee", String messageText = Res.get("shared.sendFundsDetailsWithFee",
@ -287,24 +312,16 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
.onAction(() -> { .onAction(() -> {
if (xmrWalletService.isWalletEncrypted()) { if (xmrWalletService.isWalletEncrypted()) {
walletPasswordWindow.headLine(Res.get("walletPasswordWindow.headline")).onSuccess(() -> { walletPasswordWindow.headLine(Res.get("walletPasswordWindow.headline")).onSuccess(() -> {
relayTx(tx, withdrawToAddress, amount, fee); relayTx(tx, withdrawToAddress, receiverAmount, fee);
}).onClose(() -> { }).onClose(() -> {
popup.hide(); popup.hide();
}).hideForgotPasswordButton().show(); }).hideForgotPasswordButton().show();
} else { } else {
relayTx(tx, withdrawToAddress, amount, fee); relayTx(tx, withdrawToAddress, receiverAmount, fee);
} }
}) })
.closeButtonText(Res.get("shared.cancel")) .closeButtonText(Res.get("shared.cancel"))
.show(); .show();
} catch (Throwable e) {
if (e.getMessage().contains("enough")) new Popup().warning(Res.get("funds.withdrawal.warn.amountExceeds")).show();
else {
e.printStackTrace();
new Popup().warning(e.getMessage()).show();
}
}
}
} }
private void relayTx(MoneroTxWallet tx, String withdrawToAddress, BigInteger receiverAmount, BigInteger fee) { private void relayTx(MoneroTxWallet tx, String withdrawToAddress, BigInteger receiverAmount, BigInteger fee) {
@ -318,16 +335,6 @@ public class WithdrawalView extends ActivatableView<VBox, Void> {
.show(); .show();
} }
log.debug("onWithdraw onSuccess tx ID:{}", tx.getHash()); log.debug("onWithdraw onSuccess tx ID:{}", tx.getHash());
// TODO: remove this?
List<Trade> trades = new ArrayList<>(tradeManager.getObservableList());
trades.stream()
.filter(Trade::isPayoutPublished)
.forEach(trade -> xmrWalletService.getAddressEntry(trade.getId(), XmrAddressEntry.Context.TRADE_PAYOUT)
.ifPresent(addressEntry -> {
if (xmrWalletService.getBalanceForAddress(addressEntry.getAddressString()).compareTo(BigInteger.ZERO) == 0)
tradeManager.onTradeCompleted(trade);
}));
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
new Popup().warning(e.getMessage()).show(); new Popup().warning(e.getMessage()).show();