Search in sources :

Example 6 with AddressEntry

use of bisq.core.btc.AddressEntry in project bisq-core by bisq-network.

the class MakerCreateAndSignContract method run.

@Override
protected void run() {
    try {
        runInterceptHook();
        Preconditions.checkNotNull(trade.getTakerFeeTxId(), "trade.getTakeOfferFeeTxId() must not be null");
        TradingPeer taker = processModel.getTradingPeer();
        PaymentAccountPayload makerPaymentAccountPayload = processModel.getPaymentAccountPayload(trade);
        checkNotNull(makerPaymentAccountPayload, "makerPaymentAccountPayload must not be null");
        PaymentAccountPayload takerPaymentAccountPayload = taker.getPaymentAccountPayload();
        boolean isBuyerMakerAndSellerTaker = trade instanceof BuyerAsMakerTrade;
        NodeAddress buyerNodeAddress = isBuyerMakerAndSellerTaker ? processModel.getMyNodeAddress() : processModel.getTempTradingPeerNodeAddress();
        NodeAddress sellerNodeAddress = isBuyerMakerAndSellerTaker ? processModel.getTempTradingPeerNodeAddress() : processModel.getMyNodeAddress();
        BtcWalletService walletService = processModel.getBtcWalletService();
        String id = processModel.getOffer().getId();
        checkArgument(!walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG).isPresent(), "addressEntry must not be set here.");
        AddressEntry makerAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG);
        byte[] makerMultiSigPubKey = makerAddressEntry.getPubKey();
        AddressEntry takerAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.TRADE_PAYOUT);
        checkNotNull(trade.getTradeAmount(), "trade.getTradeAmount() must not be null");
        Contract contract = new Contract(processModel.getOffer().getOfferPayload(), trade.getTradeAmount().value, trade.getTradePrice().getValue(), trade.getTakerFeeTxId(), buyerNodeAddress, sellerNodeAddress, trade.getArbitratorNodeAddress(), trade.getMediatorNodeAddress(), isBuyerMakerAndSellerTaker, processModel.getAccountId(), taker.getAccountId(), makerPaymentAccountPayload, takerPaymentAccountPayload, processModel.getPubKeyRing(), taker.getPubKeyRing(), takerAddressEntry.getAddressString(), taker.getPayoutAddressString(), makerMultiSigPubKey, taker.getMultiSigPubKey());
        String contractAsJson = Utilities.objectToJson(contract);
        log.trace("Contract as json:{}", contractAsJson);
        String signature = Sig.sign(processModel.getKeyRing().getSignatureKeyPair().getPrivate(), contractAsJson);
        trade.setContract(contract);
        trade.setContractAsJson(contractAsJson);
        trade.setMakerContractSignature(signature);
        processModel.setMyMultiSigPubKey(makerMultiSigPubKey);
        complete();
    } catch (Throwable t) {
        failed(t);
    }
}
Also used : TradingPeer(bisq.core.trade.protocol.TradingPeer) BuyerAsMakerTrade(bisq.core.trade.BuyerAsMakerTrade) BtcWalletService(bisq.core.btc.wallet.BtcWalletService) AddressEntry(bisq.core.btc.AddressEntry) PaymentAccountPayload(bisq.core.payment.payload.PaymentAccountPayload) NodeAddress(bisq.network.p2p.NodeAddress) Contract(bisq.core.trade.Contract)

Example 7 with AddressEntry

use of bisq.core.btc.AddressEntry in project bisq-core by bisq-network.

the class MakerSendPublishDepositTxRequest method run.

