Search in sources :

Example 1 with Tx

use of bisq.core.dao.blockchain.vo.Tx in project bisq-core by bisq-network.

the class JsonBlockChainExporter method maybeExport.

public void maybeExport() {
    if (dumpBlockchainData) {
        ListenableFuture<Void> future = executor.submit(() -> {
            final BsqBlockChain bsqBlockChainClone = readableBsqBlockChain.getClone();
            for (Tx tx : bsqBlockChainClone.getTxMap().values()) {
                String txId = tx.getId();
                JsonTxType txType = tx.getTxType() != TxType.UNDEFINED_TX_TYPE ? JsonTxType.valueOf(tx.getTxType().name()) : null;
                List<JsonTxOutput> outputs = new ArrayList<>();
                tx.getOutputs().stream().forEach(txOutput -> {
                    final JsonTxOutput outputForJson = new JsonTxOutput(txId, txOutput.getIndex(), txOutput.isVerified() ? txOutput.getValue() : 0, !txOutput.isVerified() ? txOutput.getValue() : 0, txOutput.getBlockHeight(), txOutput.isVerified(), tx.getBurntFee(), txOutput.getAddress(), new JsonScriptPubKey(txOutput.getPubKeyScript()), txOutput.getSpentInfo() != null ? new JsonSpentInfo(txOutput.getSpentInfo()) : null, tx.getTime(), txType, txType != null ? txType.getDisplayString() : "", txOutput.getOpReturnData() != null ? Utils.HEX.encode(txOutput.getOpReturnData()) : null);
                    outputs.add(outputForJson);
                    txOutputFileManager.writeToDisc(Utilities.objectToJson(outputForJson), outputForJson.getId());
                });
                List<JsonTxInput> inputs = tx.getInputs().stream().map(txInput -> {
                    final TxOutput connectedTxOutput = txInput.getConnectedTxOutput();
                    return new JsonTxInput(txInput.getConnectedTxOutputIndex(), txInput.getConnectedTxOutputTxId(), connectedTxOutput != null ? connectedTxOutput.getValue() : 0, connectedTxOutput != null && connectedTxOutput.isVerified(), connectedTxOutput != null ? connectedTxOutput.getAddress() : null, tx.getTime());
                }).collect(Collectors.toList());
                final JsonTx jsonTx = new JsonTx(txId, tx.getBlockHeight(), tx.getBlockHash(), tx.getTime(), inputs, outputs, txType, txType != null ? txType.getDisplayString() : "", tx.getBurntFee());
                txFileManager.writeToDisc(Utilities.objectToJson(jsonTx), txId);
            }
            bsqBlockChainFileManager.writeToDisc(Utilities.objectToJson(bsqBlockChainClone), "BsqBlockChain");
            return null;
        });
        Futures.addCallback(future, new FutureCallback<Void>() {

            public void onSuccess(Void ignore) {
                log.trace("onSuccess");
            }

            public void onFailure(@NotNull Throwable throwable) {
                log.error(throwable.toString());
                throwable.printStackTrace();
            }
        });
    }
}
Also used : ListenableFuture(com.google.common.util.concurrent.ListenableFuture) Utilities(bisq.common.util.Utilities) ReadableBsqBlockChain(bisq.core.dao.blockchain.ReadableBsqBlockChain) Inject(com.google.inject.Inject) DaoOptionKeys(bisq.core.dao.DaoOptionKeys) ArrayList(java.util.ArrayList) JsonFileManager(bisq.common.storage.JsonFileManager) Named(javax.inject.Named) BsqBlockChain(bisq.core.dao.blockchain.BsqBlockChain) Tx(bisq.core.dao.blockchain.vo.Tx) Utils(org.bitcoinj.core.Utils) IOException(java.io.IOException) TxOutput(bisq.core.dao.blockchain.vo.TxOutput) TxType(bisq.core.dao.blockchain.vo.TxType) Collectors(java.util.stream.Collectors) FutureCallback(com.google.common.util.concurrent.FutureCallback) File(java.io.File) FileUtil(bisq.common.storage.FileUtil) Futures(com.google.common.util.concurrent.Futures) List(java.util.List) Slf4j(lombok.extern.slf4j.Slf4j) Paths(java.nio.file.Paths) Storage(bisq.common.storage.Storage) NotNull(org.jetbrains.annotations.NotNull) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService) TxOutput(bisq.core.dao.blockchain.vo.TxOutput) Tx(bisq.core.dao.blockchain.vo.Tx) ArrayList(java.util.ArrayList) ReadableBsqBlockChain(bisq.core.dao.blockchain.ReadableBsqBlockChain) BsqBlockChain(bisq.core.dao.blockchain.BsqBlockChain)

