do not process payment sent & received msgs until deposits confirmed

This commit is contained in:
woodser 2025-04-02 17:49:05 -04:00
parent 584cc3b6d4
commit ef359720f1
No known key found for this signature in database
GPG Key ID: 55A10DD48ADEE5EF
3 changed files with 33 additions and 9 deletions

View File

@ -510,6 +510,12 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
protected void handle(PaymentSentMessage message, NodeAddress peer, boolean reprocessOnError) {
log.info(LOG_HIGHLIGHT + "handle(PaymentSentMessage) for " + trade.getClass().getSimpleName() + " " + trade.getShortId() + " from " + peer);
// ignore if not seller or arbitrator
if (!(trade instanceof SellerTrade || trade instanceof ArbitratorTrade)) {
log.warn("Ignoring PaymentSentMessage since not seller or arbitrator");
return;
}
// validate signature
try {
HavenoUtils.verifyPaymentSentMessage(trade, message);
@ -522,11 +528,8 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
trade.getBuyer().setPaymentSentMessage(message);
trade.requestPersistence();
// process message on trade thread
if (!trade.isInitialized() || trade.isShutDownStarted()) return;
if (!(trade instanceof SellerTrade || trade instanceof ArbitratorTrade)) {
log.warn("Ignoring PaymentSentMessage since not seller or arbitrator");
return;
}
ThreadUtils.execute(() -> {
// We are more tolerant with expected phase and allow also DEPOSITS_PUBLISHED as it can be the case
// that the wallet is still syncing and so the DEPOSITS_CONFIRMED state to yet triggered when we received
@ -549,7 +552,7 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
return;
}
latchTrade();
expect(anyPhase(Trade.Phase.DEPOSITS_CONFIRMED, Trade.Phase.DEPOSITS_UNLOCKED)
expect(anyPhase()
.with(message)
.from(peer))
.setup(tasks(
@ -589,6 +592,12 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
private void handle(PaymentReceivedMessage message, NodeAddress peer, boolean reprocessOnError) {
log.info(LOG_HIGHLIGHT + "handle(PaymentReceivedMessage) for " + trade.getClass().getSimpleName() + " " + trade.getShortId() + " from " + peer);
// ignore if not buyer or arbitrator
if (!(trade instanceof BuyerTrade || trade instanceof ArbitratorTrade)) {
log.warn("Ignoring PaymentReceivedMessage since not buyer or arbitrator");
return;
}
// validate signature
try {
HavenoUtils.verifyPaymentReceivedMessage(trade, message);
@ -601,12 +610,9 @@ public abstract class TradeProtocol implements DecryptedDirectMessageListener, D
trade.getSeller().setPaymentReceivedMessage(message);
trade.requestPersistence();
// process message on trade thread
if (!trade.isInitialized() || trade.isShutDownStarted()) return;
ThreadUtils.execute(() -> {
if (!(trade instanceof BuyerTrade || trade instanceof ArbitratorTrade)) {
log.warn("Ignoring PaymentReceivedMessage since not buyer or arbitrator");
return;
}
synchronized (trade.getLock()) {
if (!trade.isInitialized() || trade.isShutDownStarted()) return;
latchTrade();

View File

@ -72,6 +72,7 @@ public class ProcessPaymentReceivedMessage extends TradeTask {
// update to the latest peer address of our peer if message is correct
trade.getSeller().setNodeAddress(processModel.getTempTradePeerNodeAddress());
if (trade.getSeller().getNodeAddress().equals(trade.getBuyer().getNodeAddress())) trade.getBuyer().setNodeAddress(null); // tests can reuse addresses
trade.requestPersistence();
// ack and complete if already processed
if (trade.getPhase().ordinal() >= Trade.Phase.PAYMENT_RECEIVED.ordinal() && trade.isPayoutPublished()) {
@ -80,6 +81,14 @@ public class ProcessPaymentReceivedMessage extends TradeTask {
return;
}
// cannot process until wallet sees deposits unlocked
if (!trade.isDepositsUnlocked()) {
trade.syncAndPollWallet();
if (!trade.isDepositsUnlocked()) {
throw new RuntimeException("Cannot process PaymentReceivedMessage until wallet sees that deposits are unlocked for " + trade.getClass().getSimpleName() + " " + trade.getId());
}
}
// set state
trade.getSeller().setUpdatedMultisigHex(message.getUpdatedMultisigHex());
trade.getBuyer().setAccountAgeWitness(message.getBuyerAccountAgeWitness());

View File

@ -46,6 +46,15 @@ public class ProcessPaymentSentMessage extends TradeTask {
// update latest peer address
trade.getBuyer().setNodeAddress(processModel.getTempTradePeerNodeAddress());
trade.requestPersistence();
// cannot process until wallet sees deposits confirmed
if (!trade.isDepositsConfirmed()) {
trade.syncAndPollWallet();
if (!trade.isDepositsConfirmed()) {
throw new RuntimeException("Cannot process PaymentSentMessage until wallet sees that deposits are confirmed for " + trade.getClass().getSimpleName() + " " + trade.getId());
}
}
// update state from message
trade.getBuyer().setUpdatedMultisigHex(message.getUpdatedMultisigHex());