@Override
protected void run() {
    try {
        runInterceptHook();
        BtcWalletService walletService = processModel.getBtcWalletService();
        String id = processModel.getOffer().getId();
        Optional<AddressEntry> addressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
        checkArgument(addressEntryOptional.isPresent(), "addressEntry must be set here.");
        AddressEntry makerPayoutAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.TRADE_PAYOUT);
        byte[] makerMultiSigPubKey = processModel.getMyMultiSigPubKey();
        checkArgument(Arrays.equals(makerMultiSigPubKey, addressEntryOptional.get().getPubKey()), "makerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
        final byte[] preparedDepositTx = processModel.getPreparedDepositTx();
        // Maker has to use preparedDepositTx as nonce.
        // He cannot manipulate the preparedDepositTx - so we avoid to have a challenge protocol for passing the nonce we want to get signed.
        final PaymentAccountPayload paymentAccountPayload = checkNotNull(processModel.getPaymentAccountPayload(trade), "processModel.getPaymentAccountPayload(trade) must not be null");
        byte[] sig = Sig.sign(processModel.getKeyRing().getSignatureKeyPair().getPrivate(), preparedDepositTx);
        PublishDepositTxRequest message = new PublishDepositTxRequest(processModel.getOfferId(), paymentAccountPayload, processModel.getAccountId(), makerMultiSigPubKey, trade.getContractAsJson(), trade.getMakerContractSignature(), makerPayoutAddressEntry.getAddressString(), preparedDepositTx, processModel.getRawTransactionInputs(), processModel.getMyNodeAddress(), UUID.randomUUID().toString(), sig, new Date().getTime());
        trade.setState(Trade.State.MAKER_SENT_PUBLISH_DEPOSIT_TX_REQUEST);
        processModel.getP2PService().sendEncryptedMailboxMessage(trade.getTradingPeerNodeAddress(), processModel.getTradingPeer().getPubKeyRing(), message, new SendMailboxMessageListener() {

            @Override
            public void onArrived() {
                log.info("Message arrived at peer. tradeId={}", id);
                trade.setState(Trade.State.MAKER_SAW_ARRIVED_PUBLISH_DEPOSIT_TX_REQUEST);
                complete();
            }

            @Override
            public void onStoredInMailbox() {
                log.info("Message stored in mailbox. tradeId={}", id);
                trade.setState(Trade.State.MAKER_STORED_IN_MAILBOX_PUBLISH_DEPOSIT_TX_REQUEST);
                complete();
            }

            @Override
            public void onFault(String errorMessage) {
                log.error("sendEncryptedMailboxMessage failed. message=" + message);
                trade.setState(Trade.State.MAKER_SEND_FAILED_PUBLISH_DEPOSIT_TX_REQUEST);
                appendToErrorMessage("Sending message failed: message=" + message + "\nerrorMessage=" + errorMessage);
                failed(errorMessage);
            }
        });
    } catch (Throwable t) {
        failed(t);
    }
}
Also used : BtcWalletService(bisq.core.btc.wallet.BtcWalletService) AddressEntry(bisq.core.btc.AddressEntry) PaymentAccountPayload(bisq.core.payment.payload.PaymentAccountPayload) SendMailboxMessageListener(bisq.network.p2p.SendMailboxMessageListener) PublishDepositTxRequest(bisq.core.trade.messages.PublishDepositTxRequest) Date(java.util.Date)

Example 8 with AddressEntry

use of bisq.core.btc.AddressEntry in project bisq-core by bisq-network.

the class SellerSignAndFinalizePayoutTx method run.

@Override
protected void run() {
    try {
        runInterceptHook();
        checkNotNull(trade.getTradeAmount(), "trade.getTradeAmount() must not be null");
        Offer offer = trade.getOffer();
        TradingPeer tradingPeer = processModel.getTradingPeer();
        BtcWalletService walletService = processModel.getBtcWalletService();
        String id = processModel.getOffer().getId();
        final byte[] buyerSignature = tradingPeer.getSignature();
        Coin buyerPayoutAmount = offer.getBuyerSecurityDeposit().add(trade.getTradeAmount());
        Coin sellerPayoutAmount = offer.getSellerSecurityDeposit();
        final String buyerPayoutAddressString = tradingPeer.getPayoutAddressString();
        String sellerPayoutAddressString = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.TRADE_PAYOUT).getAddressString();
        final byte[] buyerMultiSigPubKey = tradingPeer.getMultiSigPubKey();
        byte[] sellerMultiSigPubKey = processModel.getMyMultiSigPubKey();
        Optional<AddressEntry> MultiSigAddressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
        checkArgument(MultiSigAddressEntryOptional.isPresent() && Arrays.equals(sellerMultiSigPubKey, MultiSigAddressEntryOptional.get().getPubKey()), "sellerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
        DeterministicKey multiSigKeyPair = walletService.getMultiSigKeyPair(id, sellerMultiSigPubKey);
        Transaction transaction = processModel.getTradeWalletService().sellerSignsAndFinalizesPayoutTx(trade.getDepositTx(), buyerSignature, buyerPayoutAmount, sellerPayoutAmount, buyerPayoutAddressString, sellerPayoutAddressString, multiSigKeyPair, buyerMultiSigPubKey, sellerMultiSigPubKey, trade.getArbitratorBtcPubKey());
        trade.setPayoutTx(transaction);
        walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.MULTI_SIG);
        complete();
    } catch (Throwable t) {
        failed(t);
    }
}
Also used : Coin(org.bitcoinj.core.Coin) TradingPeer(bisq.core.trade.protocol.TradingPeer) Transaction(org.bitcoinj.core.Transaction) Offer(bisq.core.offer.Offer) BtcWalletService(bisq.core.btc.wallet.BtcWalletService) AddressEntry(bisq.core.btc.AddressEntry) DeterministicKey(org.bitcoinj.crypto.DeterministicKey)

