@Override public boolean isGenerated() { return tx.isCoinBase() || tx.isCoinStake(); }
@Override public boolean isGenerated() { return tx.isCoinBase() || tx.isCoinStake(); }
/** Adds a transaction to this block, with or without checking the sanity of doing so */ void addTransaction(Transaction t, boolean runSanityChecks) { unCacheTransactions(); if (transactions == null) { transactions = new ArrayList<>(); } t.setParent(this); if (runSanityChecks && transactions.size() == 0 && !t.isCoinBase()) throw new RuntimeException("Attempted to add a non-coinbase transaction as the first transaction: " + t); else if (runSanityChecks && transactions.size() > 0 && t.isCoinBase()) throw new RuntimeException("Attempted to add a coinbase transaction when there already is one: " + t); transactions.add(t); adjustLength(transactions.size(), t.length); // Force a recalculation next time the values are needed. merkleRoot = null; hash = null; }
/** Adds a transaction to this block, with or without checking the sanity of doing so */ void addTransaction(Transaction t, boolean runSanityChecks) { unCacheTransactions(); if (transactions == null) { transactions = new ArrayList<>(); } t.setParent(this); if (runSanityChecks && transactions.size() == 0 && !t.isCoinBase()) throw new RuntimeException("Attempted to add a non-coinbase transaction as the first transaction: " + t); else if (runSanityChecks && transactions.size() > 0 && t.isCoinBase()) throw new RuntimeException("Attempted to add a coinbase transaction when there already is one: " + t); transactions.add(t); adjustLength(transactions.size(), t.length); // Force a recalculation next time the values are needed. merkleRoot = null; hash = null; }
/** Adds a transaction to this block, with or without checking the sanity of doing so */ void addTransaction(Transaction t, boolean runSanityChecks) { unCacheTransactions(); if (transactions == null) { transactions = new ArrayList<Transaction>(); } t.setParent(this); if (runSanityChecks && transactions.size() == 0 && !t.isCoinBase()) throw new RuntimeException("Attempted to add a non-coinbase transaction as the first transaction: " + t); else if (runSanityChecks && transactions.size() > 0 && t.isCoinBase()) throw new RuntimeException("Attempted to add a coinbase transaction when there already is one: " + t); transactions.add(t); adjustLength(transactions.size(), t.length); // Force a recalculation next time the values are needed. merkleRoot = null; hash = null; }
/** Adds a transaction to this block, with or without checking the sanity of doing so */ void addTransaction(Transaction t, boolean runSanityChecks) { unCacheTransactions(); if (transactions == null) { transactions = new ArrayList<Transaction>(); } t.setParent(this); if (runSanityChecks && transactions.size() == 0 && !t.isCoinBase()) throw new RuntimeException("Attempted to add a non-coinbase transaction as the first transaction: " + t); else if (runSanityChecks && transactions.size() > 0 && t.isCoinBase()) throw new RuntimeException("Attempted to add a coinbase transaction when there already is one: " + t); transactions.add(t); adjustLength(transactions.size(), t.length); // Force a recalculation next time the values are needed. merkleRoot = null; hash = null; }
/** * Verify the transactions on a block. * * @param height block height, if known, or -1 otherwise. If provided, used * to validate the coinbase input script of v2 and above blocks. * @throws VerificationException if there was an error verifying the block. */ private void checkTransactions(final int height, final EnumSet<VerifyFlag> flags) throws VerificationException { // The first transaction in a block must always be a coinbase transaction. if (!transactions.get(0).isCoinBase()) throw new VerificationException("First tx is not coinbase"); if (flags.contains(Block.VerifyFlag.HEIGHT_IN_COINBASE) && height >= BLOCK_HEIGHT_GENESIS) { transactions.get(0).checkCoinBaseHeight(height); } // The rest must not be. for (int i = 1; i < transactions.size(); i++) { if (transactions.get(i).isCoinBase()) throw new VerificationException("TX " + i + " is coinbase when it should not be."); } }
/** * Verify the transactions on a block. * * @param height block height, if known, or -1 otherwise. If provided, used * to validate the coinbase input script of v2 and above blocks. * @throws VerificationException if there was an error verifying the block. */ private void checkTransactions(final int height, final EnumSet<VerifyFlag> flags) throws VerificationException { // The first transaction in a block must always be a coinbase transaction. if (!transactions.get(0).isCoinBase()) throw new VerificationException("First tx is not coinbase"); if (flags.contains(Block.VerifyFlag.HEIGHT_IN_COINBASE) && height >= BLOCK_HEIGHT_GENESIS) { transactions.get(0).checkCoinBaseHeight(height); } // The rest must not be. for (int i = 1; i < transactions.size(); i++) { if (transactions.get(i).isCoinBase()) throw new VerificationException("TX " + i + " is coinbase when it should not be."); } }
/** * Verify the transactions on a block. * * @param height block height, if known, or -1 otherwise. If provided, used * to validate the coinbase input script of v2 and above blocks. * @throws VerificationException if there was an error verifying the block. */ private void checkTransactions(final int height, final EnumSet<VerifyFlag> flags) throws VerificationException { // The first transaction in a block must always be a coinbase transaction. if (!transactions.get(0).isCoinBase()) throw new VerificationException("First tx is not coinbase"); if (flags.contains(Block.VerifyFlag.HEIGHT_IN_COINBASE) && height >= BLOCK_HEIGHT_GENESIS) { transactions.get(0).checkCoinBaseHeight(height); } // The rest must not be. for (int i = 1; i < transactions.size(); i++) { if (transactions.get(i).isCoinBase()) throw new VerificationException("TX " + i + " is coinbase when it should not be."); } }
/** * Verify the transactions on a block. * * @param height block height, if known, or -1 otherwise. If provided, used * to validate the coinbase input script of v2 and above blocks. * @throws VerificationException if there was an error verifying the block. */ private void checkTransactions(final int height, final EnumSet<VerifyFlag> flags) throws VerificationException { // The first transaction in a block must always be a coinbase transaction. if (!transactions.get(0).isCoinBase()) throw new VerificationException("First tx is not coinbase"); if (flags.contains(Block.VerifyFlag.HEIGHT_IN_COINBASE) && height >= BLOCK_HEIGHT_GENESIS) { transactions.get(0).checkCoinBaseHeight(height); } // The rest must not be. for (int i = 1; i < transactions.size(); i++) { if (transactions.get(i).isCoinBase()) throw new VerificationException("TX " + i + " is coinbase when it should not be."); } }
/** * A transaction is mature if it is either a building coinbase tx that is as deep or deeper than the required coinbase depth, or a non-coinbase tx. */ public boolean isMature() { if (!isCoinBase()) return true; if (getConfidence().getConfidenceType() != ConfidenceType.BUILDING) return false; return getConfidence().getDepthInBlocks() >= params.getSpendableCoinbaseDepth(); }
/** * A transaction is mature if it is either a building coinbase tx that is as deep or deeper than the required coinbase depth, or a non-coinbase tx. */ public boolean isMature() { if (!isCoinBase()) return true; if (getConfidence().getConfidenceType() != ConfidenceType.BUILDING) return false; return getConfidence().getDepthInBlocks() >= params.getSpendableCoinbaseDepth(); }
/** * A transaction is mature if it is either a building coinbase tx that is as deep or deeper than the required coinbase depth, or a non-coinbase tx. */ public boolean isMature() { if (!isCoinBase()) return true; if (getConfidence().getConfidenceType() != ConfidenceType.BUILDING) return false; return getConfidence().getDepthInBlocks() >= params.getSpendableCoinbaseDepth(); }
@Override public void receiveFromBlock(Transaction tx, StoredBlock block, BlockChain.NewBlockType blockType, int relativityOffset) throws VerificationException { super.receiveFromBlock(tx, block, blockType, relativityOffset); BlockChainTest.this.block[0] = block; if (isTransactionRelevant(tx) && tx.isCoinBase()) { BlockChainTest.this.coinbaseTransaction = tx; } } };
/** * A transaction is mature if it is either a building coinbase tx that is as deep or deeper than the required * coinbase depth, or a non-coinbase tx. */ public boolean isMature() { if (!isCoinBase()) return true; if (getConfidence().getConfidenceType() != ConfidenceType.BUILDING) return false; return getConfidence().getDepthInBlocks() >= params.getSpendableCoinbaseDepth(); }
/** * Check block height is in coinbase input script, for use after BIP 34 * enforcement is enabled. */ public void checkCoinBaseHeight(final int height) throws VerificationException { checkArgument(height >= Block.BLOCK_HEIGHT_GENESIS); checkState(isCoinBase()); // Check block height is in coinbase input script final TransactionInput in = this.getInputs().get(0); final ScriptBuilder builder = new ScriptBuilder(); builder.number(height); final byte[] expected = builder.build().getProgram(); final byte[] actual = in.getScriptBytes(); if (actual.length < expected.length) { throw new VerificationException.CoinbaseHeightMismatch("Block height mismatch in coinbase."); } for (int scriptIdx = 0; scriptIdx < expected.length; scriptIdx++) { if (actual[scriptIdx] != expected[scriptIdx]) { throw new VerificationException.CoinbaseHeightMismatch("Block height mismatch in coinbase."); } } }
/** * Check block height is in coinbase input script, for use after BIP 34 * enforcement is enabled. */ public void checkCoinBaseHeight(final int height) throws VerificationException { checkArgument(height >= Block.BLOCK_HEIGHT_GENESIS); checkState(isCoinBase()); // Check block height is in coinbase input script final TransactionInput in = this.getInputs().get(0); final ScriptBuilder builder = new ScriptBuilder(); builder.number(height); final byte[] expected = builder.build().getProgram(); final byte[] actual = in.getScriptBytes(); if (actual.length < expected.length) { throw new VerificationException.CoinbaseHeightMismatch("Block height mismatch in coinbase."); } for (int scriptIdx = 0; scriptIdx < expected.length; scriptIdx++) { if (actual[scriptIdx] != expected[scriptIdx]) { throw new VerificationException.CoinbaseHeightMismatch("Block height mismatch in coinbase."); } } }
/** * @param transaction The Bitcoinj transaction providing the information * @param amount The amount as calculated from the wallet */ public TransactionSeenEvent(Transaction transaction, Coin amount) { transactionId = transaction.getHashAsString(); TransactionConfidence confidence = transaction.getConfidence(); confidenceType = confidence.getConfidenceType(); if (confidenceType.equals(TransactionConfidence.ConfidenceType.BUILDING)) { depthInBlocks = confidence.getDepthInBlocks(); } else { depthInBlocks = DEPTH_IN_BLOCKS_IS_UNDEFINED; } coinbase = transaction.isCoinBase(); numberOfPeers = confidence.numBroadcastPeers(); this.amount = amount; firstAppearanceInWallet = false; }
@Test public void coinbaseTxns() throws Exception { // Covers issue 420 where the outpoint index of a coinbase tx input was being mis-serialized. Block b = PARAMS.getGenesisBlock().createNextBlockWithCoinbase(Block.BLOCK_VERSION_GENESIS, myKey.getPubKey(), FIFTY_COINS, Block.BLOCK_HEIGHT_GENESIS); Transaction coinbase = b.getTransactions().get(0); assertTrue(coinbase.isCoinBase()); BlockChain chain = new BlockChain(PARAMS, myWallet, new MemoryBlockStore(PARAMS)); assertTrue(chain.add(b)); // Wallet now has a coinbase tx in it. assertEquals(1, myWallet.getTransactions(true).size()); assertTrue(myWallet.getTransaction(coinbase.getHash()).isCoinBase()); Wallet wallet2 = roundTrip(myWallet); assertEquals(1, wallet2.getTransactions(true).size()); assertTrue(wallet2.getTransaction(coinbase.getHash()).isCoinBase()); }
/** Create a fake coinbase transaction. */ public static Transaction createFakeCoinbaseTx(final NetworkParameters params) { TransactionOutPoint outpoint = new TransactionOutPoint(params, -1, Sha256Hash.ZERO_HASH); TransactionInput input = new TransactionInput(params, null, new byte[0], outpoint); Transaction tx = new Transaction(params); tx.addInput(input); TransactionOutput outputToMe = new TransactionOutput(params, tx, Coin.FIFTY_COINS, new ECKey().toAddress(params)); tx.addOutput(outputToMe); checkState(tx.isCoinBase()); return tx; }