From 9953bbe5cb2f7e34c730565497e1819d010a9f04 Mon Sep 17 00:00:00 2001 From: Mike Hearn Date: Mon, 7 Oct 2013 17:57:53 +0200 Subject: [PATCH] TransactionOutput: tighter checks on values when constructing (don't allow negative values, etc). --- core/src/main/java/com/google/bitcoin/core/Transaction.java | 2 +- .../main/java/com/google/bitcoin/core/TransactionOutput.java | 5 +++++ core/src/main/java/com/google/bitcoin/core/Utils.java | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/google/bitcoin/core/Transaction.java b/core/src/main/java/com/google/bitcoin/core/Transaction.java index da5452bf..a88b0640 100644 --- a/core/src/main/java/com/google/bitcoin/core/Transaction.java +++ b/core/src/main/java/com/google/bitcoin/core/Transaction.java @@ -1014,7 +1014,7 @@ public class Transaction extends ChildMessage implements Serializable { // that position are "nulled out". Unintuitively, the value in a "null" transaction is set to -1. this.outputs = new ArrayList(this.outputs.subList(0, inputIndex + 1)); for (int i = 0; i < inputIndex; i++) - this.outputs.set(i, new TransactionOutput(params, this, BigInteger.valueOf(-1), new byte[] {})); + this.outputs.set(i, new TransactionOutput(params, this, NEGATIVE_ONE, new byte[] {})); // The signature isn't broken by new versions of the transaction issued by other parties. for (int i = 0; i < inputs.size(); i++) if (i != inputIndex) diff --git a/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java b/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java index 39f5c87f..74574143 100644 --- a/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java +++ b/core/src/main/java/com/google/bitcoin/core/TransactionOutput.java @@ -28,6 +28,7 @@ import java.io.OutputStream; import java.io.Serializable; import java.math.BigInteger; +import static com.google.common.base.Preconditions.checkArgument; import static com.google.common.base.Preconditions.checkNotNull; import static com.google.common.base.Preconditions.checkState; @@ -107,6 +108,10 @@ public class TransactionOutput extends ChildMessage implements Serializable { public TransactionOutput(NetworkParameters params, Transaction parent, BigInteger value, byte[] scriptBytes) { super(params); + // Negative values obviously make no sense, except for -1 which is used as a sentinel value when calculating + // SIGHASH_SINGLE signatures, so unfortunately we have to allow that here. + checkArgument(value.compareTo(BigInteger.ZERO) >= 0 || value.equals(Utils.NEGATIVE_ONE), "Negative values not allowed"); + checkArgument(value.compareTo(NetworkParameters.MAX_MONEY) < 0, "Values larger than MAX_MONEY not allowed"); this.value = value; this.scriptBytes = scriptBytes; parentTransaction = parent; diff --git a/core/src/main/java/com/google/bitcoin/core/Utils.java b/core/src/main/java/com/google/bitcoin/core/Utils.java index d4894224..04c2d0d0 100644 --- a/core/src/main/java/com/google/bitcoin/core/Utils.java +++ b/core/src/main/java/com/google/bitcoin/core/Utils.java @@ -38,6 +38,7 @@ import static com.google.common.base.Preconditions.checkArgument; * To enable debug logging from the library, run with -Dbitcoinj.logging=true on your command line. */ public class Utils { + public static final BigInteger NEGATIVE_ONE = BigInteger.valueOf(-1); private static final MessageDigest digest; static { try {