Search in sources :

Example 1 with DisputeCommunicationMessage

use of bisq.core.arbitration.messages.DisputeCommunicationMessage in project bisq-core by bisq-network.

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.getDisputeResult();
    if (!isArbitrator(disputeResult)) {
        final String tradeId = disputeResult.getTradeId();
        Optional<Dispute> disputeOptional = findDispute(tradeId, disputeResult.getTraderId());
        final String uid = disputeResultMessage.getUid();
        if (disputeOptional.isPresent()) {
            cleanupRetryMap(uid);
            Dispute dispute = disputeOptional.get();
            DisputeCommunicationMessage disputeCommunicationMessage = disputeResult.getDisputeCommunicationMessage();
            if (!dispute.getDisputeCommunicationMessages().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)) {
                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 ");
                            byte[] multiSigPubKey = isBuyer ? contract.getBuyerMultiSigPubKey() : contract.getSellerMultiSigPubKey();
                            DeterministicKey multiSigKeyPair = walletService.getMultiSigKeyPair(dispute.getTradeId(), multiSigPubKey);
                            Transaction signedDisputedPayoutTx = tradeWalletService.traderSignAndFinalizeDisputedPayoutTx(dispute.getDepositTxSerialized(), disputeResult.getArbitratorSignature(), disputeResult.getBuyerPayoutAmount(), disputeResult.getSellerPayoutAmount(), contract.getBuyerPayoutAddressString(), contract.getSellerPayoutAddressString(), multiSigKeyPair, contract.getBuyerMultiSigPubKey(), contract.getSellerMultiSigPubKey(), disputeResult.getArbitratorPubKey());
                            Transaction committedDisputedPayoutTx = tradeWalletService.addTxToWallet(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());
                                }
                            }, 15);
                        } catch (AddressFormatException | WalletException | TransactionVerificationException e) {
                            e.printStackTrace();
                            log.error("Error at traderSignAndFinalizeDisputedPayoutTx " + e.getMessage());
                            throw new RuntimeException("Error at traderSignAndFinalizeDisputedPayoutTx " + e.toString());
                        }
                    } 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.");
    }
}
Also used : Tradable(bisq.core.trade.Tradable) Trade(bisq.core.trade.Trade) DisputeCommunicationMessage(bisq.core.arbitration.messages.DisputeCommunicationMessage) WalletException(bisq.core.btc.exceptions.WalletException) AddressFormatException(org.bitcoinj.core.AddressFormatException) Optional(java.util.Optional) TransactionVerificationException(bisq.core.btc.exceptions.TransactionVerificationException) Transaction(org.bitcoinj.core.Transaction) Timer(bisq.common.Timer) Contract(bisq.core.trade.Contract) DeterministicKey(org.bitcoinj.crypto.DeterministicKey)

Example 2 with DisputeCommunicationMessage

use of bisq.core.arbitration.messages.DisputeCommunicationMessage in project bisq-core by bisq-network.

the class DisputeManager method sendOpenNewDisputeMessage.

