set payout tx hash on payment received unless unlocked

This commit is contained in:
woodser 2022-11-23 14:25:45 +00:00
parent d3949614c6
commit 4c7075b0bd
2 changed files with 51 additions and 40 deletions

View File

@ -816,7 +816,7 @@ public abstract class Trade implements Tradable, Model {
// submit payout tx // submit payout tx
if (publish) { if (publish) {
multisigWallet.submitMultisigTxHex(payoutTxHex); multisigWallet.submitMultisigTxHex(payoutTxHex);
setPayoutState(Trade.PayoutState.PAYOUT_PUBLISHED); pollWallet();
} }
} }
@ -1447,7 +1447,7 @@ public abstract class Trade implements Tradable, Model {
} }
} }
// check for outgoing txs (appears on payout confirmed) // check for outgoing txs (appears after wallet submits payout tx or on payout confirmed)
List<MoneroTxWallet> outgoingTxs = getWallet().getTxs(new MoneroTxQuery().setIsOutgoing(true)); List<MoneroTxWallet> outgoingTxs = getWallet().getTxs(new MoneroTxQuery().setIsOutgoing(true));
if (!outgoingTxs.isEmpty()) { if (!outgoingTxs.isEmpty()) {
MoneroTxWallet payoutTx = outgoingTxs.get(0); MoneroTxWallet payoutTx = outgoingTxs.get(0);

View File

@ -59,44 +59,11 @@ public class ProcessPaymentReceivedMessage extends TradeTask {
trade.getSeller().setNodeAddress(processModel.getTempTradingPeerNodeAddress()); trade.getSeller().setNodeAddress(processModel.getTempTradingPeerNodeAddress());
if (trade.getSeller().getNodeAddress().equals(trade.getBuyer().getNodeAddress())) trade.getBuyer().setNodeAddress(null); // tests can reuse addresses if (trade.getSeller().getNodeAddress().equals(trade.getBuyer().getNodeAddress())) trade.getBuyer().setNodeAddress(null); // tests can reuse addresses
// import multisig hex // process payout tx unless already unlocked
List<String> updatedMultisigHexes = new ArrayList<String>(); if (!trade.isPayoutUnlocked()) {
if (trade.getSeller().getUpdatedMultisigHex() != null) updatedMultisigHexes.add(trade.getSeller().getUpdatedMultisigHex()); processPayoutTx(message);
if (trade.getArbitrator().getUpdatedMultisigHex() != null) updatedMultisigHexes.add(trade.getArbitrator().getUpdatedMultisigHex()); complete();
if (!updatedMultisigHexes.isEmpty()) trade.getWallet().importMultisigHex(updatedMultisigHexes.toArray(new String[0])); // TODO (monero-project): fails if multisig hex imported individually return;
// sync and save wallet
trade.syncWallet();
trade.saveWallet();
// handle if payout tx not published
if (!trade.isPayoutPublished()) {
// wait to sign and publish payout tx if defer flag set (seller recently saw payout tx arrive at buyer)
boolean isSigned = message.getSignedPayoutTxHex() != null;
if (trade instanceof ArbitratorTrade && !isSigned && message.isDeferPublishPayout()) {
log.info("Deferring signing and publishing payout tx for {} {}", trade.getClass().getSimpleName(), trade.getId());
GenUtils.waitFor(Trade.DEFER_PUBLISH_MS);
trade.syncWallet();
}
// verify and publish payout tx
if (!trade.isPayoutPublished()) {
if (isSigned) {
log.info("{} publishing signed payout tx from seller", trade.getClass().getSimpleName());
trade.verifyPayoutTx(message.getSignedPayoutTxHex(), false, true);
} else {
log.info("{} verifying, signing, and publishing seller's payout tx", trade.getClass().getSimpleName());
try {
trade.verifyPayoutTx(message.getUnsignedPayoutTxHex(), true, true);
} catch (Exception e) {
if (trade.isPayoutPublished()) log.info("Payout tx already published for {} {}", trade.getClass().getName(), trade.getId());
else throw e;
}
}
}
} else {
log.info("Payout tx already published for {} {}", trade.getClass().getSimpleName(), trade.getId());
} }
SignedWitness signedWitness = message.getSignedWitness(); SignedWitness signedWitness = message.getSignedWitness();
@ -115,4 +82,48 @@ public class ProcessPaymentReceivedMessage extends TradeTask {
failed(t); failed(t);
} }
} }
private void processPayoutTx(PaymentReceivedMessage message) {
// import multisig hex
List<String> updatedMultisigHexes = new ArrayList<String>();
if (trade.getSeller().getUpdatedMultisigHex() != null) updatedMultisigHexes.add(trade.getSeller().getUpdatedMultisigHex());
if (trade.getArbitrator().getUpdatedMultisigHex() != null) updatedMultisigHexes.add(trade.getArbitrator().getUpdatedMultisigHex());
if (!updatedMultisigHexes.isEmpty()) trade.getWallet().importMultisigHex(updatedMultisigHexes.toArray(new String[0])); // TODO (monero-project): fails if multisig hex imported individually
// sync and save wallet
trade.syncWallet();
trade.saveWallet();
// handle if payout tx not published
if (!trade.isPayoutPublished()) {
// wait to sign and publish payout tx if defer flag set (seller recently saw payout tx arrive at buyer)
boolean isSigned = message.getSignedPayoutTxHex() != null;
if (trade instanceof ArbitratorTrade && !isSigned && message.isDeferPublishPayout()) {
log.info("Deferring signing and publishing payout tx for {} {}", trade.getClass().getSimpleName(), trade.getId());
GenUtils.waitFor(Trade.DEFER_PUBLISH_MS);
trade.syncWallet();
}
// verify and publish payout tx
if (!trade.isPayoutPublished()) {
if (isSigned) {
log.info("{} publishing signed payout tx from seller", trade.getClass().getSimpleName());
trade.verifyPayoutTx(message.getSignedPayoutTxHex(), false, true);
} else {
log.info("{} verifying, signing, and publishing seller's payout tx", trade.getClass().getSimpleName());
try {
trade.verifyPayoutTx(message.getUnsignedPayoutTxHex(), true, true);
} catch (Exception e) {
if (trade.isPayoutPublished()) log.info("Payout tx already published for {} {}", trade.getClass().getName(), trade.getId());
else throw e;
}
}
}
} else {
log.info("Payout tx already published for {} {}", trade.getClass().getSimpleName(), trade.getId());
if (message.getSignedPayoutTxHex() != null && !trade.isPayoutConfirmed()) trade.verifyPayoutTx(message.getSignedPayoutTxHex(), false, true);
}
}
} }