mirror of
https://github.com/haveno-dex/haveno.git
synced 2024-12-24 23:09:36 -05:00
arbitrator sends original unsigned payout tx if published
synchronize on trade when processing dispute messages
This commit is contained in:
parent
17ac09fa4d
commit
6dca11f471
@ -36,7 +36,6 @@ import java.util.List;
|
||||
import java.util.Optional;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import monero.wallet.model.MoneroTxWallet;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
import static java.lang.String.format;
|
||||
@ -171,25 +170,25 @@ public class CoreDisputesService {
|
||||
applyPayoutAmountsToDisputeResult(payout, winningDispute, disputeResult, customWinnerAmount);
|
||||
|
||||
// create dispute payout tx
|
||||
MoneroTxWallet disputePayoutTx = arbitrationManager.createDisputePayoutTx(trade, winningDispute.getContract(), disputeResult, false);
|
||||
trade.getProcessModel().setUnsignedPayoutTx(arbitrationManager.createDisputePayoutTx(trade, winningDispute.getContract(), disputeResult, false));
|
||||
|
||||
// close winning dispute ticket
|
||||
closeDisputeTicket(arbitrationManager, winningDispute, disputeResult, disputePayoutTx, () -> {
|
||||
closeDisputeTicket(arbitrationManager, winningDispute, disputeResult, () -> {
|
||||
arbitrationManager.requestPersistence();
|
||||
}, (errMessage, err) -> {
|
||||
throw new IllegalStateException(errMessage, err);
|
||||
});
|
||||
|
||||
// close loser's dispute ticket
|
||||
var peersDisputeOptional = arbitrationManager.getDisputesAsObservableList().stream()
|
||||
var loserDisputeOptional = arbitrationManager.getDisputesAsObservableList().stream()
|
||||
.filter(d -> tradeId.equals(d.getTradeId()) && winningDispute.getTraderId() != d.getTraderId())
|
||||
.findFirst();
|
||||
if (!peersDisputeOptional.isPresent()) throw new IllegalStateException("could not find peer dispute");
|
||||
var peerDispute = peersDisputeOptional.get();
|
||||
var peerDisputeResult = createDisputeResult(peerDispute, winner, reason, summaryNotes, closeDate);
|
||||
peerDisputeResult.setBuyerPayoutAmount(disputeResult.getBuyerPayoutAmount());
|
||||
peerDisputeResult.setSellerPayoutAmount(disputeResult.getSellerPayoutAmount());
|
||||
closeDisputeTicket(arbitrationManager, peerDispute, peerDisputeResult, disputePayoutTx, () -> {
|
||||
if (!loserDisputeOptional.isPresent()) throw new IllegalStateException("could not find peer dispute");
|
||||
var loserDispute = loserDisputeOptional.get();
|
||||
var loserDisputeResult = createDisputeResult(loserDispute, winner, reason, summaryNotes, closeDate);
|
||||
loserDisputeResult.setBuyerPayoutAmount(disputeResult.getBuyerPayoutAmount());
|
||||
loserDisputeResult.setSellerPayoutAmount(disputeResult.getSellerPayoutAmount());
|
||||
closeDisputeTicket(arbitrationManager, loserDispute, loserDisputeResult, () -> {
|
||||
arbitrationManager.requestPersistence();
|
||||
}, (errMessage, err) -> {
|
||||
throw new IllegalStateException(errMessage, err);
|
||||
@ -248,7 +247,7 @@ public class CoreDisputesService {
|
||||
}
|
||||
}
|
||||
|
||||
public void closeDisputeTicket(DisputeManager disputeManager, Dispute dispute, DisputeResult disputeResult, MoneroTxWallet payoutTx, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
public void closeDisputeTicket(DisputeManager disputeManager, Dispute dispute, DisputeResult disputeResult, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
DisputeResult.Reason reason = disputeResult.getReason();
|
||||
|
||||
String role = Res.get("shared.arbitrator");
|
||||
@ -279,7 +278,7 @@ public class CoreDisputesService {
|
||||
String summaryText = DisputeSummaryVerification.signAndApply(disputeManager, disputeResult, textToSign);
|
||||
summaryText += Res.get("disputeSummaryWindow.close.nextStepsForRefundAgentArbitration");
|
||||
|
||||
disputeManager.closeDisputeTicket(disputeResult, dispute, summaryText, payoutTx, () -> {
|
||||
disputeManager.closeDisputeTicket(disputeResult, dispute, summaryText, () -> {
|
||||
dispute.setDisputeResult(disputeResult);
|
||||
dispute.setIsClosed();
|
||||
resultHandler.handleResult();
|
||||
|
@ -443,7 +443,14 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||
Dispute dispute = message.getDispute();
|
||||
log.info("{}.onDisputeOpenedMessage() with trade {}, dispute {}", getClass().getSimpleName(), dispute.getTradeId(), dispute.getId());
|
||||
|
||||
Trade trade = null;
|
||||
// get trade
|
||||
Trade trade = tradeManager.getTrade(dispute.getTradeId());
|
||||
if (trade == null) {
|
||||
log.warn("Dispute trade {} does not exist", dispute.getTradeId());
|
||||
return;
|
||||
}
|
||||
|
||||
synchronized (trade) {
|
||||
String errorMessage = null;
|
||||
PubKeyRing senderPubKeyRing = null;
|
||||
try {
|
||||
@ -470,13 +477,6 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||
throw e;
|
||||
}
|
||||
|
||||
// get trade
|
||||
trade = tradeManager.getTrade(dispute.getTradeId());
|
||||
if (trade == null) {
|
||||
log.warn("Dispute trade {} does not exist", dispute.getTradeId());
|
||||
return;
|
||||
}
|
||||
|
||||
// get sender
|
||||
senderPubKeyRing = trade.isArbitrator() ? (dispute.isDisputeOpenerIsBuyer() ? contract.getBuyerPubKeyRing() : contract.getSellerPubKeyRing()) : trade.getArbitrator().getPubKeyRing();
|
||||
TradePeer sender = trade.getTradePeer(senderPubKeyRing);
|
||||
@ -543,6 +543,7 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||
|
||||
requestPersistence();
|
||||
}
|
||||
}
|
||||
|
||||
// arbitrator sends dispute opened message to opener's peer
|
||||
private void sendDisputeOpenedMessageToPeer(Dispute disputeFromOpener,
|
||||
@ -700,16 +701,13 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||
}
|
||||
|
||||
// arbitrator sends result to trader when their dispute is closed
|
||||
public void closeDisputeTicket(DisputeResult disputeResult, Dispute dispute, String summaryText, MoneroTxWallet payoutTx, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
public void closeDisputeTicket(DisputeResult disputeResult, Dispute dispute, String summaryText, ResultHandler resultHandler, FaultHandler faultHandler) {
|
||||
try {
|
||||
|
||||
// get trade
|
||||
Trade trade = tradeManager.getTrade(dispute.getTradeId());
|
||||
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.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;
|
||||
if (!resending) {
|
||||
@ -724,9 +722,15 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||
dispute.addAndPersistChatMessage(chatMessage);
|
||||
}
|
||||
|
||||
// create dispute closed message
|
||||
// create dispute payout tx if not published
|
||||
TradePeer receiver = trade.getTradePeer(dispute.getTraderPubKeyRing());
|
||||
String unsignedPayoutTxHex = payoutTx == null ? null : payoutTx.getTxSet().getMultisigTxHex();
|
||||
if (!trade.isPayoutPublished() && receiver.getUpdatedMultisigHex() != null) {
|
||||
trade.getProcessModel().setUnsignedPayoutTx(createDisputePayoutTx(trade, dispute.getContract(), disputeResult, false)); // can be null if we don't have receiver's multisig hex
|
||||
}
|
||||
|
||||
// create dispute closed message
|
||||
MoneroTxWallet unsignedPayoutTx = receiver.getUpdatedMultisigHex() == null ? null : trade.getProcessModel().getUnsignedPayoutTx();
|
||||
String unsignedPayoutTxHex = unsignedPayoutTx == null ? null : unsignedPayoutTx.getTxSet().getMultisigTxHex();
|
||||
TradePeer receiverPeer = receiver == trade.getBuyer() ? trade.getSeller() : trade.getBuyer();
|
||||
boolean deferPublishPayout = !resending && unsignedPayoutTxHex != null && receiverPeer.getUpdatedMultisigHex() != null && trade.getDisputeState().ordinal() >= Trade.DisputeState.ARBITRATOR_SAW_ARRIVED_DISPUTE_CLOSED_MSG.ordinal() ;
|
||||
DisputeClosedMessage disputeClosedMessage = new DisputeClosedMessage(disputeResult,
|
||||
@ -799,9 +803,9 @@ public abstract class DisputeManager<T extends DisputeList<Dispute>> extends Sup
|
||||
);
|
||||
|
||||
// save state
|
||||
if (payoutTx != null) {
|
||||
trade.setPayoutTx(payoutTx);
|
||||
trade.setPayoutTxHex(payoutTx.getTxSet().getMultisigTxHex());
|
||||
if (unsignedPayoutTx != null) {
|
||||
trade.setPayoutTx(unsignedPayoutTx);
|
||||
trade.setPayoutTxHex(unsignedPayoutTx.getTxSet().getMultisigTxHex());
|
||||
}
|
||||
trade.advanceDisputeState(Trade.DisputeState.ARBITRATOR_SENT_DISPUTE_CLOSED_MSG);
|
||||
requestPersistence();
|
||||
|
@ -169,6 +169,9 @@ public class ProcessModel implements Model, PersistablePayload {
|
||||
@Getter
|
||||
@Setter
|
||||
transient private MoneroTxWallet depositTxXmr;
|
||||
@Getter
|
||||
@Setter
|
||||
transient private MoneroTxWallet unsignedPayoutTx;
|
||||
@Nullable
|
||||
@Getter
|
||||
@Setter
|
||||
|
@ -58,7 +58,8 @@ public class ResendDisputeClosedMessageWithPayout extends TradeTask {
|
||||
for (Dispute dispute : disputes) {
|
||||
if (!dispute.isClosed()) continue; // dispute must be closed
|
||||
if (sender.getPubKeyRing().equals(dispute.getTraderPubKeyRing())) {
|
||||
HavenoUtils.arbitrationManager.closeDisputeTicket(dispute.getDisputeResultProperty().get(), dispute, dispute.getDisputeResultProperty().get().summaryNotesProperty().get(), null, () -> {
|
||||
log.info("Arbitrator resending DisputeClosedMessage for trade {} after receiving updated multisig hex", trade.getId());
|
||||
HavenoUtils.arbitrationManager.closeDisputeTicket(dispute.getDisputeResultProperty().get(), dispute, dispute.getDisputeResultProperty().get().summaryNotesProperty().get(), () -> {
|
||||
completeAux();
|
||||
}, (errMessage, err) -> {
|
||||
err.printStackTrace();
|
||||
|
@ -590,8 +590,13 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
|
||||
closeTicketButton.setOnAction(e -> {
|
||||
|
||||
// get or create payout tx
|
||||
MoneroTxWallet payoutTx = trade.isPayoutPublished() ? trade.getPayoutTx() : arbitrationManager.createDisputePayoutTx(trade, dispute.getContract(), disputeResult, false);
|
||||
// get or create dispute payout tx
|
||||
MoneroTxWallet payoutTx = null;
|
||||
if (trade.isPayoutPublished()) payoutTx = trade.getPayoutTx();
|
||||
else {
|
||||
payoutTx = arbitrationManager.createDisputePayoutTx(trade, dispute.getContract(), disputeResult, false);
|
||||
trade.getProcessModel().setUnsignedPayoutTx(payoutTx);
|
||||
}
|
||||
|
||||
// show confirmation
|
||||
if (dispute.getSupportType() == SupportType.ARBITRATION &&
|
||||
@ -600,9 +605,9 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
showPayoutTxConfirmation(contract,
|
||||
disputeResult,
|
||||
payoutTx,
|
||||
() -> doClose(closeTicketButton, payoutTx));
|
||||
() -> doClose(closeTicketButton));
|
||||
} else {
|
||||
doClose(closeTicketButton, payoutTx);
|
||||
doClose(closeTicketButton);
|
||||
}
|
||||
});
|
||||
|
||||
@ -654,7 +659,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
}
|
||||
}
|
||||
|
||||
private void doClose(Button closeTicketButton, MoneroTxWallet payoutTx) {
|
||||
private void doClose(Button closeTicketButton) {
|
||||
DisputeManager<? extends DisputeList<Dispute>> disputeManager = getDisputeManager(dispute);
|
||||
if (disputeManager == null) {
|
||||
return;
|
||||
@ -663,7 +668,7 @@ public class DisputeSummaryWindow extends Overlay<DisputeSummaryWindow> {
|
||||
summaryNotesTextArea.textProperty().unbindBidirectional(disputeResult.summaryNotesProperty());
|
||||
|
||||
disputeResult.setCloseDate(new Date());
|
||||
disputesService.closeDisputeTicket(disputeManager, dispute, disputeResult, payoutTx, () -> {
|
||||
disputesService.closeDisputeTicket(disputeManager, dispute, disputeResult, () -> {
|
||||
if (peersDisputeOptional.isPresent() && !peersDisputeOptional.get().isClosed() && !DevEnv.isDevMode()) {
|
||||
new Popup().attention(Res.get("disputeSummaryWindow.close.closePeer")).show();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user