Search in sources :

Example 56 with Address

use of org.bitcoinj.core.Address in project catena-java by alinush.

the class CatenaClient method beforeBlockChainDownload.

/**
 * Sets up the wallet for the Catena client and reads back previous statements if the wallet was restarted.
 */
private void beforeBlockChainDownload() {
    wallet = getCatenaWallet();
    ext = wallet.getCatenaExtension();
    CatenaWalletListener listener = new CatenaWalletListener(wallet);
    List<Address> watchedAddrs = wallet().getWatchedAddresses();
    // should've been given a txid in the constructor.
    if (watchedAddrs.isEmpty()) {
        wallet.setRebootingHint(false);
        checkState(rootOfTrustTxid != null);
        log.info("Starting new wallet with: " + "\n\ttxid=" + rootOfTrustTxid + ", \n\tchainAddr=" + expectedChainAddr);
        // Here we Bloom filter for the root-of-trust TXID but because bitcoinj is limited and cannot redownload
        // the chain after it matched this TXN, we have to also specify the chain address here to make sure we don't
        // miss relevant blocks and TXs.
        peerGroup().addPeerFilterProvider(new TxidBloomFilterProvider(rootOfTrustTxid));
        wallet.addWatchedAddress(expectedChainAddr);
        ext.setRootOfTrustTxid(rootOfTrustTxid);
    // NOTE: Cannot set name of chain here because don't have the root-of-trust TX with the name yet
    // Otherwise, we have the chain's address in our watched addresses list which means we can read back the
    // root-of-trust txid saved in our CatenaWalletExtension.
    } else {
        wallet.setRebootingHint(true);
        checkState(watchedAddrs.size() == 1);
        Address chainAddr = watchedAddrs.get(0);
        String chainName = null;
        if (ext.hasName())
            chainName = ext.getName();
        rootOfTrustTxid = ext.getRootOfTrustTxid();
        log.info("Restarting old wallet with: " + "\n\taddr=" + chainAddr + ", \n\ttxid=" + rootOfTrustTxid + ", \n\t" + (chainName != null ? "name=" + chainName : "no chain name yet") + ", \n\tnumtxns=" + wallet.getTransactions(false).size());
        // Call onWalletChanged() here to process Catena TXs and initialize the chain
        listener.onWalletChanged(wallet);
    }
    // We just want to hear about certain events when debugging!
    wallet().addScriptChangeEventListener(Threading.SAME_THREAD, listener);
    wallet().addCoinsReceivedEventListener(Threading.SAME_THREAD, listener);
    wallet().addCoinsSentEventListener(Threading.SAME_THREAD, listener);
    // We run these listeners in the same thread as the Wallet listeners because we are concerned with race
    // conditions: as we handle an old fork, a new one can occur and we would be processing the old one with TX
    // confidence data from the new fork, possibly putting landing us in an incorrect state.
    wallet().addChangeEventListener(Threading.SAME_THREAD, listener);
    wallet().addReorganizeEventListener(Threading.SAME_THREAD, listener);
// TODO: can get extra info about reorgs by using chain().addReorganizeListener()
// Wallet is succesfully reloaded with TX from previous invocation of
// CatenaClient (i.e., wallet survives restarts).
}
Also used : Address(org.bitcoinj.core.Address)

Example 57 with Address

use of org.bitcoinj.core.Address in project catena-java by alinush.

the class ClientWallet method isTransactionRelevant.

/**
 * The client will never process the root-of-trust TX because it does not
 * have its PK added to the wallet, so the TX will seem irrelevant to the
 * wallet. To prevent that, we override this method.
 *
 * This method also adds the PK in the root-of-trust TX to the list of
 * watched addresses.
 */
