use of io.bitsquare.trade.Contract in project bitsquare by bitsquare.
the class DisputeManager method sendDisputeDirectMessage.
// traders send msg to the arbitrator or arbitrator to 1 trader (trader to trader is not allowed)
public DisputeCommunicationMessage sendDisputeDirectMessage(Dispute dispute, String text, ArrayList<Attachment> attachments) {
DisputeCommunicationMessage disputeCommunicationMessage = new DisputeCommunicationMessage(dispute.getTradeId(), dispute.getTraderPubKeyRing().hashCode(), isTrader(dispute), text, p2PService.getAddress());
disputeCommunicationMessage.addAllAttachments(attachments);
PubKeyRing receiverPubKeyRing = null;
NodeAddress peerNodeAddress = null;
if (isTrader(dispute)) {
dispute.addDisputeMessage(disputeCommunicationMessage);
receiverPubKeyRing = dispute.getArbitratorPubKeyRing();
peerNodeAddress = dispute.getContract().arbitratorNodeAddress;
} else if (isArbitrator(dispute)) {
if (!disputeCommunicationMessage.isSystemMessage())
dispute.addDisputeMessage(disputeCommunicationMessage);
receiverPubKeyRing = dispute.getTraderPubKeyRing();
Contract contract = dispute.getContract();
if (contract.getBuyerPubKeyRing().equals(receiverPubKeyRing))
peerNodeAddress = contract.getBuyerNodeAddress();
else
peerNodeAddress = contract.getSellerNodeAddress();
} else {
log.error("That must not happen. Trader cannot communicate to other trader.");
}
if (receiverPubKeyRing != null) {
log.trace("sendDisputeDirectMessage to peerAddress " + peerNodeAddress);
p2PService.sendEncryptedMailboxMessage(peerNodeAddress, receiverPubKeyRing, disputeCommunicationMessage, new SendMailboxMessageListener() {
@Override
public void onArrived() {
disputeCommunicationMessage.setArrived(true);
}
@Override
public void onStoredInMailbox() {
disputeCommunicationMessage.setStoredInMailbox(true);
}
@Override
public void onFault(String errorMessage) {
log.error("sendEncryptedMessage failed");
}
});
}
return disputeCommunicationMessage;
}
use of io.bitsquare.trade.Contract in project bitsquare by bitsquare.
the class DisputeManager method sendDisputeResultMessage.
// arbitrator send result to trader
public void sendDisputeResultMessage(DisputeResult disputeResult, Dispute dispute, String text) {
DisputeCommunicationMessage disputeCommunicationMessage = new DisputeCommunicationMessage(dispute.getTradeId(), dispute.getTraderPubKeyRing().hashCode(), false, text, p2PService.getAddress());
dispute.addDisputeMessage(disputeCommunicationMessage);
disputeResult.setDisputeCommunicationMessage(disputeCommunicationMessage);
NodeAddress peerNodeAddress;
Contract contract = dispute.getContract();
if (contract.getBuyerPubKeyRing().equals(dispute.getTraderPubKeyRing()))
peerNodeAddress = contract.getBuyerNodeAddress();
else
peerNodeAddress = contract.getSellerNodeAddress();
p2PService.sendEncryptedMailboxMessage(peerNodeAddress, dispute.getTraderPubKeyRing(), new DisputeResultMessage(disputeResult, p2PService.getAddress()), new SendMailboxMessageListener() {
@Override
public void onArrived() {
disputeCommunicationMessage.setArrived(true);
}
@Override
public void onStoredInMailbox() {
disputeCommunicationMessage.setStoredInMailbox(true);
}
@Override
public void onFault(String errorMessage) {
log.error("sendEncryptedMessage failed");
}
});
}
use of io.bitsquare.trade.Contract in project bitsquare by bitsquare.
the class DisputeManager method onDisputeResultMessage.
// We get that message at both peers. The dispute object is in context of the trader
private void onDisputeResultMessage(DisputeResultMessage disputeResultMessage) {
DisputeResult disputeResult = disputeResultMessage.disputeResult;
if (!isArbitrator(disputeResult)) {
final String tradeId = disputeResult.tradeId;
Optional<Dispute> disputeOptional = findDispute(tradeId, disputeResult.traderId);
final String uid = disputeResultMessage.getUID();
if (disputeOptional.isPresent()) {
cleanupRetryMap(uid);
Dispute dispute = disputeOptional.get();
DisputeCommunicationMessage disputeCommunicationMessage = disputeResult.getDisputeCommunicationMessage();
if (!dispute.getDisputeCommunicationMessagesAsObservableList().contains(disputeCommunicationMessage))
dispute.addDisputeMessage(disputeCommunicationMessage);
else
log.warn("We got a dispute mail msg what we have already stored. TradeId = " + disputeCommunicationMessage.getTradeId());
dispute.setIsClosed(true);
if (dispute.disputeResultProperty().get() != null)
log.warn("We got already a dispute result. That should only happen if a dispute needs to be closed " + "again because the first close did not succeed. TradeId = " + tradeId);
dispute.setDisputeResult(disputeResult);
// We need to avoid publishing the tx from both traders as it would create problems with zero confirmation withdrawals
// There would be different transactions if both sign and publish (signers: once buyer+arb, once seller+arb)
// The tx publisher is the winner or in case both get 50% the buyer, as the buyer has more inventive to publish the tx as he receives
// more BTC as he has deposited
final Contract contract = dispute.getContract();
boolean isBuyer = keyRing.getPubKeyRing().equals(contract.getBuyerPubKeyRing());
DisputeResult.Winner publisher = disputeResult.getWinner();
// Default isLoserPublisher is set to false
if (disputeResult.isLoserPublisher()) {
// we invert the logic
if (publisher == DisputeResult.Winner.BUYER)
publisher = DisputeResult.Winner.SELLER;
else if (publisher == DisputeResult.Winner.SELLER)
publisher = DisputeResult.Winner.BUYER;
}
if ((isBuyer && publisher == DisputeResult.Winner.BUYER) || (!isBuyer && publisher == DisputeResult.Winner.SELLER) || (isBuyer && publisher == DisputeResult.Winner.STALE_MATE)) {
final Optional<Trade> tradeOptional = tradeManager.getTradeById(tradeId);
Transaction payoutTx = null;
if (tradeOptional.isPresent()) {
payoutTx = tradeOptional.get().getPayoutTx();
} else {
final Optional<Tradable> tradableOptional = closedTradableManager.getTradableById(tradeId);
if (tradableOptional.isPresent() && tradableOptional.get() instanceof Trade) {
payoutTx = ((Trade) tradableOptional.get()).getPayoutTx();
}
}
if (payoutTx == null) {
if (dispute.getDepositTxSerialized() != null) {
try {
log.debug("do payout Transaction ");
AddressEntry multiSigAddressEntry = walletService.getOrCreateAddressEntry(dispute.getTradeId(), AddressEntry.Context.MULTI_SIG);
Transaction signedDisputedPayoutTx = tradeWalletService.traderSignAndFinalizeDisputedPayoutTx(dispute.getDepositTxSerialized(), disputeResult.getArbitratorSignature(), disputeResult.getBuyerPayoutAmount(), disputeResult.getSellerPayoutAmount(), disputeResult.getArbitratorPayoutAmount(), contract.getBuyerPayoutAddressString(), contract.getSellerPayoutAddressString(), disputeResult.getArbitratorAddressAsString(), multiSigAddressEntry.getKeyPair(), contract.getBuyerMultiSigPubKey(), contract.getSellerMultiSigPubKey(), disputeResult.getArbitratorPubKey());
Transaction committedDisputedPayoutTx = tradeWalletService.addTransactionToWallet(signedDisputedPayoutTx);
log.debug("broadcast committedDisputedPayoutTx");
tradeWalletService.broadcastTx(committedDisputedPayoutTx, new FutureCallback<Transaction>() {
@Override
public void onSuccess(Transaction transaction) {
log.debug("BroadcastTx succeeded. Transaction:" + transaction);
// after successful publish we send peer the tx
dispute.setDisputePayoutTxId(transaction.getHashAsString());
sendPeerPublishedPayoutTxMessage(transaction, dispute, contract);
// set state after payout as we call swapTradeEntryToAvailableEntry
if (tradeManager.getTradeById(dispute.getTradeId()).isPresent())
tradeManager.closeDisputedTrade(dispute.getTradeId());
else {
Optional<OpenOffer> openOfferOptional = openOfferManager.getOpenOfferById(dispute.getTradeId());
if (openOfferOptional.isPresent())
openOfferManager.closeOpenOffer(openOfferOptional.get().getOffer());
}
}
@Override
public void onFailure(@NotNull Throwable t) {
log.error(t.getMessage());
}
});
} catch (AddressFormatException | WalletException | TransactionVerificationException e) {
e.printStackTrace();
log.error("Error at traderSignAndFinalizeDisputedPayoutTx " + e.getMessage());
}
} else {
log.warn("DepositTx is null. TradeId = " + tradeId);
}
} else {
log.warn("We got already a payout tx. That might be the case if the other peer did not get the " + "payout tx and opened a dispute. TradeId = " + tradeId);
dispute.setDisputePayoutTxId(payoutTx.getHashAsString());
sendPeerPublishedPayoutTxMessage(payoutTx, dispute, contract);
}
} else {
log.trace("We don't publish the tx as we are not the winning party.");
// Clean up tangling trades
if (dispute.disputeResultProperty().get() != null && dispute.isClosed() && tradeManager.getTradeById(dispute.getTradeId()).isPresent())
tradeManager.closeDisputedTrade(dispute.getTradeId());
}
} else {
log.debug("We got a dispute result msg but we don't have a matching dispute. " + "That might happen when we get the disputeResultMessage before the dispute was created. " + "We try again after 2 sec. to apply the disputeResultMessage. TradeId = " + tradeId);
if (!delayMsgMap.containsKey(uid)) {
// We delay2 sec. to be sure the comm. msg gets added first
Timer timer = UserThread.runAfter(() -> onDisputeResultMessage(disputeResultMessage), 2);
delayMsgMap.put(uid, timer);
} else {
log.warn("We got a dispute result msg after we already repeated to apply the message after a delay. " + "That should never happen. TradeId = " + tradeId);
}
}
} else {
log.error("Arbitrator received disputeResultMessage. That must never happen.");
}
}
use of io.bitsquare.trade.Contract in project bitsquare by bitsquare.
the class DisputeManager method sendPeerOpenedDisputeMessage.
// arbitrator sends that to trading peer when he received openDispute request
private void sendPeerOpenedDisputeMessage(Dispute disputeFromOpener) {
Contract contractFromOpener = disputeFromOpener.getContract();
PubKeyRing pubKeyRing = disputeFromOpener.isDisputeOpenerIsBuyer() ? contractFromOpener.getSellerPubKeyRing() : contractFromOpener.getBuyerPubKeyRing();
Dispute dispute = new Dispute(disputeStorage, disputeFromOpener.getTradeId(), pubKeyRing.hashCode(), !disputeFromOpener.isDisputeOpenerIsBuyer(), !disputeFromOpener.isDisputeOpenerIsOfferer(), pubKeyRing, disputeFromOpener.getTradeDate(), contractFromOpener, disputeFromOpener.getContractHash(), disputeFromOpener.getDepositTxSerialized(), disputeFromOpener.getPayoutTxSerialized(), disputeFromOpener.getDepositTxId(), disputeFromOpener.getPayoutTxId(), disputeFromOpener.getContractAsJson(), disputeFromOpener.getOffererContractSignature(), disputeFromOpener.getTakerContractSignature(), disputeFromOpener.getArbitratorPubKeyRing(), disputeFromOpener.isSupportTicket());
final Optional<Dispute> storedDisputeOptional = findDispute(dispute.getTradeId(), dispute.getTraderId());
if (!storedDisputeOptional.isPresent()) {
DisputeCommunicationMessage disputeCommunicationMessage = new DisputeCommunicationMessage(dispute.getTradeId(), keyRing.getPubKeyRing().hashCode(), true, "System message: " + (dispute.isSupportTicket() ? "Your trading peer has requested support due technical problems. Please wait for further instructions." : "Your trading peer has requested a dispute.\n\n" + disputeInfo), p2PService.getAddress());
disputeCommunicationMessage.setIsSystemMessage(true);
dispute.addDisputeMessage(disputeCommunicationMessage);
disputes.add(dispute);
disputesObservableList.add(dispute);
// we mirrored dispute already!
Contract contract = dispute.getContract();
PubKeyRing peersPubKeyRing = dispute.isDisputeOpenerIsBuyer() ? contract.getBuyerPubKeyRing() : contract.getSellerPubKeyRing();
NodeAddress peerNodeAddress = dispute.isDisputeOpenerIsBuyer() ? contract.getBuyerNodeAddress() : contract.getSellerNodeAddress();
log.trace("sendPeerOpenedDisputeMessage to peerAddress " + peerNodeAddress);
p2PService.sendEncryptedMailboxMessage(peerNodeAddress, peersPubKeyRing, new PeerOpenedDisputeMessage(dispute, p2PService.getAddress()), new SendMailboxMessageListener() {
@Override
public void onArrived() {
disputeCommunicationMessage.setArrived(true);
}
@Override
public void onStoredInMailbox() {
disputeCommunicationMessage.setStoredInMailbox(true);
}
@Override
public void onFault(String errorMessage) {
log.error("sendEncryptedMessage failed");
}
});
} else {
log.warn("We got a dispute already open for that trade and trading peer.\n" + "TradeId = " + dispute.getTradeId());
}
}
use of io.bitsquare.trade.Contract in project bitsquare by bitsquare.
the class DisputeSummaryWindow method addContent.
private void addContent() {
Contract contract = dispute.getContract();
if (dispute.disputeResultProperty().get() == null)
disputeResult = new DisputeResult(dispute.getTradeId(), dispute.getTraderId());
else
disputeResult = dispute.disputeResultProperty().get();
peersDisputeOptional = disputeManager.getDisputesAsObservableList().stream().filter(d -> dispute.getTradeId().equals(d.getTradeId()) && dispute.getTraderId() != d.getTraderId()).findFirst();
addInfoPane();
if (!dispute.isSupportTicket())
addCheckboxes();
addTradeAmountPayoutControls();
addFeeControls();
addPayoutAmountTextFields();
addReasonControls();
boolean applyPeersDisputeResult = peersDisputeOptional.isPresent() && peersDisputeOptional.get().isClosed();
if (applyPeersDisputeResult) {
// If the other peers dispute has been closed we apply the result to ourselves
DisputeResult peersDisputeResult = peersDisputeOptional.get().disputeResultProperty().get();
disputeResult.setBuyerPayoutAmount(peersDisputeResult.getBuyerPayoutAmount());
disputeResult.setSellerPayoutAmount(peersDisputeResult.getSellerPayoutAmount());
disputeResult.setArbitratorPayoutAmount(peersDisputeResult.getArbitratorPayoutAmount());
disputeResult.setDisputeFeePolicy(peersDisputeResult.getDisputeFeePolicy());
disputeResult.setWinner(peersDisputeResult.getWinner());
disputeResult.setLoserIsPublisher(peersDisputeResult.isLoserPublisher());
disputeResult.setReason(peersDisputeResult.getReason());
disputeResult.setSummaryNotes(peersDisputeResult.summaryNotesProperty().get());
if (disputeResult.getBuyerPayoutAmount() != null) {
log.debug("buyerPayoutAmount " + disputeResult.getBuyerPayoutAmount().toFriendlyString());
log.debug("sellerPayoutAmount " + disputeResult.getSellerPayoutAmount().toFriendlyString());
log.debug("arbitratorPayoutAmount " + disputeResult.getArbitratorPayoutAmount().toFriendlyString());
}
buyerIsWinnerRadioButton.setDisable(true);
sellerIsWinnerRadioButton.setDisable(true);
shareRadioButton.setDisable(true);
customRadioButton.setDisable(true);
loserPaysFeeRadioButton.setDisable(true);
splitFeeRadioButton.setDisable(true);
waiveFeeRadioButton.setDisable(true);
buyerPayoutAmountInputTextField.setDisable(true);
sellerPayoutAmountInputTextField.setDisable(true);
arbitratorPayoutAmountInputTextField.setDisable(true);
buyerPayoutAmountInputTextField.setEditable(false);
sellerPayoutAmountInputTextField.setEditable(false);
arbitratorPayoutAmountInputTextField.setEditable(false);
reasonWasBugRadioButton.setDisable(true);
reasonWasUsabilityIssueRadioButton.setDisable(true);
reasonProtocolViolationRadioButton.setDisable(true);
reasonNoReplyRadioButton.setDisable(true);
reasonWasScamRadioButton.setDisable(true);
reasonWasOtherRadioButton.setDisable(true);
isLoserPublisherCheckBox.setDisable(true);
isLoserPublisherCheckBox.setSelected(peersDisputeResult.isLoserPublisher());
calculatePayoutAmounts(disputeResult.getDisputeFeePolicy());
applyTradeAmountRadioButtonStates();
} else {
applyPayoutAmounts(disputeResult.disputeFeePolicyProperty().get(), tradeAmountToggleGroup.selectedToggleProperty().get());
feePaymentPolicyChanged = Bindings.createObjectBinding(() -> new Tuple2<>(disputeResult.disputeFeePolicyProperty().get(), tradeAmountToggleGroup.selectedToggleProperty().get()), disputeResult.disputeFeePolicyProperty(), tradeAmountToggleGroup.selectedToggleProperty());
feePaymentPolicyListener = (observable, oldValue, newValue) -> applyPayoutAmounts(newValue.first, newValue.second);
feePaymentPolicyChanged.addListener(feePaymentPolicyListener);
isLoserPublisherCheckBox.setSelected(false);
}
setFeeRadioButtonState();
setReasonRadioButtonState();
addSummaryNotes();
addButtons(contract);
}
Aggregations