Search in sources :

Example 1 with VerificationException

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

the class AbstractBitcoinNetParams method checkDifficultyTransitions.

@Override
public void checkDifficultyTransitions(final StoredBlock storedPrev, final Block nextBlock, final BlockStore blockStore) throws VerificationException, BlockStoreException {
    Block prev = storedPrev.getHeader();
    // Is this supposed to be a difficulty transition point?
    if (!isDifficultyTransitionPoint(storedPrev)) {
        // No ... so check the difficulty didn't actually change.
        if (nextBlock.getDifficultyTarget() != prev.getDifficultyTarget())
            throw new VerificationException("Unexpected change in difficulty at height " + storedPrev.getHeight() + ": " + Long.toHexString(nextBlock.getDifficultyTarget()) + " vs " + Long.toHexString(prev.getDifficultyTarget()));
        return;
    }
    // We need to find a block far back in the chain. It's OK that this is expensive because it only occurs every
    // two weeks after the initial block chain download.
    final Stopwatch watch = Stopwatch.createStarted();
    StoredBlock cursor = blockStore.get(prev.getHash());
    for (int i = 0; i < this.getInterval() - 1; i++) {
        if (cursor == null) {
            // This should never happen. If it does, it means we are following an incorrect or busted chain.
            throw new VerificationException("Difficulty transition point but we did not find a way back to the genesis block.");
        }
        cursor = blockStore.get(cursor.getHeader().getPrevBlockHash());
    }
    watch.stop();
    if (watch.elapsed(TimeUnit.MILLISECONDS) > 50)
        log.info("Difficulty transition traversal took {}", watch);
    Block blockIntervalAgo = cursor.getHeader();
    int timespan = (int) (prev.getTimeSeconds() - blockIntervalAgo.getTimeSeconds());
    // Limit the adjustment step.
    final int targetTimespan = this.getTargetTimespan();
    if (timespan < targetTimespan / 4)
        timespan = targetTimespan / 4;
    if (timespan > targetTimespan * 4)
        timespan = targetTimespan * 4;
    BigInteger newTarget = Utils.decodeCompactBits(prev.getDifficultyTarget());
    newTarget = newTarget.multiply(BigInteger.valueOf(timespan));
    newTarget = newTarget.divide(BigInteger.valueOf(targetTimespan));
    if (newTarget.compareTo(this.getMaxTarget()) > 0) {
        log.info("Difficulty hit proof of work limit: {}", newTarget.toString(16));
        newTarget = this.getMaxTarget();
    }
    int accuracyBytes = (int) (nextBlock.getDifficultyTarget() >>> 24) - 3;
    long receivedTargetCompact = nextBlock.getDifficultyTarget();
    // The calculated difficulty is to a higher precision than received, so reduce here.
    BigInteger mask = BigInteger.valueOf(0xFFFFFFL).shiftLeft(accuracyBytes * 8);
    newTarget = newTarget.and(mask);
    long newTargetCompact = Utils.encodeCompactBits(newTarget);
    if (newTargetCompact != receivedTargetCompact)
        throw new VerificationException("Network provided difficulty bits do not match what was calculated: " + Long.toHexString(newTargetCompact) + " vs " + Long.toHexString(receivedTargetCompact));
}
Also used : StoredBlock(org.bitcoinj.core.StoredBlock) Stopwatch(com.google.common.base.Stopwatch) StoredBlock(org.bitcoinj.core.StoredBlock) Block(org.bitcoinj.core.Block) VerificationException(org.bitcoinj.core.VerificationException) BigInteger(java.math.BigInteger)

Example 2 with VerificationException

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

the class CatenaUtils method isCatenaTxHelper.

/**
 * Returns true if the specified tx is a valid Catena TX created from the
 * UTXO in prevLink and signed by chainAddr.
 * If prevLink is null, then the previous UTXO is not checked.
 * If chainAddr is null, then the chain's address is not checked.
 *
 * @param tx
 * @param chainAddr
 * @param prevLink
 * @return
 */
