Search in sources :

Example 1 with TransactionVerificationException

use of bisq.core.btc.exceptions.TransactionVerificationException 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 TransactionVerificationException

use of bisq.core.btc.exceptions.TransactionVerificationException in project bisq-core by bisq-network.

the class WalletService method verifyTransaction.

public static void verifyTransaction(Transaction transaction) throws TransactionVerificationException {
    try {
        log.trace("Verify transaction " + transaction);
        transaction.verify();
    } catch (Throwable t) {
        t.printStackTrace();
        log.error(t.getMessage());
        throw new TransactionVerificationException(t);
    }
}
Also used : TransactionVerificationException(bisq.core.btc.exceptions.TransactionVerificationException)

Example 3 with TransactionVerificationException

use of bisq.core.btc.exceptions.TransactionVerificationException in project bisq-core by bisq-network.

the class VoteService method revealVote.

private void revealVote(MyVote myVote) {
    byte[] hashOfBlindVoteList = VoteConsensus.getHashOfBlindVoteList(blindVoteSortedList);
    log.info("Sha256Ripemd160 hash of hashOfBlindVoteList " + Utilities.bytesAsHexString(hashOfBlindVoteList));
    byte[] opReturnData = VoteConsensus.getOpReturnDataForVoteReveal(hashOfBlindVoteList, myVote.getSecretKey());
    final Set<TxOutput> lockedForVoteTxOutputs = readableBsqBlockChain.getLockedForVoteTxOutputs();
    Optional<TxOutput> optionalStakeTxOutput = lockedForVoteTxOutputs.stream().filter(txOutput -> txOutput.getTxId().equals(myVote.getTxId())).findAny();
    if (optionalStakeTxOutput.isPresent()) {
        try {
            final TxOutput stakeTxOutput = optionalStakeTxOutput.get();
            VoteConsensus.unlockStakeTxOutputType(stakeTxOutput);
            Transaction voteRevealTx = getVoteRevealTx(stakeTxOutput, opReturnData);
            myVote.setRevealTxId(voteRevealTx.getHashAsString());
            myVoteListStorage.queueUpForSave();
            publishRevealTx(voteRevealTx, new FutureCallback<Transaction>() {

                @Override
                public void onSuccess(@Nullable Transaction result) {
                }

                @Override
                public void onFailure(@NotNull Throwable t) {
                }
            });
        } catch (InsufficientMoneyException e) {
            e.printStackTrace();
        } catch (WalletException e) {
            e.printStackTrace();
        } catch (TransactionVerificationException e) {
            e.printStackTrace();
        }
    } else {
    // log.warn("optionalStakeTxOutput is not present. myVote={}", myVote);
    }
}
Also used : Transaction(org.bitcoinj.core.Transaction) ChangeBelowDustException(bisq.core.btc.wallet.ChangeBelowDustException) Utilities(bisq.common.util.Utilities) Coin(org.bitcoinj.core.Coin) ReadableBsqBlockChain(bisq.core.dao.blockchain.ReadableBsqBlockChain) Proposal(bisq.core.dao.proposal.Proposal) Preconditions.checkArgument(com.google.common.base.Preconditions.checkArgument) BsqBlockChain(bisq.core.dao.blockchain.BsqBlockChain) SortedList(javafx.collections.transformation.SortedList) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) WalletException(bisq.core.btc.exceptions.WalletException) P2PService(bisq.network.p2p.P2PService) PersistedDataHost(bisq.common.proto.persistable.PersistedDataHost) Utils(org.bitcoinj.core.Utils) FilteredList(javafx.collections.transformation.FilteredList) Set(java.util.Set) TxOutput(bisq.core.dao.blockchain.vo.TxOutput) BsqWalletService(bisq.core.btc.wallet.BsqWalletService) Encryption(bisq.common.crypto.Encryption) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) DevEnv(bisq.common.app.DevEnv) VoteConsensus(bisq.core.dao.vote.consensus.VoteConsensus) ProtectedStorageEntry(bisq.network.p2p.storage.payload.ProtectedStorageEntry) UserThread(bisq.common.UserThread) Optional(java.util.Optional) ProtectedStoragePayload(bisq.network.p2p.storage.payload.ProtectedStoragePayload) ObservableList(javafx.collections.ObservableList) SecretKey(javax.crypto.SecretKey) NotNull(org.jetbrains.annotations.NotNull) BtcWalletService(bisq.core.btc.wallet.BtcWalletService) CryptoException(bisq.common.crypto.CryptoException) Getter(lombok.Getter) FXCollections(javafx.collections.FXCollections) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) TransactionVerificationException(bisq.core.btc.exceptions.TransactionVerificationException) Nullable(javax.annotation.Nullable) DaoPeriodService(bisq.core.dao.DaoPeriodService) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) PublicKey(java.security.PublicKey) BisqEnvironment(bisq.core.app.BisqEnvironment) InsufficientMoneyException(org.bitcoinj.core.InsufficientMoneyException) FutureCallback(com.google.common.util.concurrent.FutureCallback) HashMapChangedListener(bisq.network.p2p.storage.HashMapChangedListener) Storage(bisq.common.storage.Storage) ProposalList(bisq.core.dao.proposal.ProposalList) KeyRing(bisq.common.crypto.KeyRing) ChangeListener(javafx.beans.value.ChangeListener) ProposalCollectionsService(bisq.core.dao.proposal.ProposalCollectionsService) WalletException(bisq.core.btc.exceptions.WalletException) TxOutput(bisq.core.dao.blockchain.vo.TxOutput) Transaction(org.bitcoinj.core.Transaction) TransactionVerificationException(bisq.core.btc.exceptions.TransactionVerificationException) InsufficientMoneyException(org.bitcoinj.core.InsufficientMoneyException)

