Search in sources :

Example 6 with TxOutput

use of bisq.core.dao.state.blockchain.TxOutput in project bisq-core by bisq-network.

the class BsqWalletService method getValueSentToMeForTransaction.

@Override
public Coin getValueSentToMeForTransaction(Transaction transaction) throws ScriptException {
    Coin result = Coin.ZERO;
    final String txId = transaction.getHashAsString();
    // We check if we have a matching BSQ tx. We do that call here to avoid repeated calls in the loop.
    Optional<Tx> txOptional = bsqStateService.getTx(txId);
    // We check all the outputs of our tx
    for (int i = 0; i < transaction.getOutputs().size(); i++) {
        TransactionOutput output = transaction.getOutputs().get(i);
        final boolean isConfirmed = output.getParentTransaction() != null && output.getParentTransaction().getConfidence().getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING;
        if (output.isMineOrWatched(wallet)) {
            if (isConfirmed) {
                if (txOptional.isPresent()) {
                    // The index of the BSQ tx outputs are the same like the bitcoinj tx outputs
                    TxOutput txOutput = txOptional.get().getTxOutputs().get(i);
                    if (bsqStateService.isBsqTxOutputType(txOutput)) {
                        // TODO check why values are not the same
                        if (txOutput.getValue() != output.getValue().value) {
                            log.warn("getValueSentToMeForTransaction: Value of BSQ output do not match BitcoinJ tx output. " + "txOutput.getValue()={}, output.getValue().value={}, txId={}", txOutput.getValue(), output.getValue().value, txId);
                        }
                        // If it is a valid BSQ output we add it
                        result = result.add(Coin.valueOf(txOutput.getValue()));
                    }
                }
            }
        /*else {
                    // TODO atm we don't display amounts of unconfirmed txs but that might change so we leave that code
                    // if it will be required
                    // If the tx is not confirmed yet we add the value and assume it is a valid BSQ output.
                    result = result.add(output.getValue());
                }*/
        }
    }
    return result;
}
Also used : Coin(org.bitcoinj.core.Coin) TxOutput(bisq.core.dao.state.blockchain.TxOutput) TransactionOutput(org.bitcoinj.core.TransactionOutput) Tx(bisq.core.dao.state.blockchain.Tx) TransactionOutPoint(org.bitcoinj.core.TransactionOutPoint)

Example 7 with TxOutput

use of bisq.core.dao.state.blockchain.TxOutput in project bisq-core by bisq-network.

the class JsonBlockChainExporter method maybeExport.

