arbitrator sends same dispute payout tx to both peers on resolve w/ grpc

fix npe in trade.get*DepositTx()
This commit is contained in:
woodser 2023-02-22 13:06:22 -05:00
parent 55650c495b
commit ce579b78ca
5 changed files with 18 additions and 18 deletions

View file

@ -170,14 +170,17 @@ public class CoreDisputesService {
}
applyPayoutAmountsToDisputeResult(payout, winningDispute, disputeResult, customWinnerAmount);
// close dispute ticket
closeDisputeTicket(arbitrationManager, winningDispute, disputeResult, null, () -> {
// create dispute payout tx
MoneroTxWallet disputePayoutTx = arbitrationManager.createDisputePayoutTx(trade, winningDispute.getContract(), disputeResult, false);
// close winning dispute ticket
closeDisputeTicket(arbitrationManager, winningDispute, disputeResult, disputePayoutTx, () -> {
arbitrationManager.requestPersistence();
}, (errMessage, err) -> {
throw new IllegalStateException(errMessage, err);
});
// close peer's dispute ticket
// close loser's dispute ticket
var peersDisputeOptional = arbitrationManager.getDisputesAsObservableList().stream()
.filter(d -> tradeId.equals(d.getTradeId()) && winningDispute.getTraderId() != d.getTraderId())
.findFirst();
@ -186,7 +189,7 @@ public class CoreDisputesService {
var peerDisputeResult = createDisputeResult(peerDispute, winner, reason, summaryNotes, closeDate);
peerDisputeResult.setBuyerPayoutAmount(disputeResult.getBuyerPayoutAmount());
peerDisputeResult.setSellerPayoutAmount(disputeResult.getSellerPayoutAmount());
closeDisputeTicket(arbitrationManager, peerDispute, peerDisputeResult, null, () -> {
closeDisputeTicket(arbitrationManager, peerDispute, peerDisputeResult, disputePayoutTx, () -> {
arbitrationManager.requestPersistence();
}, (errMessage, err) -> {
throw new IllegalStateException(errMessage, err);

View file

@ -708,7 +708,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
if (trade == null) throw new RuntimeException("Dispute trade " + dispute.getTradeId() + " does not exist");
// create dispute payout tx if not given
if (payoutTx == null) payoutTx = createDisputePayoutTx(trade, dispute, disputeResult, false); // can be null if already published or we don't have receiver's multisig hex
if (payoutTx == null) payoutTx = createDisputePayoutTx(trade, dispute.getContract(), disputeResult, false); // can be null if already published or we don't have receiver's multisig hex
// persist result in dispute's chat message once
boolean resending = disputeResult.getChatMessage() != null;
@ -814,15 +814,14 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
// Utils
///////////////////////////////////////////////////////////////////////////////////////////
public MoneroTxWallet createDisputePayoutTx(Trade trade, Dispute dispute, DisputeResult disputeResult, boolean skipMultisigImport) {
public MoneroTxWallet createDisputePayoutTx(Trade trade, Contract contract, DisputeResult disputeResult, boolean skipMultisigImport) {
// sync and save wallet
trade.syncWallet();
trade.saveWallet();
// create unsigned dispute payout tx if not already published and arbitrator has trader's updated multisig info
TradePeer receiver = trade.getTradePeer(dispute.getTraderPubKeyRing());
if (!trade.isPayoutPublished() && receiver.getUpdatedMultisigHex() != null) {
// create unsigned dispute payout tx if not already published
if (!trade.isPayoutPublished()) {
MoneroWallet multisigWallet = trade.getWallet();
// import multisig hex
@ -840,10 +839,9 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
try {
// trade wallet must be synced
if (trade.getWallet().isMultisigImportNeeded()) throw new RuntimeException("Arbitrator's wallet needs updated multisig hex to create payout tx which means a trader must have already broadcast the payout tx for trade " + dispute.getTradeId());
if (trade.getWallet().isMultisigImportNeeded()) throw new RuntimeException("Arbitrator's wallet needs updated multisig hex to create payout tx which means a trader must have already broadcast the payout tx for trade " + trade.getId());
// collect winner and loser payout address and amounts
Contract contract = dispute.getContract();
String winnerPayoutAddress = disputeResult.getWinner() == Winner.BUYER ?
(contract.isBuyerMakerAndSellerTaker() ? contract.getMakerPayoutAddressString() : contract.getTakerPayoutAddressString()) :
(contract.isBuyerMakerAndSellerTaker() ? contract.getTakerPayoutAddressString() : contract.getMakerPayoutAddressString());

View file

@ -292,7 +292,7 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
}
} else {
if (trade.isPayoutPublished()) log.info("Dispute payout tx already published for {} {}", trade.getClass().getSimpleName(), trade.getId());
else if (disputeClosedMessage.getUnsignedPayoutTxHex() == null) log.info("{} did not receive unsigned dispute payout tx for trade {} because the arbitrator did not have their updated multisig info (can happen if trader went offline after trade started)", trade.getClass().getName(), trade.getId());
else if (disputeClosedMessage.getUnsignedPayoutTxHex() == null) log.info("{} did not receive unsigned dispute payout tx for trade {} because the arbitrator did not have their updated multisig info (can happen if trader went offline after trade started)", trade.getClass().getSimpleName(), trade.getId());
}
// We use the chatMessage as we only persist those not the DisputeClosedMessage.
@ -430,7 +430,7 @@ public final class ArbitrationManager extends DisputeManager<ArbitrationDisputeL
// TODO (monero-project): creating tx will require exchanging updated multisig hex if message needs reprocessed. provide weight with describe_transfer so fee can be estimated?
MoneroTxWallet feeEstimateTx = null;
try {
feeEstimateTx = createDisputePayoutTx(trade, dispute, disputeResult, true);
feeEstimateTx = createDisputePayoutTx(trade, dispute.getContract(), disputeResult, true);
} catch (Exception e) {
log.warn("Could not recreate dispute payout tx to verify fee: " + e.getMessage());
}

View file

@ -1059,7 +1059,7 @@ public abstract class Trade implements Tradable, Model {
private MoneroTx getDepositTx(TradePeer trader) {
String depositId = trader.getDepositTxHash();
try {
if (trader == null || !trader.getDepositTx().isConfirmed()) {
if (trader.getDepositTx() == null || !trader.getDepositTx().isConfirmed()) {
trader.setDepositTx(getTxFromWalletOrDaemon(depositId));
}
return trader.getDepositTx();
@ -1578,8 +1578,7 @@ public abstract class Trade implements Tradable, Model {
@Nullable
public MoneroTxWallet getPayoutTx() {
if (payoutTx == null)
payoutTx = payoutTxId != null ? xmrWalletService.getWallet().getTx(payoutTxId) : null;
if (payoutTx == null) payoutTx = payoutTxId == null ? null : xmrWalletService.getWallet().getTx(payoutTxId);
return payoutTx;
}

View file

@ -590,8 +590,8 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
closeTicketButton.setOnAction(e -> {
// create payout tx
MoneroTxWallet payoutTx = arbitrationManager.createDisputePayoutTx(trade, dispute, disputeResult, false);
// get or create payout tx
MoneroTxWallet payoutTx = trade.isPayoutPublished() ? trade.getPayoutTx() : arbitrationManager.createDisputePayoutTx(trade, dispute.getContract(), disputeResult, false);
// show confirmation
if (dispute.getSupportType() == SupportType.ARBITRATION &&