Example 9 with AddressEntry

use of bisq.core.btc.AddressEntry in project bisq-core by bisq-network.

the class SellerAsTakerSignAndPublishDepositTx method run.

@Override
protected void run() {
    try {
        runInterceptHook();
        log.debug("\n\n------------------------------------------------------------\n" + "Contract as json\n" + trade.getContractAsJson() + "\n------------------------------------------------------------\n");
        byte[] contractHash = Hash.getSha256Hash(trade.getContractAsJson());
        trade.setContractHash(contractHash);
        List<RawTransactionInput> sellerInputs = checkNotNull(processModel.getRawTransactionInputs(), "sellerInputs must not be null");
        BtcWalletService walletService = processModel.getBtcWalletService();
        String id = processModel.getOffer().getId();
        Optional<AddressEntry> addressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
        checkArgument(addressEntryOptional.isPresent(), "addressEntryOptional must be present");
        AddressEntry sellerMultiSigAddressEntry = addressEntryOptional.get();
        byte[] sellerMultiSigPubKey = processModel.getMyMultiSigPubKey();
        checkArgument(Arrays.equals(sellerMultiSigPubKey, sellerMultiSigAddressEntry.getPubKey()), "sellerMultiSigPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
        Coin sellerInput = Coin.valueOf(sellerInputs.stream().mapToLong(input -> input.value).sum());
        sellerMultiSigAddressEntry.setCoinLockedInMultiSig(sellerInput.subtract(trade.getTxFee().multiply(2)));
        walletService.saveAddressEntryList();
        TradingPeer tradingPeer = processModel.getTradingPeer();
        Transaction depositTx = processModel.getTradeWalletService().takerSignsAndPublishesDepositTx(true, contractHash, processModel.getPreparedDepositTx(), tradingPeer.getRawTransactionInputs(), sellerInputs, tradingPeer.getMultiSigPubKey(), sellerMultiSigPubKey, trade.getArbitratorBtcPubKey(), new FutureCallback<Transaction>() {

            @Override
            public void onSuccess(Transaction transaction) {
                if (!completed) {
                    log.trace("takerSignAndPublishTx succeeded " + transaction);
                    trade.setState(Trade.State.TAKER_PUBLISHED_DEPOSIT_TX);
                    walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE);
                    complete();
                } else {
                    log.warn("We got the onSuccess callback called after the timeout has been triggered a complete().");
                }
            }

            @Override
            public void onFailure(@NotNull Throwable t) {
                if (!completed) {
                    failed(t);
                } else {
                    log.warn("We got the onFailure callback called after the timeout has been triggered a complete().");
                }
            }
        });
        // We set the deposit tx in case we get the onFailure called.
        trade.setDepositTx(depositTx);
    } catch (Throwable t) {
        final Contract contract = trade.getContract();
        if (contract != null)
            contract.printDiff(processModel.getTradingPeer().getContractAsJson());
        failed(t);
    }
}
Also used : AddressEntry(bisq.core.btc.AddressEntry) RawTransactionInput(bisq.core.btc.data.RawTransactionInput) Coin(org.bitcoinj.core.Coin) TradingPeer(bisq.core.trade.protocol.TradingPeer) Transaction(org.bitcoinj.core.Transaction) BtcWalletService(bisq.core.btc.wallet.BtcWalletService) Contract(bisq.core.trade.Contract)

Example 10 with AddressEntry

use of bisq.core.btc.AddressEntry in project bisq-core by bisq-network.

the class TakerSendPayDepositRequest method run.