@Override
public boolean isTransactionRelevant(Transaction tx) throws ScriptException {
    lock.lock();
    try {
        CatenaWalletExtension ext = getCatenaExtension();
        boolean isRelevant = super.isTransactionRelevant(tx);
        boolean isRootOfTrustTx = false;
        if (ext.hasRootOfTrustTxid()) {
            isRootOfTrustTx = ext.getRootOfTrustTxid().equals(tx.getHash());
            if (isRootOfTrustTx) {
                // NOTE: We save this in the wallet extension later, for now we just display them.
                Address chainAddr = tx.getOutput(0).getAddressFromP2PKHScript(params);
                log.debug("Identified chain address from root-of-trust TX " + tx.getHashAsString() + ": " + chainAddr);
                if (ext.hasName() == false) {
                    log.debug("Also, identified chain name from root-of-trust TX " + tx.getHashAsString() + ": " + new String(CatenaUtils.getCatenaTxData(tx)));
                }
                checkState(chainAddr != null, "No P2PKH address in the root-of-trust TX's first output");
            // NOTE: By the time we add the Catena chain's PK to the wallet it could be too late because bitcoinj
            // might've downloaded future blocks (i.e., blocks past the root-of-trust block) and ignored Catena
            // TXs in those blocks since it didn't have this PK in its Bloom filter yet. For now, this code
            // doesn't have any effect until bitcoinj will handle blockchain redownloads. That's why we also pass
            // the chain address to the CatenaClient constructor.
            // addWatchedAddresses(ImmutableList.<Address>of(chainAddr), 1);
            }
        } else {
        // log.trace("Too early to match root-of-trust TXN because TXID is not yet set in wallet extension.");
        }
        return isRelevant || isRootOfTrustTx;
    } finally {
        lock.unlock();
    }
}
Also used : Address(org.bitcoinj.core.Address) CatenaWalletExtension(org.catena.common.CatenaWalletExtension)

Example 58 with Address

use of org.bitcoinj.core.Address in project bisq-core by bisq-network.

the class SellerAsMakerCreatesAndSignsDepositTx method run.

@Override
protected void run() {
    try {
        runInterceptHook();
        checkNotNull(trade.getTradeAmount(), "trade.getTradeAmount() must not be null");
        BtcWalletService walletService = processModel.getBtcWalletService();
        String id = processModel.getOffer().getId();
        TradingPeer tradingPeer = processModel.getTradingPeer();
        final Offer offer = trade.getOffer();
        // params
        final boolean makerIsBuyer = false;
        final byte[] contractHash = Hash.getSha256Hash(trade.getContractAsJson());
        trade.setContractHash(contractHash);
        log.debug("\n\n------------------------------------------------------------\n" + "Contract as json\n" + trade.getContractAsJson() + "\n------------------------------------------------------------\n");
        final Coin makerInputAmount = offer.getSellerSecurityDeposit().add(trade.getTradeAmount());
        Optional<AddressEntry> addressEntryOptional = walletService.getAddressEntry(id, AddressEntry.Context.MULTI_SIG);
        checkArgument(addressEntryOptional.isPresent(), "addressEntryOptional must be present");
        AddressEntry makerMultiSigAddressEntry = addressEntryOptional.get();
        makerMultiSigAddressEntry.setCoinLockedInMultiSig(makerInputAmount);
        walletService.saveAddressEntryList();
        final Coin msOutputAmount = makerInputAmount.add(trade.getTxFee()).add(offer.getBuyerSecurityDeposit());
        final List<RawTransactionInput> takerRawTransactionInputs = tradingPeer.getRawTransactionInputs();
        final long takerChangeOutputValue = tradingPeer.getChangeOutputValue();
        final String takerChangeAddressString = tradingPeer.getChangeOutputAddress();
        final Address makerAddress = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE).getAddress();
        final Address makerChangeAddress = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE).getAddress();
        final byte[] buyerPubKey = tradingPeer.getMultiSigPubKey();
        final byte[] sellerPubKey = processModel.getMyMultiSigPubKey();
        checkArgument(Arrays.equals(sellerPubKey, makerMultiSigAddressEntry.getPubKey()), "sellerPubKey from AddressEntry must match the one from the trade data. trade id =" + id);
        final byte[] arbitratorBtcPubKey = trade.getArbitratorBtcPubKey();
        PreparedDepositTxAndMakerInputs result = processModel.getTradeWalletService().makerCreatesAndSignsDepositTx(makerIsBuyer, contractHash, makerInputAmount, msOutputAmount, takerRawTransactionInputs, takerChangeOutputValue, takerChangeAddressString, makerAddress, makerChangeAddress, buyerPubKey, sellerPubKey, arbitratorBtcPubKey);
        processModel.setPreparedDepositTx(result.depositTransaction);
        processModel.setRawTransactionInputs(result.rawMakerInputs);
        complete();
    } catch (Throwable t) {
        failed(t);
    }
}
Also used : Address(org.bitcoinj.core.Address) AddressEntry(bisq.core.btc.AddressEntry) RawTransactionInput(bisq.core.btc.data.RawTransactionInput) Coin(org.bitcoinj.core.Coin) TradingPeer(bisq.core.trade.protocol.TradingPeer) BtcWalletService(bisq.core.btc.wallet.BtcWalletService) Offer(bisq.core.offer.Offer) PreparedDepositTxAndMakerInputs(bisq.core.btc.data.PreparedDepositTxAndMakerInputs)