private static boolean isCatenaTxHelper(Transaction tx, boolean verifySig, Address chainAddr, TransactionOutput prevLink, boolean checkPrevLinkIndex) {
    checkNotNull(tx);
    log.trace("Inspecting TX " + tx);
    String txid = tx.getHashAsString();
    NetworkParameters params = tx.getParams();
    // Check if this TX is properly connected to the previous TX's (unique) UTXO
    if (prevLink != null) {
        // Check the prev TX's output is #0
        if (checkPrevLinkIndex && prevLink.getIndex() != 0) {
            log.warn("Index of UTXO '" + prevLink.getOutPointFor() + "' was '" + prevLink.getIndex() + "' but expected index 0 (w.r.t. to txid=" + txid + ")");
            return false;
        }
        if (checkConnectedTo(tx, prevLink) == false)
            return false;
        // Check that the address in the previous output matches the one provided to this call
        Address prevLinkAddr = prevLink.getAddressFromP2PKHScript(tx.getParams());
        if (chainAddr != null && prevLinkAddr.equals(chainAddr) == false) {
            log.warn("Address in UTXO '" + prevLink.getOutPointFor() + "' was '" + prevLinkAddr + "' but expected chain address '" + chainAddr + "' (w.r.t. to txid=" + txid + ")");
            return false;
        }
        // Verify the signature on the first input
        if (verifySig) {
            TransactionInput firstInput = tx.getInput(0);
            try {
                firstInput.verify();
            } catch (ScriptException e) {
                log.warn("TX '" + txid + "' has invalid signature: " + Throwables.getStackTraceAsString(e));
                return false;
            } catch (VerificationException e) {
                log.warn("TX '" + txid + "' has invalid format: " + Throwables.getStackTraceAsString(e));
                return false;
            } catch (Throwable e) {
                log.warn("TX '" + txid + "' unknown signature verification error: " + Throwables.getStackTraceAsString(e));
                return false;
            }
        }
    }
    // Make sure we have only one input
    if (tx.getInputs().size() != 1) {
        log.warn("expected only one input in tx '" + txid + "', got " + tx.getInputs().size());
        return false;
    }
    // Make sure we have only two outputs (data + next)
    if (tx.getOutputs().size() != 2) {
        log.warn("expected two outputs in tx '" + txid + "' (continuation and OP_RETURN), got " + tx.getOutputs().size());
        return false;
    }
    // Make sure chain's address is correct in first output
    Address firstOutputAddr = tx.getOutput(0).getAddressFromP2PKHScript(params);
    if (chainAddr != null && !firstOutputAddr.equals(chainAddr)) {
        log.warn("first output address of '" + txid + "' was '" + firstOutputAddr + "'; expected chain address '" + chainAddr + "'");
        return false;
    }
    // Make sure 2nd output is an OP_RETURN
    Script secondOutput = tx.getOutput(1).getScriptPubKey();
    if (!secondOutput.isOpReturn()) {
        log.warn("second output of '" + txid + "' was supposed to be an OP_RETURN, got '" + secondOutput + "'");
        return false;
    }
    // All is well.
    return true;
}
Also used : ScriptException(org.bitcoinj.core.ScriptException) Script(org.bitcoinj.script.Script) Address(org.bitcoinj.core.Address) NetworkParameters(org.bitcoinj.core.NetworkParameters) VerificationException(org.bitcoinj.core.VerificationException) TransactionInput(org.bitcoinj.core.TransactionInput)

Example 3 with VerificationException

use of org.bitcoinj.core.VerificationException in project bitcoin-wallet by bitcoin-wallet.

the class AcceptBluetoothService method handleTx.

private boolean handleTx(final Transaction tx) {
    log.info("tx {} arrived via blueooth", tx.getTxId());
    final Wallet wallet = this.wallet.getValue();
    try {
        if (wallet.isTransactionRelevant(tx)) {
            wallet.receivePending(tx, null);
            new BlockchainServiceLiveData(this).observe(this, blockchainService -> blockchainService.broadcastTransaction(tx));
        } else {
            log.info("tx {} irrelevant", tx.getTxId());
        }
        return true;
    } catch (final VerificationException x) {
        log.info("cannot verify tx " + tx.getTxId() + " received via bluetooth", x);
    }
    return false;
}
Also used : BlockchainServiceLiveData(de.schildbach.wallet.data.BlockchainServiceLiveData) Wallet(org.bitcoinj.wallet.Wallet) VerificationException(org.bitcoinj.core.VerificationException)

Example 4 with VerificationException

use of org.bitcoinj.core.VerificationException in project bitcoin-wallet by bitcoin-wallet.

the class SendCoinsQrActivity method onActivityResult.