Example 2 with Tx

use of bisq.core.dao.blockchain.vo.Tx in project bisq-core by bisq-network.

the class FullNodeParser method findBsqTxsInBlock.

// /////////////////////////////////////////////////////////////////////////////////////////
// Private
// /////////////////////////////////////////////////////////////////////////////////////////
private List<Tx> findBsqTxsInBlock(Block btcdBlock) throws BsqBlockchainException {
    int blockHeight = btcdBlock.getHeight();
    log.debug("Parse block at height={} ", blockHeight);
    // Check if the new block is the same chain we have built on.
    List<Tx> txList = new ArrayList<>();
    // We use a list as we want to maintain sorting of tx intra-block dependency
    List<Tx> bsqTxsInBlock = new ArrayList<>();
    // We add all transactions to the block
    long startTs = System.currentTimeMillis();
    // We don't user foreach because scope for exception would not be in method body...
    for (String txId : btcdBlock.getTx()) {
        // TODO if we use requestFee move code to later point once we found our bsq txs, so we only request it for bsq txs
        if (requestFee)
            rpcService.requestFees(txId, blockHeight, feesByBlock);
        final Tx tx = rpcService.requestTx(txId, blockHeight);
        txList.add(tx);
        checkForGenesisTx(blockHeight, bsqTxsInBlock, tx);
    }
    log.debug("Requesting {} transactions took {} ms", btcdBlock.getTx().size(), System.currentTimeMillis() - startTs);
    // Worst case is that all txs in a block are depending on another, so only one get resolved at each iteration.
    // Min tx size is 189 bytes (normally about 240 bytes), 1 MB can contain max. about 5300 txs (usually 2000).
    // Realistically we don't expect more then a few recursive calls.
    // There are some blocks with testing such dependency chains like block 130768 where at each iteration only
    // one get resolved.
    // Lately there is a patter with 24 iterations observed
    recursiveFindBsqTxs(bsqTxsInBlock, txList, blockHeight, 0, 5300);
    return bsqTxsInBlock;
}
Also used : Tx(bisq.core.dao.blockchain.vo.Tx) ArrayList(java.util.ArrayList)

Example 3 with Tx

use of bisq.core.dao.blockchain.vo.Tx in project bisq-core by bisq-network.

the class FullNodeParser method parseBlock.

BsqBlock parseBlock(Block btcdBlock) throws BsqBlockchainException, BlockNotConnectingException {
    long startTs = System.currentTimeMillis();
    List<Tx> bsqTxsInBlock = findBsqTxsInBlock(btcdBlock);
    final BsqBlock bsqBlock = new BsqBlock(btcdBlock.getHeight(), btcdBlock.getTime(), btcdBlock.getHash(), btcdBlock.getPreviousBlockHash(), ImmutableList.copyOf(bsqTxsInBlock));
    bsqBlockController.addBlockIfValid(bsqBlock);
    log.debug("parseBlock took {} ms at blockHeight {}; bsqTxsInBlock.size={}", System.currentTimeMillis() - startTs, bsqBlock.getHeight(), bsqTxsInBlock.size());
    return bsqBlock;
}
Also used : Tx(bisq.core.dao.blockchain.vo.Tx) BsqBlock(bisq.core.dao.blockchain.vo.BsqBlock)

Example 4 with Tx

use of bisq.core.dao.blockchain.vo.Tx in project bisq-core by bisq-network.

the class RpcService method requestTx.