public void maybeExport() {
    if (dumpBlockchainData) {
        ListenableFuture<Void> future = executor.submit(() -> {
            final BsqState bsqStateClone = bsqStateService.getClone();
            Map<String, Tx> txMap = bsqStateService.getBlocksFromState(bsqStateClone).stream().filter(Objects::nonNull).flatMap(block -> block.getTxs().stream()).collect(Collectors.toMap(Tx::getId, tx -> tx));
            for (Tx tx : txMap.values()) {
                String txId = tx.getId();
                final Optional<TxType> optionalTxType = bsqStateService.getOptionalTxType(txId);
                optionalTxType.ifPresent(txType1 -> {
                    JsonTxType txType = txType1 != TxType.UNDEFINED_TX_TYPE ? JsonTxType.valueOf(txType1.name()) : null;
                    List<JsonTxOutput> outputs = new ArrayList<>();
                    tx.getTxOutputs().forEach(txOutput -> {
                        final Optional<SpentInfo> optionalSpentInfo = bsqStateService.getSpentInfo(txOutput);
                        final boolean isBsqOutput = bsqStateService.isBsqTxOutputType(txOutput);
                        final PubKeyScript pubKeyScript = txOutput.getPubKeyScript();
                        final JsonTxOutput outputForJson = new JsonTxOutput(txId, txOutput.getIndex(), isBsqOutput ? txOutput.getValue() : 0, !isBsqOutput ? txOutput.getValue() : 0, txOutput.getBlockHeight(), isBsqOutput, bsqStateService.getBurntFee(tx.getId()), txOutput.getAddress(), pubKeyScript != null ? new JsonScriptPubKey(pubKeyScript) : null, optionalSpentInfo.map(JsonSpentInfo::new).orElse(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.getTxInputs().stream().map(txInput -> {
                        Optional<TxOutput> optionalTxOutput = bsqStateService.getConnectedTxOutput(txInput);
                        if (optionalTxOutput.isPresent()) {
                            final TxOutput connectedTxOutput = optionalTxOutput.get();
                            final boolean isBsqOutput = bsqStateService.isBsqTxOutputType(connectedTxOutput);
                            return new JsonTxInput(txInput.getConnectedTxOutputIndex(), txInput.getConnectedTxOutputTxId(), connectedTxOutput.getValue(), isBsqOutput, connectedTxOutput.getAddress(), tx.getTime());
                        } else {
                            return null;
                        }
                    }).filter(Objects::nonNull).collect(Collectors.toList());
                    final JsonTx jsonTx = new JsonTx(txId, tx.getBlockHeight(), tx.getBlockHash(), tx.getTime(), inputs, outputs, txType, txType != null ? txType.getDisplayString() : "", bsqStateService.getBurntFee(tx.getId()));
                    txFileManager.writeToDisc(Utilities.objectToJson(jsonTx), txId);
                });
            }
            jsonFileManager.writeToDisc(Utilities.objectToJson(bsqStateClone), "BsqStateService");
            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) TxOutput(bisq.core.dao.state.blockchain.TxOutput) Inject(com.google.inject.Inject) DaoOptionKeys(bisq.core.dao.DaoOptionKeys) TxType(bisq.core.dao.state.blockchain.TxType) ArrayList(java.util.ArrayList) JsonFileManager(bisq.common.storage.JsonFileManager) Map(java.util.Map) Named(javax.inject.Named) SpentInfo(bisq.core.dao.state.blockchain.SpentInfo) BsqState(bisq.core.dao.state.BsqState) Utils(org.bitcoinj.core.Utils) Tx(bisq.core.dao.state.blockchain.Tx) BsqStateService(bisq.core.dao.state.BsqStateService) IOException(java.io.IOException) Collectors(java.util.stream.Collectors) FutureCallback(com.google.common.util.concurrent.FutureCallback) File(java.io.File) PubKeyScript(bisq.core.dao.state.blockchain.PubKeyScript) Objects(java.util.Objects) 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) Optional(java.util.Optional) NotNull(org.jetbrains.annotations.NotNull) ListeningExecutorService(com.google.common.util.concurrent.ListeningExecutorService) TxOutput(bisq.core.dao.state.blockchain.TxOutput) BsqState(bisq.core.dao.state.BsqState) ArrayList(java.util.ArrayList) PubKeyScript(bisq.core.dao.state.blockchain.PubKeyScript) SpentInfo(bisq.core.dao.state.blockchain.SpentInfo) Tx(bisq.core.dao.state.blockchain.Tx) TxType(bisq.core.dao.state.blockchain.TxType) Objects(java.util.Objects)

Example 8 with TxOutput

use of bisq.core.dao.state.blockchain.TxOutput in project bisq-core by bisq-network.

the class IssuanceService method issueBsq.

public void issueBsq(CompensationProposal compensationProposal, int chainHeight) {
    bsqStateService.getIssuanceCandidateTxOutputs().stream().filter(txOutput -> isValid(txOutput, compensationProposal, periodService, chainHeight)).forEach(txOutput -> {
        // We don't check atm if the output is unspent. We cannot use the bsqWallet as that would not
        // reflect our current block state (could have been spent at later block which is valid and
        // bsqWallet would show that spent state). We would need to support a spent status for the outputs
        // which are interpreted as BTC (as a not yet accepted comp. request).
        Optional<Tx> optionalTx = bsqStateService.getTx(compensationProposal.getTxId());
        if (optionalTx.isPresent()) {
            long amount = compensationProposal.getRequestedBsq().value;
            Tx tx = optionalTx.get();
            // We use key from first input
            TxInput txInput = tx.getTxInputs().get(0);
            String pubKey = txInput.getPubKey();
            Issuance issuance = new Issuance(tx.getId(), chainHeight, amount, pubKey);
            bsqStateService.addIssuance(issuance);
            bsqStateService.addUnspentTxOutput(txOutput);
            StringBuilder sb = new StringBuilder();
            sb.append("\n################################################################################\n");
            sb.append("We issued new BSQ to tx with ID ").append(txOutput.getTxId()).append("\nfor compensationProposal with UID ").append(compensationProposal.getTxId()).append("\n################################################################################\n");
            log.info(sb.toString());
        } else {
            // TODO throw exception
            log.error("Tx for compensation request not found. txId={}", compensationProposal.getTxId());
        }
    });
}
Also used : Inject(javax.inject.Inject) Issuance(bisq.core.dao.state.governance.Issuance) Slf4j(lombok.extern.slf4j.Slf4j) PeriodService(bisq.core.dao.state.period.PeriodService) TxOutput(bisq.core.dao.state.blockchain.TxOutput) Tx(bisq.core.dao.state.blockchain.Tx) BsqStateService(bisq.core.dao.state.BsqStateService) Optional(java.util.Optional) CompensationProposal(bisq.core.dao.governance.proposal.compensation.CompensationProposal) DaoPhase(bisq.core.dao.state.period.DaoPhase) TxInput(bisq.core.dao.state.blockchain.TxInput) Tx(bisq.core.dao.state.blockchain.Tx) Issuance(bisq.core.dao.state.governance.Issuance) TxInput(bisq.core.dao.state.blockchain.TxInput)

Example 9 with TxOutput

use of bisq.core.dao.state.blockchain.TxOutput in project bisq-core by bisq-network.

the class UnlockService method publishUnlockTx.

public void publishUnlockTx(String lockupTxId, ResultHandler resultHandler, ExceptionHandler exceptionHandler) {
    try {
        TxOutput lockupTxOutput = bsqStateService.getLockupTxOutput(lockupTxId).get();
        final Transaction unlockTx = getUnlockTx(lockupTxOutput);
        // noinspection Duplicates
        walletsManager.publishAndCommitBsqTx(unlockTx, new TxBroadcaster.Callback() {

            @Override
            public void onSuccess(Transaction transaction) {
                resultHandler.handleResult();
            }

            @Override
            public void onTxMalleability(TxMalleabilityException exception) {
                exceptionHandler.handleException(exception);
            }

            @Override
            public void onFailure(TxBroadcastException exception) {
                exceptionHandler.handleException(exception);
            }
        });
    } catch (TransactionVerificationException | InsufficientMoneyException | WalletException exception) {
        exceptionHandler.handleException(exception);
    }
}
Also used : WalletException(bisq.core.btc.exceptions.WalletException) TxOutput(bisq.core.dao.state.blockchain.TxOutput) TxMalleabilityException(bisq.core.btc.wallet.TxMalleabilityException) TxBroadcaster(bisq.core.btc.wallet.TxBroadcaster) Transaction(org.bitcoinj.core.Transaction) TransactionVerificationException(bisq.core.btc.exceptions.TransactionVerificationException) InsufficientMoneyException(org.bitcoinj.core.InsufficientMoneyException) TxBroadcastException(bisq.core.btc.wallet.TxBroadcastException)

Example 10 with TxOutput

use of bisq.core.dao.state.blockchain.TxOutput in project bisq-core by bisq-network.

the class VoteRevealService method revealVote.

private void revealVote(MyVote myVote, int chainHeight) throws IOException, WalletException, InsufficientMoneyException, TransactionVerificationException, VoteRevealException {
    // We collect all valid blind vote items we received via the p2p network.
    // It might be that different nodes have a different collection of those items.
    // To ensure we get a consensus of the data for later calculating the result we will put a hash of each
    // voters  blind vote collection into the opReturn data and check for a majority at issuance time.
    // The voters "vote" with their stake at the reveal tx for their version of the blind vote collection.
    // TODO make more clear by using param like here:
    /* List<BlindVote> blindVotes = BlindVoteConsensus.getSortedBlindVoteListOfCycle(blindVoteListService);
         VoteRevealConsensus.getHashOfBlindVoteList(blindVotes);*/
    byte[] hashOfBlindVoteList = getHashOfBlindVoteList();
    log.info("Sha256Ripemd160 hash of hashOfBlindVoteList " + Utilities.bytesAsHexString(hashOfBlindVoteList));
    byte[] opReturnData = VoteRevealConsensus.getOpReturnData(hashOfBlindVoteList, myVote.getSecretKey());
    // We search for my unspent stake output.
    // myVote is already tested if it is in current cycle at maybeRevealVotes
    // We expect that the blind vote tx and stake output is available. If not we throw an exception.
    TxOutput stakeTxOutput = bsqStateService.getUnspentBlindVoteStakeTxOutputs().stream().filter(txOutput -> txOutput.getTxId().equals(myVote.getTxId())).findFirst().orElseThrow(() -> new VoteRevealException("stakeTxOutput is not found for myVote.", myVote));
    // TODO is phase check needed and done in parser still?
    if (periodService.isTxInCorrectCycle(stakeTxOutput.getTxId(), chainHeight)) {
        Transaction voteRevealTx = getVoteRevealTx(stakeTxOutput, opReturnData);
        log.info("voteRevealTx={}", voteRevealTx);
        publishTx(voteRevealTx);
        // TODO add comment...
        // We don't want to wait for a successful broadcast to avoid issues if the broadcast succeeds delayed or at
        // next startup but the tx was actually broadcasted.
        myVoteListService.applyRevealTxId(myVote, voteRevealTx.getHashAsString());
        // Just for additional resilience we republish our blind votes
        final List<BlindVote> sortedBlindVoteListOfCycle = BlindVoteConsensus.getSortedBlindVoteListOfCycle(blindVoteListService);
        rePublishBlindVotePayloadList(sortedBlindVoteListOfCycle);
    } else {
        final String msg = "Tx of stake out put is not in our cycle. That must not happen.";
        log.error("{}. chainHeight={},  blindVoteTxId()={}", msg, chainHeight, myVote.getTxId());
        voteRevealExceptions.add(new VoteRevealException(msg, stakeTxOutput.getTxId()));
    }
}
Also used : TxOutput(bisq.core.dao.state.blockchain.TxOutput) Transaction(org.bitcoinj.core.Transaction) BlindVote(bisq.core.dao.governance.blindvote.BlindVote)

Aggregations

TxOutput (bisq.core.dao.state.blockchain.TxOutput)10 Tx (bisq.core.dao.state.blockchain.Tx)6 BsqStateService (bisq.core.dao.state.BsqStateService)4 Transaction (org.bitcoinj.core.Transaction)4 Optional (java.util.Optional)3 Slf4j (lombok.extern.slf4j.Slf4j)3 Coin (org.bitcoinj.core.Coin)3 TransactionOutPoint (org.bitcoinj.core.TransactionOutPoint)3 TransactionOutput (org.bitcoinj.core.TransactionOutput)3 Utilities (bisq.common.util.Utilities)2 TransactionVerificationException (bisq.core.btc.exceptions.TransactionVerificationException)2 WalletException (bisq.core.btc.exceptions.WalletException)2 BlindVote (bisq.core.dao.governance.blindvote.BlindVote)2 CompensationProposal (bisq.core.dao.governance.proposal.compensation.CompensationProposal)2 BsqStateListener (bisq.core.dao.state.BsqStateListener)2 Block (bisq.core.dao.state.blockchain.Block)2 TxInput (bisq.core.dao.state.blockchain.TxInput)2 DaoPhase (bisq.core.dao.state.period.DaoPhase)2 PeriodService (bisq.core.dao.state.period.PeriodService)2 List (java.util.List)2