@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
    if (requestCode == REQUEST_CODE_SCAN && resultCode == Activity.RESULT_OK) {
        final String input = intent.getStringExtra(ScanActivity.INTENT_EXTRA_RESULT);
        new StringInputParser(input) {

            @Override
            protected void handlePaymentIntent(final PaymentIntent paymentIntent) {
                SendCoinsActivity.start(SendCoinsQrActivity.this, paymentIntent);
                SendCoinsQrActivity.this.finish();
            }

            @Override
            protected void handlePrivateKey(final PrefixedChecksummedBytes key) {
                if (Constants.ENABLE_SWEEP_WALLET) {
                    SweepWalletActivity.start(SendCoinsQrActivity.this, key);
                    SendCoinsQrActivity.this.finish();
                } else {
                    super.handlePrivateKey(key);
                }
            }

            @Override
            protected void handleDirectTransaction(final Transaction transaction) throws VerificationException {
                walletActivityViewModel.broadcastTransaction(transaction);
                SendCoinsQrActivity.this.finish();
            }

            @Override
            protected void error(final int messageResId, final Object... messageArgs) {
                final DialogBuilder dialog = DialogBuilder.dialog(SendCoinsQrActivity.this, 0, messageResId, messageArgs);
                dialog.singleDismissButton(dismissListener);
                dialog.show();
            }

            private final OnClickListener dismissListener = (dialog, which) -> SendCoinsQrActivity.this.finish();
        }.parse();
    } else {
        finish();
    }
}
Also used : PaymentIntent(de.schildbach.wallet.data.PaymentIntent) Bundle(android.os.Bundle) Transaction(org.bitcoinj.core.Transaction) ViewModelProvider(androidx.lifecycle.ViewModelProvider) OnClickListener(android.content.DialogInterface.OnClickListener) ScanActivity(de.schildbach.wallet.ui.scan.ScanActivity) Intent(android.content.Intent) VerificationException(org.bitcoinj.core.VerificationException) PrefixedChecksummedBytes(org.bitcoinj.core.PrefixedChecksummedBytes) StringInputParser(de.schildbach.wallet.ui.InputParser.StringInputParser) SendCoinsActivity(de.schildbach.wallet.ui.send.SendCoinsActivity) SweepWalletActivity(de.schildbach.wallet.ui.send.SweepWalletActivity) Activity(android.app.Activity) Constants(de.schildbach.wallet.Constants) PrefixedChecksummedBytes(org.bitcoinj.core.PrefixedChecksummedBytes) Transaction(org.bitcoinj.core.Transaction) StringInputParser(de.schildbach.wallet.ui.InputParser.StringInputParser) VerificationException(org.bitcoinj.core.VerificationException) OnClickListener(android.content.DialogInterface.OnClickListener) PaymentIntent(de.schildbach.wallet.data.PaymentIntent)

Example 5 with VerificationException

use of org.bitcoinj.core.VerificationException in project bitcoin-wallet by bitcoin-wallet.

the class WalletActivity method onActivityResult.

@Override
public void onActivityResult(final int requestCode, final int resultCode, final Intent intent) {
    if (requestCode == REQUEST_CODE_SCAN) {
        if (resultCode == Activity.RESULT_OK) {
            final String input = intent.getStringExtra(ScanActivity.INTENT_EXTRA_RESULT);
            new StringInputParser(input) {

                @Override
                protected void handlePaymentIntent(final PaymentIntent paymentIntent) {
                    SendCoinsActivity.start(WalletActivity.this, paymentIntent);
                }

                @Override
                protected void handlePrivateKey(final PrefixedChecksummedBytes key) {
                    if (Constants.ENABLE_SWEEP_WALLET)
                        SweepWalletActivity.start(WalletActivity.this, key);
                    else
                        super.handlePrivateKey(key);
                }

                @Override
                protected void handleDirectTransaction(final Transaction tx) throws VerificationException {
                    walletActivityViewModel.broadcastTransaction(tx);
                }

                @Override
                protected void error(final int messageResId, final Object... messageArgs) {
                    final DialogBuilder dialog = DialogBuilder.dialog(WalletActivity.this, R.string.button_scan, messageResId, messageArgs);
                    dialog.singleDismissButton(null);
                    dialog.show();
                }
            }.parse();
        }
    } else {
        super.onActivityResult(requestCode, resultCode, intent);
    }
}
Also used : PrefixedChecksummedBytes(org.bitcoinj.core.PrefixedChecksummedBytes) Transaction(org.bitcoinj.core.Transaction) StringInputParser(de.schildbach.wallet.ui.InputParser.StringInputParser) VerificationException(org.bitcoinj.core.VerificationException) PaymentIntent(de.schildbach.wallet.data.PaymentIntent)

Aggregations

VerificationException (org.bitcoinj.core.VerificationException)9 PaymentIntent (de.schildbach.wallet.data.PaymentIntent)6 StringInputParser (de.schildbach.wallet.ui.InputParser.StringInputParser)6 Transaction (org.bitcoinj.core.Transaction)6 PrefixedChecksummedBytes (org.bitcoinj.core.PrefixedChecksummedBytes)4 DialogBuilder (de.schildbach.wallet.ui.DialogBuilder)2 Address (org.bitcoinj.core.Address)2 Activity (android.app.Activity)1 OnClickListener (android.content.DialogInterface.OnClickListener)1 Intent (android.content.Intent)1 Bundle (android.os.Bundle)1 ViewModelProvider (androidx.lifecycle.ViewModelProvider)1 Stopwatch (com.google.common.base.Stopwatch)1 Constants (de.schildbach.wallet.Constants)1 BlockchainServiceLiveData (de.schildbach.wallet.data.BlockchainServiceLiveData)1 ScanActivity (de.schildbach.wallet.ui.scan.ScanActivity)1 SendCoinsActivity (de.schildbach.wallet.ui.send.SendCoinsActivity)1 SweepWalletActivity (de.schildbach.wallet.ui.send.SweepWalletActivity)1 BigInteger (java.math.BigInteger)1 Block (org.bitcoinj.core.Block)1