public void sendOpenNewDisputeMessage(Dispute dispute, boolean reOpen, ResultHandler resultHandler, FaultHandler faultHandler) {
    if (!disputes.contains(dispute)) {
        final Optional<Dispute> storedDisputeOptional = findDispute(dispute.getTradeId(), dispute.getTraderId());
        if (!storedDisputeOptional.isPresent() || reOpen) {
            String sysMsg = dispute.isSupportTicket() ? Res.get("support.youOpenedTicket") : Res.get("support.youOpenedDispute", disputeInfo);
            DisputeCommunicationMessage disputeCommunicationMessage = new DisputeCommunicationMessage(dispute.getTradeId(), keyRing.getPubKeyRing().hashCode(), false, Res.get("support.systemMsg", sysMsg), null, p2PService.getAddress(), new Date().getTime(), false, false, UUID.randomUUID().toString());
            disputeCommunicationMessage.setSystemMessage(true);
            dispute.addDisputeMessage(disputeCommunicationMessage);
            if (!reOpen) {
                disputes.add(dispute);
            }
            p2PService.sendEncryptedMailboxMessage(dispute.getContract().getArbitratorNodeAddress(), dispute.getArbitratorPubKeyRing(), new OpenNewDisputeMessage(dispute, p2PService.getAddress(), UUID.randomUUID().toString()), new SendMailboxMessageListener() {

                @Override
                public void onArrived() {
                    log.info("Message arrived at peer. tradeId={}", disputeCommunicationMessage.getTradeId());
                    disputeCommunicationMessage.setArrived(true);
                    resultHandler.handleResult();
                }

                @Override
                public void onStoredInMailbox() {
                    log.info("Message stored in mailbox. tradeId={}", disputeCommunicationMessage.getTradeId());
                    disputeCommunicationMessage.setStoredInMailbox(true);
                    resultHandler.handleResult();
                }

                @Override
                public void onFault(String errorMessage) {
                    log.error("sendEncryptedMailboxMessage failed. disputeCommunicationMessage=" + disputeCommunicationMessage);
                    faultHandler.handleFault("Sending dispute message failed: " + errorMessage, new MessageDeliveryFailedException());
                }
            });
        } else {
            final String msg = "We got a dispute already open for that trade and trading peer.\n" + "TradeId = " + dispute.getTradeId();
            log.warn(msg);
            faultHandler.handleFault(msg, new DisputeAlreadyOpenException());
        }
    } else {
        final String msg = "We got a dispute msg what we have already stored. TradeId = " + dispute.getTradeId();
        log.warn(msg);
        faultHandler.handleFault(msg, new DisputeAlreadyOpenException());
    }
}
Also used : OpenNewDisputeMessage(bisq.core.arbitration.messages.OpenNewDisputeMessage) SendMailboxMessageListener(bisq.network.p2p.SendMailboxMessageListener) DisputeCommunicationMessage(bisq.core.arbitration.messages.DisputeCommunicationMessage) Date(java.util.Date)

Example 3 with DisputeCommunicationMessage

use of bisq.core.arbitration.messages.DisputeCommunicationMessage in project bisq-core by bisq-network.

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.isDisputeOpenerIsMaker(), pubKeyRing, disputeFromOpener.getTradeDate().getTime(), contractFromOpener, disputeFromOpener.getContractHash(), disputeFromOpener.getDepositTxSerialized(), disputeFromOpener.getPayoutTxSerialized(), disputeFromOpener.getDepositTxId(), disputeFromOpener.getPayoutTxId(), disputeFromOpener.getContractAsJson(), disputeFromOpener.getMakerContractSignature(), disputeFromOpener.getTakerContractSignature(), disputeFromOpener.getArbitratorPubKeyRing(), disputeFromOpener.isSupportTicket());
    final Optional<Dispute> storedDisputeOptional = findDispute(dispute.getTradeId(), dispute.getTraderId());
    if (!storedDisputeOptional.isPresent()) {
        String sysMsg = dispute.isSupportTicket() ? Res.get("support.peerOpenedTicket") : Res.get("support.peerOpenedDispute", disputeInfo);
        DisputeCommunicationMessage disputeCommunicationMessage = new DisputeCommunicationMessage(dispute.getTradeId(), keyRing.getPubKeyRing().hashCode(), false, Res.get("support.systemMsg", sysMsg), null, p2PService.getAddress(), new Date().getTime(), false, false, UUID.randomUUID().toString());
        disputeCommunicationMessage.setSystemMessage(true);
        dispute.addDisputeMessage(disputeCommunicationMessage);
        disputes.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(), UUID.randomUUID().toString()), new SendMailboxMessageListener() {

            @Override
            public void onArrived() {
                log.info("Message arrived at peer. tradeId={}", disputeCommunicationMessage.getTradeId());
                disputeCommunicationMessage.setArrived(true);
            }

            @Override
            public void onStoredInMailbox() {
                log.info("Message stored in mailbox. tradeId={}", disputeCommunicationMessage.getTradeId());
                disputeCommunicationMessage.setStoredInMailbox(true);
            }

            @Override
            public void onFault(String errorMessage) {
                log.error("sendEncryptedMailboxMessage failed. disputeCommunicationMessage=" + disputeCommunicationMessage);
            }
        });
    } else {
        log.warn("We got a dispute already open for that trade and trading peer.\n" + "TradeId = " + dispute.getTradeId());
    }
}
Also used : PubKeyRing(bisq.common.crypto.PubKeyRing) PeerOpenedDisputeMessage(bisq.core.arbitration.messages.PeerOpenedDisputeMessage) NodeAddress(bisq.network.p2p.NodeAddress) SendMailboxMessageListener(bisq.network.p2p.SendMailboxMessageListener) Contract(bisq.core.trade.Contract) DisputeCommunicationMessage(bisq.core.arbitration.messages.DisputeCommunicationMessage) Date(java.util.Date)