Example 59 with Address

use of org.bitcoinj.core.Address in project bisq-core by bisq-network.

the class CreateTakerFeeTx method run.

@Override
protected void run() {
    try {
        runInterceptHook();
        User user = processModel.getUser();
        NodeAddress selectedArbitratorNodeAddress = ArbitratorSelectionRule.select(user.getAcceptedArbitratorAddresses(), processModel.getOffer());
        log.debug("selectedArbitratorAddress " + selectedArbitratorNodeAddress);
        Arbitrator selectedArbitrator = user.getAcceptedArbitratorByAddress(selectedArbitratorNodeAddress);
        checkNotNull(selectedArbitrator, "selectedArbitrator must not be null at CreateTakeOfferFeeTx");
        BtcWalletService walletService = processModel.getBtcWalletService();
        String id = processModel.getOffer().getId();
        AddressEntry addressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.OFFER_FUNDING);
        AddressEntry reservedForTradeAddressEntry = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.RESERVED_FOR_TRADE);
        AddressEntry changeAddressEntry = walletService.getOrCreateAddressEntry(AddressEntry.Context.AVAILABLE);
        Address fundingAddress = addressEntry.getAddress();
        Address reservedForTradeAddress = reservedForTradeAddressEntry.getAddress();
        Address changeAddress = changeAddressEntry.getAddress();
        final TradeWalletService tradeWalletService = processModel.getTradeWalletService();
        if (trade.isCurrencyForTakerFeeBtc()) {
            tradeFeeTx = tradeWalletService.createBtcTradingFeeTx(fundingAddress, reservedForTradeAddress, changeAddress, processModel.getFundsNeededForTradeAsLong(), processModel.isUseSavingsWallet(), trade.getTakerFee(), trade.getTxFee(), selectedArbitrator.getBtcAddress(), new FutureCallback<Transaction>() {

                @Override
                public void onSuccess(Transaction transaction) {
                    // we delay one render frame to be sure we don't get called before the method call has
                    // returned (tradeFeeTx would be null in that case)
                    UserThread.execute(() -> {
                        if (!completed) {
                            processModel.setTakeOfferFeeTx(tradeFeeTx);
                            trade.setTakerFeeTxId(tradeFeeTx.getHashAsString());
                            walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING);
                            trade.setState(Trade.State.TAKER_PUBLISHED_TAKER_FEE_TX);
                            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().");
                    }
                }
            });
        } else {
            final BsqWalletService bsqWalletService = processModel.getBsqWalletService();
            Transaction preparedBurnFeeTx = processModel.getBsqWalletService().getPreparedBurnFeeTx(trade.getTakerFee());
            Transaction txWithBsqFee = tradeWalletService.completeBsqTradingFeeTx(preparedBurnFeeTx, fundingAddress, reservedForTradeAddress, changeAddress, processModel.getFundsNeededForTradeAsLong(), processModel.isUseSavingsWallet(), trade.getTxFee());
            Transaction signedTx = processModel.getBsqWalletService().signTx(txWithBsqFee);
            WalletService.checkAllScriptSignaturesForTx(signedTx);
            bsqWalletService.commitTx(signedTx);
            // We need to create another instance, otherwise the tx would trigger an invalid state exception
            // if it gets committed 2 times
            tradeWalletService.commitTx(tradeWalletService.getClonedTransaction(signedTx));
            bsqWalletService.broadcastTx(signedTx, new FutureCallback<Transaction>() {

                @Override
                public void onSuccess(@Nullable Transaction transaction) {
                    if (!completed) {
                        if (transaction != null) {
                            log.debug("Successfully sent tx with id " + transaction.getHashAsString());
                            trade.setTakerFeeTxId(transaction.getHashAsString());
                            processModel.setTakeOfferFeeTx(transaction);
                            walletService.swapTradeEntryToAvailableEntry(id, AddressEntry.Context.OFFER_FUNDING);
                            trade.setState(Trade.State.TAKER_PUBLISHED_TAKER_FEE_TX);
                            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) {
                        log.error(t.toString());
                        t.printStackTrace();
                        trade.setErrorMessage("An error occurred.\n" + "Error message:\n" + t.getMessage());
                        failed(t);
                    } else {
                        log.warn("We got the onFailure callback called after the timeout has been triggered a complete().");
                    }
                }
            });
        }
    } catch (Throwable t) {
        failed(t);
    }
}
Also used : User(bisq.core.user.User) NodeAddress(bisq.network.p2p.NodeAddress) Address(org.bitcoinj.core.Address) AddressEntry(bisq.core.btc.AddressEntry) TradeWalletService(bisq.core.btc.wallet.TradeWalletService) Arbitrator(bisq.core.arbitration.Arbitrator) Preconditions.checkNotNull(com.google.common.base.Preconditions.checkNotNull) NotNull(org.jetbrains.annotations.NotNull) Transaction(org.bitcoinj.core.Transaction) BtcWalletService(bisq.core.btc.wallet.BtcWalletService) BsqWalletService(bisq.core.btc.wallet.BsqWalletService) NodeAddress(bisq.network.p2p.NodeAddress) FutureCallback(com.google.common.util.concurrent.FutureCallback)