@Override
protected void run() {
    try {
        runInterceptHook();
        checkNotNull(trade.getTradeAmount(), "TradeAmount must not be null");
        checkNotNull(trade.getTakerFeeTxId(), "TakeOfferFeeTxId must not be null");
        final User user = processModel.getUser();
        checkNotNull(user, "User must not be null");
        final List<NodeAddress> acceptedArbitratorAddresses = user.getAcceptedArbitratorAddresses();
        final List<NodeAddress> acceptedMediatorAddresses = user.getAcceptedMediatorAddresses();
        checkNotNull(acceptedArbitratorAddresses, "acceptedArbitratorAddresses must not be null");
        checkNotNull(acceptedMediatorAddresses, "acceptedMediatorAddresses must not be null");
        BtcWalletService walletService = processModel.getBtcWalletService();
        String id = processModel.getOffer().getId();
        checkArgument(!walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG).isPresent(), "addressEntry must not be set here.");
        AddressEntry addressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.MULTI_SIG);
        byte[] takerMultiSigPubKey = addressEntry.getPubKey();
        processModel.setMyMultiSigPubKey(takerMultiSigPubKey);
        AddressEntry takerPayoutAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.TRADE_PAYOUT);
        String takerPayoutAddressString = takerPayoutAddressEntry.getAddressString();
        final String offerId = processModel.getOfferId();
        // Taker has to use offerId as nonce (he cannot manipulate that - so we avoid to have a challenge protocol for passing the nonce we want to get signed)
        // He cannot manipulate the offerId - so we avoid to have a challenge protocol for passing the nonce we want to get signed.
        final PaymentAccountPayload paymentAccountPayload = checkNotNull(processModel.getPaymentAccountPayload(trade), "processModel.getPaymentAccountPayload(trade) must not be null");
        byte[] sig = Sig.sign(processModel.getKeyRing().getSignatureKeyPair().getPrivate(), offerId.getBytes());
        PayDepositRequest message = new PayDepositRequest(offerId, processModel.getMyNodeAddress(), trade.getTradeAmount().value, trade.getTradePrice().getValue(), trade.getTxFee().getValue(), trade.getTakerFee().getValue(), trade.isCurrencyForTakerFeeBtc(), processModel.getRawTransactionInputs(), processModel.getChangeOutputValue(), processModel.getChangeOutputAddress(), takerMultiSigPubKey, takerPayoutAddressString, processModel.getPubKeyRing(), paymentAccountPayload, processModel.getAccountId(), trade.getTakerFeeTxId(), new ArrayList<>(acceptedArbitratorAddresses), new ArrayList<>(acceptedMediatorAddresses), trade.getArbitratorNodeAddress(), trade.getMediatorNodeAddress(), UUID.randomUUID().toString(), Version.getP2PMessageVersion(), sig, new Date().getTime());
        processModel.getP2PService().sendEncryptedDirectMessage(trade.getTradingPeerNodeAddress(), processModel.getTradingPeer().getPubKeyRing(), message, new SendDirectMessageListener() {

            @Override
            public void onArrived() {
                log.debug("Message arrived at peer. tradeId={}, message{}", id, message);
                complete();
            }

            @Override
            public void onFault() {
                appendToErrorMessage("Sending message failed: message=" + message + "\nerrorMessage=" + errorMessage);
                failed();
            }
        });
    } catch (Throwable t) {
        failed(t);
    }
}
Also used : User(bisq.core.user.User) AddressEntry(bisq.core.btc.AddressEntry) PaymentAccountPayload(bisq.core.payment.payload.PaymentAccountPayload) SendDirectMessageListener(bisq.network.p2p.SendDirectMessageListener) Date(java.util.Date) PayDepositRequest(bisq.core.trade.messages.PayDepositRequest) BtcWalletService(bisq.core.btc.wallet.BtcWalletService) NodeAddress(bisq.network.p2p.NodeAddress)

Aggregations

AddressEntry (bisq.core.btc.AddressEntry)27 Coin (org.bitcoinj.core.Coin)16 BtcWalletService (bisq.core.btc.wallet.BtcWalletService)15 Transaction (org.bitcoinj.core.Transaction)14 Address (org.bitcoinj.core.Address)8 AddressEntryException (bisq.core.btc.AddressEntryException)7 TradingPeer (bisq.core.trade.protocol.TradingPeer)7 InsufficientFundsException (bisq.core.btc.InsufficientFundsException)6 FeeService (bisq.core.provider.fee.FeeService)6 Preferences (bisq.core.user.Preferences)6 Optional (java.util.Optional)6 Collectors (java.util.stream.Collectors)6 TransactionVerificationException (bisq.core.btc.exceptions.TransactionVerificationException)5 Preconditions.checkNotNull (com.google.common.base.Preconditions.checkNotNull)5 FutureCallback (com.google.common.util.concurrent.FutureCallback)5 List (java.util.List)5 Set (java.util.Set)5 DeterministicKey (org.bitcoinj.crypto.DeterministicKey)5 AddressFormatException (org.bitcoinj.core.AddressFormatException)4 SendRequest (org.bitcoinj.wallet.SendRequest)4