Example 4 with DisputeCommunicationMessage

use of bisq.core.arbitration.messages.DisputeCommunicationMessage in project bisq-desktop by bisq-network.

the class TraderDisputeView method onSelectDispute.

private void onSelectDispute(Dispute dispute) {
    removeListenersOnSelectDispute();
    if (dispute == null) {
        if (root.getChildren().size() > 2)
            root.getChildren().remove(2);
        selectedDispute = null;
    } else if (selectedDispute != dispute) {
        this.selectedDispute = dispute;
        boolean isTrader = disputeManager.isTrader(selectedDispute);
        tableGroupHeadline = new TableGroupHeadline();
        tableGroupHeadline.setText(Res.get("support.messages"));
        AnchorPane.setTopAnchor(tableGroupHeadline, 10d);
        AnchorPane.setRightAnchor(tableGroupHeadline, 0d);
        AnchorPane.setBottomAnchor(tableGroupHeadline, 0d);
        AnchorPane.setLeftAnchor(tableGroupHeadline, 0d);
        disputeCommunicationMessages = selectedDispute.getDisputeCommunicationMessages();
        SortedList<DisputeCommunicationMessage> sortedList = new SortedList<>(disputeCommunicationMessages);
        sortedList.setComparator((o1, o2) -> new Date(o1.getDate()).compareTo(new Date(o2.getDate())));
        messageListView = new ListView<>(sortedList);
        messageListView.setId("message-list-view");
        messageListView.setMinHeight(150);
        AnchorPane.setTopAnchor(messageListView, 30d);
        AnchorPane.setRightAnchor(messageListView, 0d);
        AnchorPane.setLeftAnchor(messageListView, 0d);
        messagesAnchorPane = new AnchorPane();
        VBox.setVgrow(messagesAnchorPane, Priority.ALWAYS);
        inputTextArea = new TextArea();
        inputTextArea.setPrefHeight(70);
        inputTextArea.setWrapText(true);
        if (!(this instanceof ArbitratorDisputeView))
            inputTextArea.setPromptText(Res.get("support.input.prompt"));
        sendButton = new AutoTooltipButton(Res.get("support.send"));
        sendButton.setDefaultButton(true);
        sendButton.setOnAction(e -> onTrySendMessage());
        inputTextAreaTextSubscription = EasyBind.subscribe(inputTextArea.textProperty(), t -> sendButton.setDisable(t.isEmpty()));
        Button uploadButton = new AutoTooltipButton(Res.get("support.addAttachments"));
        uploadButton.setOnAction(e -> onRequestUpload());
        sendMsgInfoLabel = new AutoTooltipLabel();
        sendMsgInfoLabel.setVisible(false);
        sendMsgInfoLabel.setManaged(false);
        sendMsgInfoLabel.setPadding(new Insets(5, 0, 0, 0));
        sendMsgBusyAnimation = new BusyAnimation(false);
        if (!selectedDispute.isClosed()) {
            HBox buttonBox = new HBox();
            buttonBox.setSpacing(10);
            buttonBox.getChildren().addAll(sendButton, uploadButton, sendMsgBusyAnimation, sendMsgInfoLabel);
            if (!isTrader) {
                Button closeDisputeButton = new AutoTooltipButton(Res.get("support.closeTicket"));
                closeDisputeButton.setOnAction(e -> onCloseDispute(selectedDispute));
                closeDisputeButton.setDefaultButton(true);
                Pane spacer = new Pane();
                HBox.setHgrow(spacer, Priority.ALWAYS);
                buttonBox.getChildren().addAll(spacer, closeDisputeButton);
            }
            messagesInputBox = new VBox();
            messagesInputBox.setSpacing(10);
            messagesInputBox.getChildren().addAll(inputTextArea, buttonBox);
            VBox.setVgrow(buttonBox, Priority.ALWAYS);
            AnchorPane.setRightAnchor(messagesInputBox, 0d);
            AnchorPane.setBottomAnchor(messagesInputBox, 5d);
            AnchorPane.setLeftAnchor(messagesInputBox, 0d);
            AnchorPane.setBottomAnchor(messageListView, 120d);
            messagesAnchorPane.getChildren().addAll(tableGroupHeadline, messageListView, messagesInputBox);
        } else {
            AnchorPane.setBottomAnchor(messageListView, 0d);
            messagesAnchorPane.getChildren().addAll(tableGroupHeadline, messageListView);
        }
        messageListView.setCellFactory(new Callback<ListView<DisputeCommunicationMessage>, ListCell<DisputeCommunicationMessage>>() {

            @Override
            public ListCell<DisputeCommunicationMessage> call(ListView<DisputeCommunicationMessage> list) {
                return new ListCell<DisputeCommunicationMessage>() {

                    public ChangeListener<Boolean> sendMsgBusyAnimationListener;

                    final Pane bg = new Pane();

                    final ImageView arrow = new ImageView();

                    final Label headerLabel = new AutoTooltipLabel();

                    final Label messageLabel = new AutoTooltipLabel();

                    final Label copyIcon = new Label();

                    final HBox attachmentsBox = new HBox();

                    final AnchorPane messageAnchorPane = new AnchorPane();

                    final Label statusIcon = new Label();

                    final double arrowWidth = 15d;

                    final double attachmentsBoxHeight = 20d;

                    final double border = 10d;

                    final double bottomBorder = 25d;

                    final double padding = border + 10d;

                    final double msgLabelPaddingRight = padding + 20d;

                    {
                        bg.setMinHeight(30);
                        messageLabel.setWrapText(true);
                        headerLabel.setTextAlignment(TextAlignment.CENTER);
                        attachmentsBox.setSpacing(5);
                        statusIcon.getStyleClass().add("small-text");
                        copyIcon.setTooltip(new Tooltip(Res.get("shared.copyToClipboard")));
                        messageAnchorPane.getChildren().addAll(bg, arrow, headerLabel, messageLabel, copyIcon, attachmentsBox, statusIcon);
                        messageLabel.setOnMouseClicked(event -> {
                            if (2 > event.getClickCount()) {
                                return;
                            }
                            GUIUtil.showSelectableTextModal(headerLabel.getText(), messageLabel.getText());
                        });
                    }

                    @Override
                    public void updateItem(final DisputeCommunicationMessage item, boolean empty) {
                        super.updateItem(item, empty);
                        if (item != null && !empty) {
                            copyIcon.setOnMouseClicked(e -> Utilities.copyToClipboard(messageLabel.getText()));
                            /* messageAnchorPane.prefWidthProperty().bind(EasyBind.map(messageListView.widthProperty(),
                                        w -> (double) w - padding - GUIUtil.getScrollbarWidth(messageListView)));*/
                            if (!messageAnchorPane.prefWidthProperty().isBound())
                                messageAnchorPane.prefWidthProperty().bind(messageListView.widthProperty().subtract(padding + GUIUtil.getScrollbarWidth(messageListView)));
                            AnchorPane.setTopAnchor(bg, 15d);
                            AnchorPane.setBottomAnchor(bg, bottomBorder);
                            AnchorPane.setTopAnchor(headerLabel, 0d);
                            AnchorPane.setBottomAnchor(arrow, bottomBorder + 5d);
                            AnchorPane.setTopAnchor(messageLabel, 25d);
                            AnchorPane.setTopAnchor(copyIcon, 25d);
                            AnchorPane.setBottomAnchor(attachmentsBox, bottomBorder + 10);
                            boolean senderIsTrader = item.isSenderIsTrader();
                            boolean isMyMsg = isTrader ? senderIsTrader : !senderIsTrader;
                            arrow.setVisible(!item.isSystemMessage());
                            arrow.setManaged(!item.isSystemMessage());
                            statusIcon.setVisible(false);
                            headerLabel.getStyleClass().removeAll("message-header", "success-text", "highlight-static");
                            messageLabel.getStyleClass().removeAll("my-message", "message");
                            copyIcon.getStyleClass().removeAll("my-message", "message");
                            if (item.isSystemMessage()) {
                                headerLabel.getStyleClass().addAll("message-header", "success-text");
                                bg.setId("message-bubble-green");
                                messageLabel.getStyleClass().add("my-message");
                                copyIcon.getStyleClass().add("my-message");
                            } else if (isMyMsg) {
                                headerLabel.getStyleClass().add("highlight-static");
                                bg.setId("message-bubble-blue");
                                messageLabel.getStyleClass().add("my-message");
                                copyIcon.getStyleClass().add("my-message");
                                if (isTrader)
                                    arrow.setId("bubble_arrow_blue_left");
                                else
                                    arrow.setId("bubble_arrow_blue_right");
                                if (sendMsgBusyAnimationListener != null)
                                    sendMsgBusyAnimation.isRunningProperty().removeListener(sendMsgBusyAnimationListener);
                                sendMsgBusyAnimationListener = (observable, oldValue, newValue) -> {
                                    if (!newValue) {
                                        if (item.arrivedProperty().get())
                                            showArrivedIcon();
                                        else if (item.storedInMailboxProperty().get())
                                            showMailboxIcon();
                                    }
                                };
                                sendMsgBusyAnimation.isRunningProperty().addListener(sendMsgBusyAnimationListener);
                                if (item.arrivedProperty().get())
                                    showArrivedIcon();
                                else if (item.storedInMailboxProperty().get())
                                    showMailboxIcon();
                            // TODO show that icon on error
                            /*else if (sendMsgProgressIndicator.getProgress() == 0)
                                        showNotArrivedIcon();*/
                            } else {
                                headerLabel.getStyleClass().add("message-header");
                                bg.setId("message-bubble-grey");
                                messageLabel.getStyleClass().add("message");
                                copyIcon.getStyleClass().add("message");
                                if (isTrader)
                                    arrow.setId("bubble_arrow_grey_right");
                                else
                                    arrow.setId("bubble_arrow_grey_left");
                            }
                            if (item.isSystemMessage()) {
                                AnchorPane.setLeftAnchor(headerLabel, padding);
                                AnchorPane.setRightAnchor(headerLabel, padding);
                                AnchorPane.setLeftAnchor(bg, border);
                                AnchorPane.setRightAnchor(bg, border);
                                AnchorPane.setLeftAnchor(messageLabel, padding);
                                AnchorPane.setRightAnchor(messageLabel, msgLabelPaddingRight);
                                AnchorPane.setRightAnchor(copyIcon, padding);
                                AnchorPane.setLeftAnchor(attachmentsBox, padding);
                                AnchorPane.setRightAnchor(attachmentsBox, padding);
                            } else if (senderIsTrader) {
                                AnchorPane.setLeftAnchor(headerLabel, padding + arrowWidth);
                                AnchorPane.setLeftAnchor(bg, border + arrowWidth);
                                AnchorPane.setRightAnchor(bg, border);
                                AnchorPane.setLeftAnchor(arrow, border);
                                AnchorPane.setLeftAnchor(messageLabel, padding + arrowWidth);
                                AnchorPane.setRightAnchor(messageLabel, msgLabelPaddingRight);
                                AnchorPane.setRightAnchor(copyIcon, padding);
                                AnchorPane.setLeftAnchor(attachmentsBox, padding + arrowWidth);
                                AnchorPane.setRightAnchor(attachmentsBox, padding);
                                AnchorPane.setRightAnchor(statusIcon, padding);
                            } else {
                                AnchorPane.setRightAnchor(headerLabel, padding + arrowWidth);
                                AnchorPane.setLeftAnchor(bg, border);
                                AnchorPane.setRightAnchor(bg, border + arrowWidth);
                                AnchorPane.setRightAnchor(arrow, border);
                                AnchorPane.setLeftAnchor(messageLabel, padding);
                                AnchorPane.setRightAnchor(messageLabel, msgLabelPaddingRight + arrowWidth);
                                AnchorPane.setRightAnchor(copyIcon, padding + arrowWidth);
                                AnchorPane.setLeftAnchor(attachmentsBox, padding);
                                AnchorPane.setRightAnchor(attachmentsBox, padding + arrowWidth);
                                AnchorPane.setLeftAnchor(statusIcon, padding);
                            }
                            AnchorPane.setBottomAnchor(statusIcon, 7d);
                            headerLabel.setText(formatter.formatDateTime(new Date(item.getDate())));
                            messageLabel.setText(item.getMessage());
                            attachmentsBox.getChildren().clear();
                            if (item.getAttachments() != null && item.getAttachments().size() > 0) {
                                AnchorPane.setBottomAnchor(messageLabel, bottomBorder + attachmentsBoxHeight + 10);
                                attachmentsBox.getChildren().add(new AutoTooltipLabel(Res.get("support.attachments") + " ") {

                                    {
                                        setPadding(new Insets(0, 0, 3, 0));
                                        if (isMyMsg)
                                            getStyleClass().add("my-message");
                                        else
                                            getStyleClass().add("message");
                                    }
                                });
                                item.getAttachments().stream().forEach(attachment -> {
                                    final Label icon = new Label();
                                    setPadding(new Insets(0, 0, 3, 0));
                                    if (isMyMsg)
                                        icon.getStyleClass().add("attachment-icon");
                                    else
                                        icon.getStyleClass().add("attachment-icon-black");
                                    AwesomeDude.setIcon(icon, AwesomeIcon.FILE_TEXT);
                                    icon.setPadding(new Insets(-2, 0, 0, 0));
                                    icon.setTooltip(new Tooltip(attachment.getFileName()));
                                    icon.setOnMouseClicked(event -> onOpenAttachment(attachment));
                                    attachmentsBox.getChildren().add(icon);
                                });
                            } else {
                                AnchorPane.setBottomAnchor(messageLabel, bottomBorder + 10);
                            }
                            // Need to set it here otherwise style is not correct
                            AwesomeDude.setIcon(copyIcon, AwesomeIcon.COPY, "16.0");
                            copyIcon.getStyleClass().addAll("icon", "copy-icon-disputes");
                            // TODO There are still some cell rendering issues on updates
                            setGraphic(messageAnchorPane);
                        } else {
                            if (sendMsgBusyAnimation != null && sendMsgBusyAnimationListener != null)
                                sendMsgBusyAnimation.isRunningProperty().removeListener(sendMsgBusyAnimationListener);
                            messageAnchorPane.prefWidthProperty().unbind();
                            AnchorPane.clearConstraints(bg);
                            AnchorPane.clearConstraints(headerLabel);
                            AnchorPane.clearConstraints(arrow);
                            AnchorPane.clearConstraints(messageLabel);
                            AnchorPane.clearConstraints(copyIcon);
                            AnchorPane.clearConstraints(statusIcon);
                            AnchorPane.clearConstraints(attachmentsBox);
                            copyIcon.setOnMouseClicked(null);
                            setGraphic(null);
                        }
                    }

                    /*  private void showNotArrivedIcon() {
                            statusIcon.setVisible(true);
                            AwesomeDude.setIcon(statusIcon, AwesomeIcon.WARNING_SIGN, "14");
                            Tooltip.install(statusIcon, new Tooltip("Message did not arrive. Please try to send again."));
                            statusIcon.setTextFill(Paint.valueOf("#dd0000"));
                        }*/
                    private void showMailboxIcon() {
                        statusIcon.setVisible(true);
                        AwesomeDude.setIcon(statusIcon, AwesomeIcon.ENVELOPE_ALT, "14");
                        statusIcon.setTooltip(new Tooltip(Res.get("support.savedInMailbox")));
                        statusIcon.setTextFill(Paint.valueOf("#0f87c3"));
                    }

                    private void showArrivedIcon() {
                        statusIcon.setVisible(true);
                        AwesomeDude.setIcon(statusIcon, AwesomeIcon.OK, "14");
                        statusIcon.setTooltip(new Tooltip(Res.get("support.arrived")));
                        statusIcon.setTextFill(Paint.valueOf("#0f87c3"));
                    }
                };
            }
        });
        if (root.getChildren().size() > 2)
            root.getChildren().remove(2);
        root.getChildren().add(2, messagesAnchorPane);
        scrollToBottom();
    }
    addListenersOnSelectDispute();
}
Also used : Button(javafx.scene.control.Button) EventHandler(javafx.event.EventHandler) PubKeyRing(bisq.common.crypto.PubKeyRing) BusyAnimation(bisq.desktop.components.BusyAnimation) Utilities(bisq.common.util.Utilities) HyperlinkWithIcon(bisq.desktop.components.HyperlinkWithIcon) ListCell(javafx.scene.control.ListCell) URL(java.net.URL) Date(java.util.Date) ReadOnlyBooleanProperty(javafx.beans.property.ReadOnlyBooleanProperty) DisputeManager(bisq.core.arbitration.DisputeManager) VBox(javafx.scene.layout.VBox) BSFormatter(bisq.desktop.util.BSFormatter) Contract(bisq.core.trade.Contract) InputTextField(bisq.desktop.components.InputTextField) ReadOnlyObjectWrapper(javafx.beans.property.ReadOnlyObjectWrapper) ListChangeListener(javafx.collections.ListChangeListener) Res(bisq.core.locale.Res) Map(java.util.Map) TableView(javafx.scene.control.TableView) ParseException(java.text.ParseException) DateFormat(java.text.DateFormat) Pane(javafx.scene.layout.Pane) SortedList(javafx.collections.transformation.SortedList) HBox(javafx.scene.layout.HBox) Popup(bisq.desktop.main.overlays.popups.Popup) AutoTooltipTableColumn(bisq.desktop.components.AutoTooltipTableColumn) P2PService(bisq.network.p2p.P2PService) AutoTooltipLabel(bisq.desktop.components.AutoTooltipLabel) FilteredList(javafx.collections.transformation.FilteredList) KeyEvent(javafx.scene.input.KeyEvent) Subscription(org.fxmisc.easybind.Subscription) SendPrivateNotificationWindow(bisq.desktop.main.overlays.windows.SendPrivateNotificationWindow) Priority(javafx.scene.layout.Priority) List(java.util.List) TradeManager(bisq.core.trade.TradeManager) AnchorPane(javafx.scene.layout.AnchorPane) Paint(javafx.scene.paint.Paint) NodeAddress(bisq.network.p2p.NodeAddress) AutoTooltipButton(bisq.desktop.components.AutoTooltipButton) AppOptionKeys(bisq.core.app.AppOptionKeys) UserThread(bisq.common.UserThread) ByteStreams(com.google.common.io.ByteStreams) Optional(java.util.Optional) Attachment(bisq.core.arbitration.Attachment) ObservableList(javafx.collections.ObservableList) AwesomeIcon(de.jensd.fx.fontawesome.AwesomeIcon) TableGroupHeadline(bisq.desktop.components.TableGroupHeadline) GUIUtil(bisq.desktop.util.GUIUtil) Scene(javafx.scene.Scene) ActivatableView(bisq.desktop.common.view.ActivatableView) ListView(javafx.scene.control.ListView) DisputeSummaryWindow(bisq.desktop.main.overlays.windows.DisputeSummaryWindow) TextArea(javafx.scene.control.TextArea) SimpleDateFormat(java.text.SimpleDateFormat) Timer(bisq.common.Timer) HashMap(java.util.HashMap) Dispute(bisq.core.arbitration.Dispute) ContractWindow(bisq.desktop.main.overlays.windows.ContractWindow) FxmlView(bisq.desktop.common.view.FxmlView) TableColumn(javafx.scene.control.TableColumn) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) TableCell(javafx.scene.control.TableCell) Lists(com.google.common.collect.Lists) Insets(javafx.geometry.Insets) Connection(bisq.network.p2p.network.Connection) TextAlignment(javafx.scene.text.TextAlignment) Callback(javafx.util.Callback) Tooltip(javafx.scene.control.Tooltip) PrivateNotificationManager(bisq.core.alert.PrivateNotificationManager) Nullable(javax.annotation.Nullable) KeyCode(javafx.scene.input.KeyCode) Version(bisq.common.app.Version) Label(javafx.scene.control.Label) TradeDetailsWindow(bisq.desktop.main.overlays.windows.TradeDetailsWindow) MalformedURLException(java.net.MalformedURLException) Trade(bisq.core.trade.Trade) AwesomeDude(de.jensd.fx.fontawesome.AwesomeDude) FileOutputStream(java.io.FileOutputStream) IOException(java.io.IOException) File(java.io.File) TimeUnit(java.util.concurrent.TimeUnit) FileChooser(javafx.stage.FileChooser) DisputeCommunicationMessage(bisq.core.arbitration.messages.DisputeCommunicationMessage) Stage(javafx.stage.Stage) EasyBind(org.fxmisc.easybind.EasyBind) ImageView(javafx.scene.image.ImageView) ArbitratorDisputeView(bisq.desktop.main.disputes.arbitrator.ArbitratorDisputeView) Named(com.google.inject.name.Named) KeyRing(bisq.common.crypto.KeyRing) ChangeListener(javafx.beans.value.ChangeListener) InputStream(java.io.InputStream) TableGroupHeadline(bisq.desktop.components.TableGroupHeadline) HBox(javafx.scene.layout.HBox) Insets(javafx.geometry.Insets) TextArea(javafx.scene.control.TextArea) ListCell(javafx.scene.control.ListCell) SortedList(javafx.collections.transformation.SortedList) AutoTooltipLabel(bisq.desktop.components.AutoTooltipLabel) Label(javafx.scene.control.Label) ArbitratorDisputeView(bisq.desktop.main.disputes.arbitrator.ArbitratorDisputeView) ListView(javafx.scene.control.ListView) Button(javafx.scene.control.Button) AutoTooltipButton(bisq.desktop.components.AutoTooltipButton) ListChangeListener(javafx.collections.ListChangeListener) ChangeListener(javafx.beans.value.ChangeListener) ImageView(javafx.scene.image.ImageView) AutoTooltipLabel(bisq.desktop.components.AutoTooltipLabel) AnchorPane(javafx.scene.layout.AnchorPane) DisputeCommunicationMessage(bisq.core.arbitration.messages.DisputeCommunicationMessage) BusyAnimation(bisq.desktop.components.BusyAnimation) Tooltip(javafx.scene.control.Tooltip) AutoTooltipButton(bisq.desktop.components.AutoTooltipButton) Pane(javafx.scene.layout.Pane) AnchorPane(javafx.scene.layout.AnchorPane) Date(java.util.Date) Callback(javafx.util.Callback) VBox(javafx.scene.layout.VBox)