public Tx requestTx(String txId, int blockHeight) throws BsqBlockchainException {
    try {
        RawTransaction rawTransaction = requestRawTransaction(txId);
        // rawTransaction.getTime() is in seconds but we keep it in ms internally
        final long time = rawTransaction.getTime() * 1000;
        final List<TxInput> txInputs = rawTransaction.getVIn().stream().filter(rawInput -> rawInput != null && rawInput.getVOut() != null && rawInput.getTxId() != null).map(rawInput -> new TxInput(rawInput.getTxId(), rawInput.getVOut())).collect(Collectors.toList());
        final List<TxOutput> txOutputs = rawTransaction.getVOut().stream().filter(e -> e != null && e.getN() != null && e.getValue() != null && e.getScriptPubKey() != null).map(rawOutput -> {
            byte[] opReturnData = null;
            final com.neemre.btcdcli4j.core.domain.PubKeyScript scriptPubKey = rawOutput.getScriptPubKey();
            if (scriptPubKey.getType().equals(ScriptTypes.NULL_DATA)) {
                String[] chunks = scriptPubKey.getAsm().split(" ");
                // We get on testnet a lot of "OP_RETURN 0" data, so we filter those away
                if (chunks.length == 2 && chunks[0].equals("OP_RETURN") && !"0".equals(chunks[1])) {
                    try {
                        opReturnData = Utils.HEX.decode(chunks[1]);
                    } catch (Throwable t) {
                        // We get sometimes exceptions, seems BitcoinJ
                        // cannot handle all existing OP_RETURN data, but we ignore them
                        // anyway as our OP_RETURN data is valid in BitcoinJ
                        log.warn("Error at Utils.HEX.decode(chunks[1]): " + t.toString() + " / chunks[1]=" + chunks[1]);
                    }
                }
            }
            // We don't support raw MS which are the only case where scriptPubKey.getAddresses()>1
            String address = scriptPubKey.getAddresses() != null && scriptPubKey.getAddresses().size() == 1 ? scriptPubKey.getAddresses().get(0) : null;
            final PubKeyScript pubKeyScript = dumpBlockchainData ? new PubKeyScript(scriptPubKey) : null;
            return new TxOutput(rawOutput.getN(), rawOutput.getValue().movePointRight(8).longValue(), rawTransaction.getTxId(), pubKeyScript, address, opReturnData, blockHeight);
        }).collect(Collectors.toList());
        return new Tx(txId, blockHeight, rawTransaction.getBlockHash(), time, ImmutableList.copyOf(txInputs), ImmutableList.copyOf(txOutputs));
    } catch (BitcoindException | CommunicationException e) {
        log.error("error at requestTx with txId={}, blockHeight={}", txId, blockHeight);
        throw new BsqBlockchainException(e.getMessage(), e);
    }
}
Also used : BtcdClientImpl(com.neemre.btcdcli4j.core.client.BtcdClientImpl) Coin(org.bitcoinj.core.Coin) Inject(com.google.inject.Inject) LoggerFactory(org.slf4j.LoggerFactory) DaoOptionKeys(bisq.core.dao.DaoOptionKeys) RawTransaction(com.neemre.btcdcli4j.core.domain.RawTransaction) BtcdDaemonImpl(com.neemre.btcdcli4j.daemon.BtcdDaemonImpl) BigDecimal(java.math.BigDecimal) ImmutableList(com.google.common.collect.ImmutableList) Transaction(com.neemre.btcdcli4j.core.domain.Transaction) Map(java.util.Map) PoolingHttpClientConnectionManager(org.apache.http.impl.conn.PoolingHttpClientConnectionManager) PubKeyScript(bisq.core.dao.blockchain.btcd.PubKeyScript) BitcoindException(com.neemre.btcdcli4j.core.BitcoindException) Named(javax.inject.Named) TxInput(bisq.core.dao.blockchain.vo.TxInput) CloseableHttpClient(org.apache.http.impl.client.CloseableHttpClient) Properties(java.util.Properties) Logger(org.slf4j.Logger) Tx(bisq.core.dao.blockchain.vo.Tx) Utils(org.bitcoinj.core.Utils) CommunicationException(com.neemre.btcdcli4j.core.CommunicationException) ScriptTypes(com.neemre.btcdcli4j.core.domain.enums.ScriptTypes) BtcdClient(com.neemre.btcdcli4j.core.client.BtcdClient) TxOutput(bisq.core.dao.blockchain.vo.TxOutput) Collectors(java.util.stream.Collectors) BlockListener(com.neemre.btcdcli4j.daemon.event.BlockListener) Consumer(java.util.function.Consumer) Block(com.neemre.btcdcli4j.core.domain.Block) List(java.util.List) BsqBlockchainException(bisq.core.dao.blockchain.exceptions.BsqBlockchainException) BtcdDaemon(com.neemre.btcdcli4j.daemon.BtcdDaemon) HttpClients(org.apache.http.impl.client.HttpClients) TxOutput(bisq.core.dao.blockchain.vo.TxOutput) Tx(bisq.core.dao.blockchain.vo.Tx) CommunicationException(com.neemre.btcdcli4j.core.CommunicationException) PubKeyScript(bisq.core.dao.blockchain.btcd.PubKeyScript) TxInput(bisq.core.dao.blockchain.vo.TxInput) BsqBlockchainException(bisq.core.dao.blockchain.exceptions.BsqBlockchainException) RawTransaction(com.neemre.btcdcli4j.core.domain.RawTransaction) BitcoindException(com.neemre.btcdcli4j.core.BitcoindException)

