public void receiveLock(Transaction tx) throws VerificationException { // Can run in a peer thread. This method will only be called if a prior call to isPendingTransactionLockRelevant // returned true, so we already know by this point that it sends coins to or from our wallet, or is a double // spend against one of our other pending transactions. lock.lock(); try { tx.verify(); Transaction lockedTx = pending.get(tx.getHash()); //lockedTx.getConfidence().setConfidenceType(ConfidenceType.INSTANTX_LOCKED); confidenceChanged.put(lockedTx, TransactionConfidence.Listener.ChangeReason.TYPE); //TODO: this is causing problems later, the transaction doesn't get setAppearedInBlock, etc, Wallet crashes. //unspent.put(lockedTx.getHash(), lockedTx); //pending.remove(lockedTx); } finally { lock.unlock(); } // maybeRotateKeys() will ignore pending transactions so we don't bother calling it here (see the comments // in that function for an explanation of why). }
/** * Returns true if the tx is a valid settlement transaction. */ public synchronized boolean isSettlementTransaction(Transaction tx) { try { tx.verify(); tx.getInput(0).verify(getContractInternal().getOutput(0)); return true; } catch (VerificationException e) { return false; } }
/** * Returns true if the tx is a valid settlement transaction. */ public synchronized boolean isSettlementTransaction(Transaction tx) { try { tx.verify(); tx.getInput(0).verify(getContractInternal().getOutput(0)); return true; } catch (VerificationException e) { return false; } }
/** * Returns true if the tx is a valid settlement transaction. */ public synchronized boolean isSettlementTransaction(Transaction tx) { try { tx.verify(); tx.getInput(0).verify(getContractInternal().getOutput(0)); return true; } catch (VerificationException e) { return false; } }
/** * Returns true if the tx is a valid settlement transaction. */ public synchronized boolean isSettlementTransaction(Transaction tx) { try { tx.verify(); tx.getInput(0).verify(getContractInternal().getOutput(0)); return true; } catch (VerificationException e) { return false; } }
/** * Create a payment message. This wraps up transaction data along with anything else useful for making a payment. * * @param transactions transactions to include with the payment message * @param refundOutputs list of outputs to refund coins to, or null * @param memo arbitrary, user readable memo, or null if none * @param merchantData arbitrary merchant data, or null if none * @return created payment message */ public static Protos.Payment createPaymentMessage(List<Transaction> transactions, @Nullable List<Protos.Output> refundOutputs, @Nullable String memo, @Nullable byte[] merchantData) { Protos.Payment.Builder builder = Protos.Payment.newBuilder(); for (Transaction transaction : transactions) { transaction.verify(); builder.addTransactions(ByteString.copyFrom(transaction.unsafeBitcoinSerialize())); } if (refundOutputs != null) { for (Protos.Output output : refundOutputs) builder.addRefundTo(output); } if (memo != null) builder.setMemo(memo); if (merchantData != null) builder.setMerchantData(ByteString.copyFrom(merchantData)); return builder.build(); }
/** * Create a payment message. This wraps up transaction data along with anything else useful for making a payment. * * @param transactions transactions to include with the payment message * @param refundOutputs list of outputs to refund coins to, or null * @param memo arbitrary, user readable memo, or null if none * @param merchantData arbitrary merchant data, or null if none * @return created payment message */ public static Protos.Payment createPaymentMessage(List<Transaction> transactions, @Nullable List<Protos.Output> refundOutputs, @Nullable String memo, @Nullable byte[] merchantData) { Protos.Payment.Builder builder = Protos.Payment.newBuilder(); for (Transaction transaction : transactions) { transaction.verify(); builder.addTransactions(ByteString.copyFrom(transaction.unsafeBitcoinSerialize())); } if (refundOutputs != null) { for (Protos.Output output : refundOutputs) builder.addRefundTo(output); } if (memo != null) builder.setMemo(memo); if (merchantData != null) builder.setMerchantData(ByteString.copyFrom(merchantData)); return builder.build(); }
@Test(expected = VerificationException.EmptyInputsOrOutputs.class) public void emptyOutputs() throws Exception { tx.clearOutputs(); tx.verify(); }
@Test(expected = VerificationException.EmptyInputsOrOutputs.class) public void emptyInputs() throws Exception { tx.clearInputs(); tx.verify(); }
/** * Checks the block contents * * @param height block height, if known, or -1 otherwise. If valid, used * to validate the coinbase input script of v2 and above blocks. * @param flags flags to indicate which tests should be applied (i.e. * whether to test for height in the coinbase transaction). * @throws VerificationException if there was an error verifying the block. */ public void verifyTransactions(final int height, final EnumSet<VerifyFlag> flags) throws VerificationException { // Now we need to check that the body of the block actually matches the headers. The network won't generate // an invalid block, but if we didn't validate this then an untrusted man-in-the-middle could obtain the next // valid block from the network and simply replace the transactions in it with their own fictional // transactions that reference spent or non-existant inputs. if (transactions.isEmpty()) throw new VerificationException("Block had no transactions"); if (this.getOptimalEncodingMessageSize() > MAX_BLOCK_SIZE) throw new VerificationException("Block larger than MAX_BLOCK_SIZE"); checkTransactions(height, flags); checkMerkleRoot(); checkSigOps(); if (flags.contains(VerifyFlag.SEGWIT)) checkSegwitCommit(); for (Transaction transaction : transactions) transaction.verify(); }
/** * Checks the block contents * * @param height block height, if known, or -1 otherwise. If valid, used * to validate the coinbase input script of v2 and above blocks. * @param flags flags to indicate which tests should be applied (i.e. * whether to test for height in the coinbase transaction). * @throws VerificationException if there was an error verifying the block. */ public void verifyTransactions(final int height, final EnumSet<VerifyFlag> flags) throws VerificationException { // Now we need to check that the body of the block actually matches the headers. The network won't generate // an invalid block, but if we didn't validate this then an untrusted man-in-the-middle could obtain the next // valid block from the network and simply replace the transactions in it with their own fictional // transactions that reference spent or non-existant inputs. if (transactions.isEmpty()) throw new VerificationException("Block had no transactions"); if (this.getOptimalEncodingMessageSize() > MAX_BLOCK_SIZE) throw new VerificationException("Block larger than MAX_BLOCK_SIZE"); checkTransactions(height, flags); checkMerkleRoot(); checkSigOps(); for (Transaction transaction : transactions) transaction.verify(); }
/** * Checks the block contents * * @param height block height, if known, or -1 otherwise. If valid, used * to validate the coinbase input script of v2 and above blocks. * @param flags flags to indicate which tests should be applied (i.e. * whether to test for height in the coinbase transaction). * @throws VerificationException if there was an error verifying the block. */ public void verifyTransactions(final int height, final EnumSet<VerifyFlag> flags) throws VerificationException { // Now we need to check that the body of the block actually matches the headers. The network won't generate // an invalid block, but if we didn't validate this then an untrusted man-in-the-middle could obtain the next // valid block from the network and simply replace the transactions in it with their own fictional // transactions that reference spent or non-existant inputs. if (transactions.isEmpty()) throw new VerificationException("Block had no transactions"); if (this.getOptimalEncodingMessageSize() > MAX_BLOCK_SIZE) throw new VerificationException("Block larger than MAX_BLOCK_SIZE"); checkTransactions(height, flags); checkMerkleRoot(); checkSigOps(); for (Transaction transaction : transactions) transaction.verify(); }
@Test(expected = VerificationException.LargerThanMaxBlockSize.class) public void tooHuge() throws Exception { tx.getInput(0).setScriptBytes(new byte[Block.MAX_BLOCK_SIZE]); tx.verify(); }
@Test(expected = VerificationException.NegativeValueOutput.class) public void negativeOutput() throws Exception { tx.getOutput(0).setValue(Coin.NEGATIVE_SATOSHI); tx.verify(); }
/** * Checks the block contents * * @param height block height, if known, or -1 otherwise. If valid, used * to validate the coinbase input script of v2 and above blocks. * @param flags flags to indicate which tests should be applied (i.e. * whether to test for height in the coinbase transaction). * @throws VerificationException if there was an error verifying the block. */ public void verifyTransactions(final int height, final EnumSet<VerifyFlag> flags) throws VerificationException { // Now we need to check that the body of the block actually matches the headers. The network won't generate // an invalid block, but if we didn't validate this then an untrusted man-in-the-middle could obtain the next // valid block from the network and simply replace the transactions in it with their own fictional // transactions that reference spent or non-existant inputs. if (transactions.isEmpty()) throw new VerificationException("Block had no transactions"); if (this.getOptimalEncodingMessageSize() > (height >= params.getDIP0001BlockHeight() ? MAX_BLOCK_SIZE_DIP0001 : MAX_BLOCK_SIZE)) throw new VerificationException("Block larger than MAX_BLOCK_SIZE"); checkTransactions(height, flags); checkMerkleRoot(); checkSigOps(); for (Transaction transaction : transactions) transaction.verify(); }
@Test(expected = VerificationException.DuplicatedOutPoint.class) public void duplicateOutPoint() throws Exception { TransactionInput input = tx.getInput(0); input.setScriptBytes(new byte[1]); tx.addInput(input.duplicateDetached()); tx.verify(); }
@Test(expected = VerificationException.UnexpectedCoinbaseInput.class) public void coinbaseInputInNonCoinbaseTX() throws Exception { tx.addInput(Sha256Hash.ZERO_HASH, 0xFFFFFFFFL, new ScriptBuilder().data(new byte[10]).build()); tx.verify(); }
@Test(expected = VerificationException.CoinbaseScriptSizeOutOfRange.class) public void coinbaseScriptSigTooSmall() throws Exception { tx.clearInputs(); tx.addInput(Sha256Hash.ZERO_HASH, 0xFFFFFFFFL, new ScriptBuilder().build()); tx.verify(); }
@Test(expected = VerificationException.ExcessiveValue.class) public void exceedsMaxMoney2() throws Exception { Coin half = PARAMS.getMaxMoney().divide(2).add(Coin.SATOSHI); tx.getOutput(0).setValue(half); tx.addOutput(half, ADDRESS); tx.verify(); }
@Test(expected = VerificationException.CoinbaseScriptSizeOutOfRange.class) public void coinbaseScriptSigTooLarge() throws Exception { tx.clearInputs(); TransactionInput input = tx.addInput(Sha256Hash.ZERO_HASH, 0xFFFFFFFFL, new ScriptBuilder().data(new byte[99]).build()); assertEquals(101, input.getScriptBytes().length); tx.verify(); }