Example 5 with DisputeCommunicationMessage

use of bisq.core.arbitration.messages.DisputeCommunicationMessage in project bisq-core by bisq-network.

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, null, p2PService.getAddress(), new Date().getTime(), false, false, UUID.randomUUID().toString());
    disputeCommunicationMessage.addAllAttachments(attachments);
    PubKeyRing receiverPubKeyRing = null;
    NodeAddress peerNodeAddress = null;
    if (isTrader(dispute)) {
        dispute.addDisputeMessage(disputeCommunicationMessage);
        receiverPubKeyRing = dispute.getArbitratorPubKeyRing();
        peerNodeAddress = dispute.getContract().getArbitratorNodeAddress();
    } 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() {
                log.info("Message arrived at peer. tradeId={}", disputeCommunicationMessage.getTradeId());
                disputeCommunicationMessage.setArrived(true);
            }

            @Override
            public void onStoredInMailbox() {
                log.info("Message stored in mailbox. tradeId={}", disputeCommunicationMessage.getTradeId());
                disputeCommunicationMessage.setStoredInMailbox(true);
            }

            @Override
            public void onFault(String errorMessage) {
                log.error("sendEncryptedMailboxMessage failed. disputeCommunicationMessage=" + disputeCommunicationMessage);
            }
        });
    }
    return disputeCommunicationMessage;
}
Also used : PubKeyRing(bisq.common.crypto.PubKeyRing) NodeAddress(bisq.network.p2p.NodeAddress) SendMailboxMessageListener(bisq.network.p2p.SendMailboxMessageListener) Contract(bisq.core.trade.Contract) DisputeCommunicationMessage(bisq.core.arbitration.messages.DisputeCommunicationMessage) Date(java.util.Date)