Example 60 with Address

use of org.bitcoinj.core.Address in project bisq-core by bisq-network.

the class BuyerSetupPayoutTxListener method run.

@Override
protected void run() {
    try {
        runInterceptHook();
        if (!trade.isPayoutPublished()) {
            BtcWalletService walletService = processModel.getBtcWalletService();
            final String id = processModel.getOffer().getId();
            Address address = walletService.getOrCreateAddressEntry(id, AddressEntry.Context.TRADE_PAYOUT).getAddress();
            final TransactionConfidence confidence = walletService.getConfidenceForAddress(address);
            if (isInNetwork(confidence)) {
                applyConfidence(confidence);
            } else {
                confidenceListener = new AddressConfidenceListener(address) {

                    @Override
                    public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
                        if (isInNetwork(confidence))
                            applyConfidence(confidence);
                    }
                };
                walletService.addAddressConfidenceListener(confidenceListener);
                tradeStateSubscription = EasyBind.subscribe(trade.stateProperty(), newValue -> {
                    if (trade.isPayoutPublished()) {
                        swapMultiSigEntry();
                        // hack to remove tradeStateSubscription at callback
                        UserThread.execute(this::unSubscribe);
                    }
                });
            }
        }
        // we complete immediately, our object stays alive because the balanceListener is stored in the WalletService
        complete();
    } catch (Throwable t) {
        failed(t);
    }
}
Also used : BtcWalletService(bisq.core.btc.wallet.BtcWalletService) Transaction(org.bitcoinj.core.Transaction) TransactionConfidence(org.bitcoinj.core.TransactionConfidence) Trade(bisq.core.trade.Trade) Subscription(org.fxmisc.easybind.Subscription) Slf4j(lombok.extern.slf4j.Slf4j) TaskRunner(bisq.common.taskrunner.TaskRunner) AddressEntry(bisq.core.btc.AddressEntry) EasyBind(org.fxmisc.easybind.EasyBind) UserThread(bisq.common.UserThread) Address(org.bitcoinj.core.Address) AddressConfidenceListener(bisq.core.btc.listeners.AddressConfidenceListener) TradeTask(bisq.core.trade.protocol.tasks.TradeTask) AddressConfidenceListener(bisq.core.btc.listeners.AddressConfidenceListener) Address(org.bitcoinj.core.Address) BtcWalletService(bisq.core.btc.wallet.BtcWalletService) TransactionConfidence(org.bitcoinj.core.TransactionConfidence)

Aggregations

Address (org.bitcoinj.core.Address)78 Transaction (org.bitcoinj.core.Transaction)32 Coin (org.bitcoinj.core.Coin)28 TransactionOutput (org.bitcoinj.core.TransactionOutput)15 TransactionInput (org.bitcoinj.core.TransactionInput)13 ArrayList (java.util.ArrayList)12 AddressEntry (bisq.core.btc.AddressEntry)11 Wallet (org.bitcoinj.wallet.Wallet)11 BtcWalletService (bisq.core.btc.wallet.BtcWalletService)10 AddressFormatException (org.bitcoinj.core.AddressFormatException)10 TransactionConfidence (org.bitcoinj.core.TransactionConfidence)10 IOException (java.io.IOException)9 SendRequest (org.bitcoinj.wallet.SendRequest)9 WalletService (io.bitsquare.btc.WalletService)8 List (java.util.List)8 Collectors (java.util.stream.Collectors)8 Nullable (javax.annotation.Nullable)8 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)8 Script (org.bitcoinj.script.Script)8 Intent (android.content.Intent)7