recover from payment received message not processed

This commit is contained in:
woodser 2024-07-16 12:22:12 -04:00
parent 1c381de806
commit 33bf54bcac
4 changed files with 41 additions and 27 deletions

View file

@ -490,7 +490,6 @@ public abstract class Trade implements Tradable, Model {
private Long payoutHeight; private Long payoutHeight;
private IdlePayoutSyncer idlePayoutSyncer; private IdlePayoutSyncer idlePayoutSyncer;
@Getter @Getter
@Setter
private boolean isCompleted; private boolean isCompleted;
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -614,8 +613,8 @@ public abstract class Trade implements Tradable, Model {
public void initialize(ProcessModelServiceProvider serviceProvider) { public void initialize(ProcessModelServiceProvider serviceProvider) {
if (isInitialized) throw new IllegalStateException(getClass().getSimpleName() + " " + getId() + " is already initialized"); if (isInitialized) throw new IllegalStateException(getClass().getSimpleName() + " " + getId() + " is already initialized");
// done if payout unlocked // done if payout unlocked and marked complete
if (isPayoutUnlocked()) { if (isPayoutUnlocked() && isCompleted()) {
clearAndShutDown(); clearAndShutDown();
return; return;
} }
@ -679,13 +678,12 @@ public abstract class Trade implements Tradable, Model {
log.info("Payout published for {} {}", getClass().getSimpleName(), getId()); log.info("Payout published for {} {}", getClass().getSimpleName(), getId());
// sync main wallet to update pending balance // sync main wallet to update pending balance
if (!isPayoutConfirmed()) { ThreadUtils.submitToPool(() -> {
new Thread(() -> { HavenoUtils.waitFor(1000);
HavenoUtils.waitFor(1000); if (isPayoutConfirmed()) return;
if (isShutDownStarted) return; if (isShutDownStarted) return;
if (xmrConnectionService.isConnected()) syncAndPollWallet(); if (xmrConnectionService.isConnected()) syncAndPollWallet();
}).start(); });
}
// complete disputed trade // complete disputed trade
if (getDisputeState().isArbitrated() && !getDisputeState().isClosed()) { if (getDisputeState().isArbitrated() && !getDisputeState().isClosed()) {
@ -707,7 +705,8 @@ public abstract class Trade implements Tradable, Model {
if (newValue == Trade.PayoutState.PAYOUT_UNLOCKED) { if (newValue == Trade.PayoutState.PAYOUT_UNLOCKED) {
if (!isInitialized) return; if (!isInitialized) return;
log.info("Payout unlocked for {} {}, deleting multisig wallet", getClass().getSimpleName(), getId()); log.info("Payout unlocked for {} {}, deleting multisig wallet", getClass().getSimpleName(), getId());
clearAndShutDown(); if (isCompleted()) clearAndShutDown();
else deleteWallet();
} }
}); });
}); });
@ -790,6 +789,11 @@ public abstract class Trade implements Tradable, Model {
return getArbitrator() == null ? null : getArbitrator().getNodeAddress(); return getArbitrator() == null ? null : getArbitrator().getNodeAddress();
} }
public void setCompleted(boolean completed) {
this.isCompleted = completed;
if (isPayoutUnlocked()) clearAndShutDown();
}
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
// WALLET MANAGEMENT // WALLET MANAGEMENT
/////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////
@ -996,7 +1000,11 @@ public abstract class Trade implements Tradable, Model {
private void forceCloseWallet() { private void forceCloseWallet() {
if (wallet != null) { if (wallet != null) {
xmrWalletService.forceCloseWallet(wallet, wallet.getPath()); try {
xmrWalletService.forceCloseWallet(wallet, wallet.getPath());
} catch (Exception e) {
log.warn("Error force closing wallet for {} {}: {}", getClass().getSimpleName(), getId(), e.getMessage());
}
stopPolling(); stopPolling();
wallet = null; wallet = null;
} }

View file

@ -296,7 +296,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
} }
public void handleInitMultisigRequest(InitMultisigRequest request, NodeAddress sender) { public void handleInitMultisigRequest(InitMultisigRequest request, NodeAddress sender) {
System.out.println(getClass().getSimpleName() + ".handleInitMultisigRequest()"); System.out.println(getClass().getSimpleName() + ".handleInitMultisigRequest() for " + trade.getClass().getSimpleName() + " " + trade.getShortId());
trade.addInitProgressStep(); trade.addInitProgressStep();
ThreadUtils.execute(() -> { ThreadUtils.execute(() -> {
synchronized (trade) { synchronized (trade) {
@ -333,7 +333,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
} }
public void handleSignContractRequest(SignContractRequest message, NodeAddress sender) { public void handleSignContractRequest(SignContractRequest message, NodeAddress sender) {
System.out.println(getClass().getSimpleName() + ".handleSignContractRequest() " + trade.getId()); System.out.println(getClass().getSimpleName() + ".handleSignContractRequest() for " + trade.getClass().getSimpleName() + " " + trade.getShortId());
ThreadUtils.execute(() -> { ThreadUtils.execute(() -> {
synchronized (trade) { synchronized (trade) {
@ -376,7 +376,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
} }
public void handleSignContractResponse(SignContractResponse message, NodeAddress sender) { public void handleSignContractResponse(SignContractResponse message, NodeAddress sender) {
System.out.println(getClass().getSimpleName() + ".handleSignContractResponse() " + trade.getId()); System.out.println(getClass().getSimpleName() + ".handleSignContractResponse() for " + trade.getClass().getSimpleName() + " " + trade.getShortId());
trade.addInitProgressStep(); trade.addInitProgressStep();
ThreadUtils.execute(() -> { ThreadUtils.execute(() -> {
synchronized (trade) { synchronized (trade) {
@ -422,7 +422,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
} }
public void handleDepositResponse(DepositResponse response, NodeAddress sender) { public void handleDepositResponse(DepositResponse response, NodeAddress sender) {
System.out.println(getClass().getSimpleName() + ".handleDepositResponse()"); System.out.println(getClass().getSimpleName() + ".handleDepositResponse() for " + trade.getClass().getSimpleName() + " " + trade.getShortId());
trade.addInitProgressStep(); trade.addInitProgressStep();
ThreadUtils.execute(() -> { ThreadUtils.execute(() -> {
synchronized (trade) { synchronized (trade) {
@ -452,7 +452,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
} }
public void handle(DepositsConfirmedMessage message, NodeAddress sender) { public void handle(DepositsConfirmedMessage message, NodeAddress sender) {
System.out.println(getClass().getSimpleName() + ".handle(DepositsConfirmedMessage) from " + sender); System.out.println(getClass().getSimpleName() + ".handle(DepositsConfirmedMessage) from " + sender + " for " + trade.getClass().getSimpleName() + " " + trade.getShortId());
if (!trade.isInitialized() || trade.isShutDown()) return; if (!trade.isInitialized() || trade.isShutDown()) return;
ThreadUtils.execute(() -> { ThreadUtils.execute(() -> {
synchronized (trade) { synchronized (trade) {
@ -481,7 +481,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
// received by seller and arbitrator // received by seller and arbitrator
protected void handle(PaymentSentMessage message, NodeAddress peer) { protected void handle(PaymentSentMessage message, NodeAddress peer) {
System.out.println(getClass().getSimpleName() + ".handle(PaymentSentMessage)"); System.out.println(getClass().getSimpleName() + ".handle(PaymentSentMessage) for " + trade.getClass().getSimpleName() + " " + trade.getShortId());
if (!trade.isInitialized() || trade.isShutDown()) return; if (!trade.isInitialized() || trade.isShutDown()) return;
if (!(trade instanceof SellerTrade || trade instanceof ArbitratorTrade)) { if (!(trade instanceof SellerTrade || trade instanceof ArbitratorTrade)) {
log.warn("Ignoring PaymentSentMessage since not seller or arbitrator"); log.warn("Ignoring PaymentSentMessage since not seller or arbitrator");
@ -535,7 +535,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
} }
private void handle(PaymentReceivedMessage message, NodeAddress peer, boolean reprocessOnError) { private void handle(PaymentReceivedMessage message, NodeAddress peer, boolean reprocessOnError) {
System.out.println(getClass().getSimpleName() + ".handle(PaymentReceivedMessage)"); System.out.println(getClass().getSimpleName() + ".handle(PaymentReceivedMessage) for " + trade.getClass().getSimpleName() + " " + trade.getShortId());
if (!trade.isInitialized() || trade.isShutDown()) return; if (!trade.isInitialized() || trade.isShutDown()) return;
ThreadUtils.execute(() -> { ThreadUtils.execute(() -> {
if (!(trade instanceof BuyerTrade || trade instanceof ArbitratorTrade)) { if (!(trade instanceof BuyerTrade || trade instanceof ArbitratorTrade)) {

View file

@ -61,16 +61,20 @@ public class ProcessDepositsConfirmedMessage extends TradeTask {
} }
// update multisig hex // update multisig hex
sender.setUpdatedMultisigHex(request.getUpdatedMultisigHex()); if (sender.getUpdatedMultisigHex() == null) {
sender.setUpdatedMultisigHex(request.getUpdatedMultisigHex());
// try to import multisig hex (retry later) // try to import multisig hex (retry later)
ThreadUtils.submitToPool(() -> { if (!trade.isPayoutPublished()) {
try { ThreadUtils.submitToPool(() -> {
trade.importMultisigHex(); try {
} catch (Exception e) { trade.importMultisigHex();
e.printStackTrace(); } catch (Exception e) {
e.printStackTrace();
}
});
} }
}); }
// persist // persist
processModel.getTradeManager().requestPersistence(); processModel.getTradeManager().requestPersistence();

View file

@ -210,6 +210,8 @@ public class PendingTradesViewModel extends ActivatableWithDataModel<PendingTrad
sellerState.set(UNDEFINED); sellerState.set(UNDEFINED);
buyerState.set(BuyerState.UNDEFINED); buyerState.set(BuyerState.UNDEFINED);
onTradeStateChanged(trade.getState()); onTradeStateChanged(trade.getState());
if (trade.isPayoutPublished()) onPayoutStateChanged(trade.getPayoutState()); // TODO: payout state takes precedence in case PaymentReceivedMessage not processed
else onTradeStateChanged(trade.getState());
}); });
} }