Example 4 with TransactionVerificationException

use of bisq.core.btc.exceptions.TransactionVerificationException in project bisq-desktop by bisq-network.

the class ActiveProposalsView method activate.

@Override
protected void activate() {
    super.activate();
    bsqWalletService.addBsqBalanceListener(this);
    onUpdateBalances(bsqWalletService.getAvailableBalance(), bsqWalletService.getPendingBalance(), bsqWalletService.getLockedForVotingBalance(), bsqWalletService.getLockedInBondsBalance());
    if (voteButton != null) {
        voteButton.setOnAction(e -> {
            Coin stake = bsqFormatter.parseToCoin(stakeInputTextField.getText());
            // TODO show popup
            try {
                voteService.publishBlindVote(stake, new FutureCallback<Transaction>() {

                    @Override
                    public void onSuccess(@Nullable Transaction result) {
                    // TODO
                    }

                    @Override
                    public void onFailure(@NotNull Throwable t) {
                    // TODO
                    }
                });
            } catch (CryptoException e1) {
                // TODO show error popup
                e1.printStackTrace();
            } catch (InsufficientBsqException e1) {
                e1.printStackTrace();
            } catch (WalletException e1) {
                e1.printStackTrace();
            } catch (TransactionVerificationException e1) {
                e1.printStackTrace();
            } catch (InsufficientMoneyException e1) {
                e1.printStackTrace();
            } catch (ChangeBelowDustException e1) {
                e1.printStackTrace();
            } catch (InvalidProtocolBufferException e1) {
                e1.printStackTrace();
            }
        });
    }
}
Also used : WalletException(bisq.core.btc.exceptions.WalletException) Coin(org.bitcoinj.core.Coin) Transaction(org.bitcoinj.core.Transaction) InsufficientBsqException(bisq.core.btc.wallet.InsufficientBsqException) TransactionVerificationException(bisq.core.btc.exceptions.TransactionVerificationException) InvalidProtocolBufferException(com.google.protobuf.InvalidProtocolBufferException) InsufficientMoneyException(org.bitcoinj.core.InsufficientMoneyException) CryptoException(bisq.common.crypto.CryptoException) ChangeBelowDustException(bisq.core.btc.wallet.ChangeBelowDustException)

