Search in sources :

Example 1 with SpentInfo

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

the class TxInputParser method process.

@SuppressWarnings("IfCanBeSwitch")
void process(TxOutputKey txOutputKey, int blockHeight, String txId, int inputIndex) {
    bsqStateService.getUnspentTxOutput(txOutputKey).ifPresent(connectedTxOutput -> {
        long inputValue = connectedTxOutput.getValue();
        accumulatedInputValue += inputValue;
        // If we are spending an output from a blind vote tx marked as VOTE_STAKE_OUTPUT we save it in our parsingModel
        // for later verification at the outputs of a reveal tx.
        TxOutputType connectedTxOutputType = connectedTxOutput.getTxOutputType();
        switch(connectedTxOutputType) {
            case UNDEFINED:
            case GENESIS_OUTPUT:
            case BSQ_OUTPUT:
            case BTC_OUTPUT:
            case PROPOSAL_OP_RETURN_OUTPUT:
            case COMP_REQ_OP_RETURN_OUTPUT:
            case CONFISCATE_BOND_OP_RETURN_OUTPUT:
            case ISSUANCE_CANDIDATE_OUTPUT:
                break;
            case BLIND_VOTE_LOCK_STAKE_OUTPUT:
                if (voteRevealInputState == TxInputParser.VoteRevealInputState.UNKNOWN) {
                    // The connected tx output of the blind vote tx is our input for the reveal tx.
                    // We allow only one input from any blind vote tx otherwise the vote reveal tx is invalid.
                    voteRevealInputState = TxInputParser.VoteRevealInputState.VALID;
                } else {
                    log.warn("We have a tx which has >1 connected txOutputs marked as BLIND_VOTE_LOCK_STAKE_OUTPUT. " + "This is not a valid BSQ tx.");
                    voteRevealInputState = TxInputParser.VoteRevealInputState.INVALID;
                }
                break;
            case BLIND_VOTE_OP_RETURN_OUTPUT:
            case VOTE_REVEAL_UNLOCK_STAKE_OUTPUT:
            case VOTE_REVEAL_OP_RETURN_OUTPUT:
                break;
            case LOCKUP:
                // txOutput. The UNLOCK can only be spent after lockTime blocks has passed.
                if (!optionalSpentLockupTxOutput.isPresent()) {
                    optionalSpentLockupTxOutput = Optional.of(connectedTxOutput);
                    unlockBlockHeight = blockHeight + connectedTxOutput.getLockTime();
                }
                break;
            case LOCKUP_OP_RETURN_OUTPUT:
                break;
            case UNLOCK:
                // This txInput is Spending an UNLOCK txOutput
                spentUnlockConnectedTxOutputs.add(connectedTxOutput);
                // TODO  We should add unlockBlockHeight to TempTxOutput and remove unlockBlockHeight from tempTx
                // then we can use connectedTxOutput to access the unlockBlockHeight instead of the tx
                bsqStateService.getTx(connectedTxOutput.getTxId()).ifPresent(unlockTx -> {
                    // Only count the input as BSQ input if spent after unlock time
                    if (blockHeight < unlockTx.getUnlockBlockHeight()) {
                        accumulatedInputValue -= inputValue;
                        burntBondValue += inputValue;
                    }
                });
                break;
            case INVALID_OUTPUT:
            default:
                break;
        }
        bsqStateService.setSpentInfo(connectedTxOutput.getKey(), new SpentInfo(blockHeight, txId, inputIndex));
        bsqStateService.removeUnspentTxOutput(connectedTxOutput);
    });
}
Also used : TxOutputType(bisq.core.dao.state.blockchain.TxOutputType) SpentInfo(bisq.core.dao.state.blockchain.SpentInfo)

Example 2 with SpentInfo

use of bisq.core.dao.state.blockchain.SpentInfo 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)

Aggregations

SpentInfo (bisq.core.dao.state.blockchain.SpentInfo)2 FileUtil (bisq.common.storage.FileUtil)1 JsonFileManager (bisq.common.storage.JsonFileManager)1 Storage (bisq.common.storage.Storage)1 Utilities (bisq.common.util.Utilities)1 DaoOptionKeys (bisq.core.dao.DaoOptionKeys)1 BsqState (bisq.core.dao.state.BsqState)1 BsqStateService (bisq.core.dao.state.BsqStateService)1 PubKeyScript (bisq.core.dao.state.blockchain.PubKeyScript)1 Tx (bisq.core.dao.state.blockchain.Tx)1 TxOutput (bisq.core.dao.state.blockchain.TxOutput)1 TxOutputType (bisq.core.dao.state.blockchain.TxOutputType)1 TxType (bisq.core.dao.state.blockchain.TxType)1 FutureCallback (com.google.common.util.concurrent.FutureCallback)1 Futures (com.google.common.util.concurrent.Futures)1 ListenableFuture (com.google.common.util.concurrent.ListenableFuture)1 ListeningExecutorService (com.google.common.util.concurrent.ListeningExecutorService)1 Inject (com.google.inject.Inject)1 File (java.io.File)1 IOException (java.io.IOException)1