Example 5 with Tx

use of bisq.core.dao.blockchain.vo.Tx in project bisq-desktop by bisq-network.

the class ProposalListItem method setupConfidence.

private void setupConfidence() {
    final Tx tx = readableBsqBlockChain.getTxMap().get(proposal.getProposalPayload().getTxId());
    if (tx != null) {
        final String txId = tx.getId();
        // We cache the walletTransaction once found
        if (walletTransaction == null) {
            final Optional<Transaction> transactionOptional = bsqWalletService.isWalletTransaction(txId);
            transactionOptional.ifPresent(transaction -> walletTransaction = transaction);
        }
        if (walletTransaction != null) {
            // It is our tx so we get confidence updates
            if (txConfidenceListener == null) {
                txConfidenceListener = new TxConfidenceListener(txId) {

                    @Override
                    public void onTransactionConfidenceChanged(TransactionConfidence confidence) {
                        updateConfidence(confidence.getConfidenceType(), confidence.getDepthInBlocks(), confidence.numBroadcastPeers());
                    }
                };
                bsqWalletService.addTxConfidenceListener(txConfidenceListener);
            }
        } else {
            // tx from other users, we dont get confidence updates but as we have the bsq tx we can calculate it
            // we get setupConfidence called at each new block from above listener so no need to register a new listener
            int depth = bsqWalletService.getChainHeightProperty().get() - tx.getBlockHeight() + 1;
            if (depth > 0)
                updateConfidence(TransactionConfidence.ConfidenceType.BUILDING, depth, -1);
        // log.error("name={}, id ={}, depth={}", compensationRequest.getPayload().getName(), compensationRequest.getPayload().getUid(), depth);
        }
        final TransactionConfidence confidence = bsqWalletService.getConfidenceForTxId(txId);
        if (confidence != null)
            updateConfidence(confidence, confidence.getDepthInBlocks());
    }
}
Also used : Tx(bisq.core.dao.blockchain.vo.Tx) Transaction(org.bitcoinj.core.Transaction) TxConfidenceListener(bisq.core.btc.listeners.TxConfidenceListener) ToString(lombok.ToString) TransactionConfidence(org.bitcoinj.core.TransactionConfidence)

Aggregations

Tx (bisq.core.dao.blockchain.vo.Tx)12 TxOutput (bisq.core.dao.blockchain.vo.TxOutput)8 Coin (org.bitcoinj.core.Coin)6 Transaction (org.bitcoinj.core.Transaction)5 List (java.util.List)4 Collectors (java.util.stream.Collectors)4 ReadableBsqBlockChain (bisq.core.dao.blockchain.ReadableBsqBlockChain)3 TxInput (bisq.core.dao.blockchain.vo.TxInput)3 ArrayList (java.util.ArrayList)3 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)3 TransactionOutput (org.bitcoinj.core.TransactionOutput)3 BisqEnvironment (bisq.core.app.BisqEnvironment)2 TxConfidenceListener (bisq.core.btc.listeners.TxConfidenceListener)2 DaoOptionKeys (bisq.core.dao.DaoOptionKeys)2 TxType (bisq.core.dao.blockchain.vo.TxType)2 BsqNode (bisq.core.dao.node.BsqNode)2 Preferences (bisq.core.user.Preferences)2 Inject (com.google.inject.Inject)2 Date (java.util.Date)2 Named (javax.inject.Named)2