Example 5 with TransactionVerificationException

use of bisq.core.btc.exceptions.TransactionVerificationException in project bisq-desktop by bisq-network.

the class ManualPayoutTxWindow method addContent.

private void addContent() {
    // We dont translate here as it is for dev only purpose
    InputTextField depositTxHex = addLabelInputTextField(gridPane, ++rowIndex, "depositTxHex:").second;
    InputTextField buyerPayoutAmount = addLabelInputTextField(gridPane, ++rowIndex, "buyerPayoutAmount:").second;
    InputTextField sellerPayoutAmount = addLabelInputTextField(gridPane, ++rowIndex, "sellerPayoutAmount:").second;
    InputTextField arbitratorPayoutAmount = addLabelInputTextField(gridPane, ++rowIndex, "arbitratorPayoutAmount:").second;
    InputTextField txFee = addLabelInputTextField(gridPane, ++rowIndex, "Tx fee:").second;
    InputTextField buyerAddressString = addLabelInputTextField(gridPane, ++rowIndex, "buyerAddressString:").second;
    InputTextField sellerAddressString = addLabelInputTextField(gridPane, ++rowIndex, "sellerAddressString:").second;
    InputTextField arbitratorAddressString = addLabelInputTextField(gridPane, ++rowIndex, "arbitratorAddressString:").second;
    InputTextField buyerPrivateKeyAsHex = addLabelInputTextField(gridPane, ++rowIndex, "buyerPrivateKeyAsHex:").second;
    InputTextField sellerPrivateKeyAsHex = addLabelInputTextField(gridPane, ++rowIndex, "sellerPrivateKeyAsHex:").second;
    InputTextField arbitratorPrivateKeyAsHex = addLabelInputTextField(gridPane, ++rowIndex, "arbitratorPrivateKeyAsHex:").second;
    InputTextField buyerPubKeyAsHex = addLabelInputTextField(gridPane, ++rowIndex, "buyerPubKeyAsHex:").second;
    InputTextField sellerPubKeyAsHex = addLabelInputTextField(gridPane, ++rowIndex, "sellerPubKeyAsHex:").second;
    InputTextField arbitratorPubKeyAsHex = addLabelInputTextField(gridPane, ++rowIndex, "arbitratorPubKeyAsHex:").second;
    InputTextField P2SHMultiSigOutputScript = addLabelInputTextField(gridPane, ++rowIndex, "P2SHMultiSigOutputScript:").second;
    // Notes:
    // Open with alt+g and enable DEV mode
    // Priv key is only visible if pw protection is removed (wallet details data (alt+j))
    // Take P2SHMultiSigOutputScript from depositTx in blockexplorer
    // Take missing buyerPubKeyAsHex and sellerPubKeyAsHex from contract data!
    // Lookup sellerPrivateKeyAsHex associated with sellerPubKeyAsHex (or buyers) in wallet details data
    // sellerPubKeys/buyerPubKeys are auto generated if used the fields below
    // Never set the priv arbitr. key here!
    depositTxHex.setText("");
    P2SHMultiSigOutputScript.setText("");
    buyerPayoutAmount.setText("");
    sellerPayoutAmount.setText("");
    arbitratorPayoutAmount.setText("0");
    buyerAddressString.setText("");
    buyerPubKeyAsHex.setText("");
    buyerPrivateKeyAsHex.setText("");
    sellerAddressString.setText("");
    sellerPubKeyAsHex.setText("");
    sellerPrivateKeyAsHex.setText("");
    arbitratorAddressString.setText("");
    arbitratorPubKeyAsHex.setText("");
    actionButtonText("Sign and publish transaction");
    FutureCallback<Transaction> callback = new FutureCallback<Transaction>() {

        @Override
        public void onSuccess(@Nullable Transaction result) {
            log.error("onSuccess");
            UserThread.execute(() -> {
                String txId = result != null ? result.getHashAsString() : "null";
                new Popup<>().information("Transaction successful published. Transaction ID: " + txId).show();
            });
        }

        @Override
        public void onFailure(@NotNull Throwable t) {
            log.error(t.toString());
            log.error("onFailure");
            UserThread.execute(() -> new Popup<>().warning(t.toString()).show());
        }
    };
    onAction(() -> {
        if (GUIUtil.isReadyForTxBroadcast(p2PService, walletsSetup)) {
            try {
                tradeWalletService.emergencySignAndPublishPayoutTx(depositTxHex.getText(), Coin.parseCoin(buyerPayoutAmount.getText()), Coin.parseCoin(sellerPayoutAmount.getText()), Coin.parseCoin(arbitratorPayoutAmount.getText()), Coin.parseCoin(txFee.getText()), buyerAddressString.getText(), sellerAddressString.getText(), arbitratorAddressString.getText(), buyerPrivateKeyAsHex.getText(), sellerPrivateKeyAsHex.getText(), arbitratorPrivateKeyAsHex.getText(), buyerPubKeyAsHex.getText(), sellerPubKeyAsHex.getText(), arbitratorPubKeyAsHex.getText(), P2SHMultiSigOutputScript.getText(), callback);
            } catch (AddressFormatException | WalletException | TransactionVerificationException e) {
                log.error(e.toString());
                e.printStackTrace();
                UserThread.execute(() -> new Popup<>().warning(e.toString()).show());
            }
        } else {
            GUIUtil.showNotReadyForTxBroadcastPopups(p2PService, walletsSetup);
        }
    });
}
Also used : WalletException(bisq.core.btc.exceptions.WalletException) AddressFormatException(org.bitcoinj.core.AddressFormatException) TransactionVerificationException(bisq.core.btc.exceptions.TransactionVerificationException) FormBuilder.addLabelInputTextField(bisq.desktop.util.FormBuilder.addLabelInputTextField) InputTextField(bisq.desktop.components.InputTextField) NotNull(org.jetbrains.annotations.NotNull) Transaction(org.bitcoinj.core.Transaction) Popup(bisq.desktop.main.overlays.popups.Popup) FutureCallback(com.google.common.util.concurrent.FutureCallback) Nullable(javax.annotation.Nullable)