Aggregations

DisputeCommunicationMessage (bisq.core.arbitration.messages.DisputeCommunicationMessage)6 Contract (bisq.core.trade.Contract)5 Date (java.util.Date)5 NodeAddress (bisq.network.p2p.NodeAddress)4 SendMailboxMessageListener (bisq.network.p2p.SendMailboxMessageListener)4 PubKeyRing (bisq.common.crypto.PubKeyRing)3 Timer (bisq.common.Timer)2 Trade (bisq.core.trade.Trade)2 UserThread (bisq.common.UserThread)1 Version (bisq.common.app.Version)1 KeyRing (bisq.common.crypto.KeyRing)1 Utilities (bisq.common.util.Utilities)1 PrivateNotificationManager (bisq.core.alert.PrivateNotificationManager)1 AppOptionKeys (bisq.core.app.AppOptionKeys)1 Attachment (bisq.core.arbitration.Attachment)1 Dispute (bisq.core.arbitration.Dispute)1 DisputeManager (bisq.core.arbitration.DisputeManager)1 DisputeResultMessage (bisq.core.arbitration.messages.DisputeResultMessage)1 OpenNewDisputeMessage (bisq.core.arbitration.messages.OpenNewDisputeMessage)1 PeerOpenedDisputeMessage (bisq.core.arbitration.messages.PeerOpenedDisputeMessage)1