Aggregations

TransactionVerificationException (bisq.core.btc.exceptions.TransactionVerificationException)10 Transaction (org.bitcoinj.core.Transaction)7 WalletException (bisq.core.btc.exceptions.WalletException)6 AddressFormatException (org.bitcoinj.core.AddressFormatException)4 Coin (org.bitcoinj.core.Coin)4 InsufficientMoneyException (org.bitcoinj.core.InsufficientMoneyException)4 ChangeBelowDustException (bisq.core.btc.wallet.ChangeBelowDustException)3 Popup (bisq.desktop.main.overlays.popups.Popup)3 FutureCallback (com.google.common.util.concurrent.FutureCallback)3 Nullable (javax.annotation.Nullable)3 CryptoException (bisq.common.crypto.CryptoException)2 BisqEnvironment (bisq.core.app.BisqEnvironment)2 AddressEntry (bisq.core.btc.AddressEntry)2 RawTransactionInput (bisq.core.btc.data.RawTransactionInput)2 InsufficientBsqException (bisq.core.btc.wallet.InsufficientBsqException)2 Proposal (bisq.core.dao.proposal.Proposal)2 InvalidProtocolBufferException (com.google.protobuf.InvalidProtocolBufferException)2 Optional (java.util.Optional)2 TransactionInput (org.bitcoinj.core.TransactionInput)2 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)2