From 88413719225429b96862f031865d7f567ca05f14 Mon Sep 17 00:00:00 2001 From: Ross Nicoll Date: Tue, 2 Feb 2016 18:47:20 +0000 Subject: [PATCH] Disable max money check on networks with no supply cap --- core/src/main/java/org/bitcoinj/core/Transaction.java | 3 +-- .../java/org/bitcoinj/core/TransactionOutput.java | 2 +- .../channels/StoredPaymentChannelClientStates.java | 11 +++++++++-- .../channels/StoredPaymentChannelServerStates.java | 8 +++++++- .../bitcoinj/protocols/payments/PaymentProtocol.java | 3 ++- .../test/java/org/bitcoinj/core/TransactionTest.java | 2 +- 6 files changed, 21 insertions(+), 8 deletions(-) diff --git a/core/src/main/java/org/bitcoinj/core/Transaction.java b/core/src/main/java/org/bitcoinj/core/Transaction.java index aacf30010..489ee6f28 100644 --- a/core/src/main/java/org/bitcoinj/core/Transaction.java +++ b/core/src/main/java/org/bitcoinj/core/Transaction.java @@ -1239,8 +1239,7 @@ public class Transaction extends ChildMessage { if (output.getValue().signum() < 0) // getValue() can throw IllegalStateException throw new VerificationException.NegativeValueOutput(); valueOut = valueOut.add(output.getValue()); - // Duplicate the MAX_MONEY check from Coin.add() in case someone accidentally removes it. - if (valueOut.compareTo(NetworkParameters.MAX_MONEY) > 0) + if (params.hasMaxMoney() && valueOut.compareTo(params.getMaxMoney()) > 0) throw new IllegalArgumentException(); } } catch (IllegalStateException e) { diff --git a/core/src/main/java/org/bitcoinj/core/TransactionOutput.java b/core/src/main/java/org/bitcoinj/core/TransactionOutput.java index 1c4759a4f..2423a3393 100644 --- a/core/src/main/java/org/bitcoinj/core/TransactionOutput.java +++ b/core/src/main/java/org/bitcoinj/core/TransactionOutput.java @@ -102,7 +102,7 @@ public class TransactionOutput extends ChildMessage { // 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.signum() >= 0 || value.equals(Coin.NEGATIVE_SATOSHI), "Negative values not allowed"); - checkArgument(value.compareTo(NetworkParameters.MAX_MONEY) <= 0, "Values larger than MAX_MONEY not allowed"); + checkArgument(!params.hasMaxMoney() || value.compareTo(params.getMaxMoney()) <= 0, "Values larger than MAX_MONEY not allowed"); this.value = value.value; this.scriptBytes = scriptBytes; setParent(parent); diff --git a/core/src/main/java/org/bitcoinj/protocols/channels/StoredPaymentChannelClientStates.java b/core/src/main/java/org/bitcoinj/protocols/channels/StoredPaymentChannelClientStates.java index e27624346..152e95d39 100644 --- a/core/src/main/java/org/bitcoinj/protocols/channels/StoredPaymentChannelClientStates.java +++ b/core/src/main/java/org/bitcoinj/protocols/channels/StoredPaymentChannelClientStates.java @@ -269,11 +269,14 @@ public class StoredPaymentChannelClientStates implements WalletExtension { public byte[] serializeWalletExtension() { lock.lock(); try { + final NetworkParameters params = getNetworkParameters(); ClientState.StoredClientPaymentChannels.Builder builder = ClientState.StoredClientPaymentChannels.newBuilder(); for (StoredClientChannel channel : mapChannels.values()) { // First a few asserts to make sure things won't break - checkState(channel.valueToMe.signum() >= 0 && channel.valueToMe.compareTo(NetworkParameters.MAX_MONEY) <= 0); - checkState(channel.refundFees.signum() >= 0 && channel.refundFees.compareTo(NetworkParameters.MAX_MONEY) <= 0); + checkState(channel.valueToMe.signum() >= 0 && + (!params.hasMaxMoney() || channel.valueToMe.compareTo(params.getMaxMoney()) <= 0)); + checkState(channel.refundFees.signum() >= 0 && + (!params.hasMaxMoney() || channel.refundFees.compareTo(params.getMaxMoney()) <= 0)); checkNotNull(channel.myKey.getPubKey()); checkState(channel.refund.getConfidence().getSource() == TransactionConfidence.Source.SELF); final ClientState.StoredClientPaymentChannel.Builder value = ClientState.StoredClientPaymentChannel.newBuilder() @@ -337,6 +340,10 @@ public class StoredPaymentChannelClientStates implements WalletExtension { lock.unlock(); } } + + private NetworkParameters getNetworkParameters() { + return this.containingWallet.getNetworkParameters(); + } } /** diff --git a/core/src/main/java/org/bitcoinj/protocols/channels/StoredPaymentChannelServerStates.java b/core/src/main/java/org/bitcoinj/protocols/channels/StoredPaymentChannelServerStates.java index 9a1b61b2f..257149041 100644 --- a/core/src/main/java/org/bitcoinj/protocols/channels/StoredPaymentChannelServerStates.java +++ b/core/src/main/java/org/bitcoinj/protocols/channels/StoredPaymentChannelServerStates.java @@ -213,11 +213,13 @@ public class StoredPaymentChannelServerStates implements WalletExtension { public byte[] serializeWalletExtension() { lock.lock(); try { + final NetworkParameters params = getNetworkParameters(); ServerState.StoredServerPaymentChannels.Builder builder = ServerState.StoredServerPaymentChannels.newBuilder(); for (StoredServerChannel channel : mapChannels.values()) { // First a few asserts to make sure things won't break // TODO: Pull MAX_MONEY from network parameters - checkState(channel.bestValueToMe.signum() >= 0 && channel.bestValueToMe.compareTo(NetworkParameters.MAX_MONEY) <= 0); + checkState(channel.bestValueToMe.signum() >= 0 && + (!params.hasMaxMoney() || channel.bestValueToMe.compareTo(params.getMaxMoney()) <= 0)); checkState(channel.refundTransactionUnlockTimeSecs > 0); checkNotNull(channel.myKey.getPrivKeyBytes()); ServerState.StoredServerPaymentChannel.Builder channelBuilder = ServerState.StoredServerPaymentChannel.newBuilder() @@ -271,4 +273,8 @@ public class StoredPaymentChannelServerStates implements WalletExtension { lock.unlock(); } } + + private NetworkParameters getNetworkParameters() { + return wallet.getNetworkParameters(); + } } diff --git a/core/src/main/java/org/bitcoinj/protocols/payments/PaymentProtocol.java b/core/src/main/java/org/bitcoinj/protocols/payments/PaymentProtocol.java index 4483c9a4b..ac408d4af 100644 --- a/core/src/main/java/org/bitcoinj/protocols/payments/PaymentProtocol.java +++ b/core/src/main/java/org/bitcoinj/protocols/payments/PaymentProtocol.java @@ -400,7 +400,8 @@ public class PaymentProtocol { public static Protos.Output createPayToAddressOutput(@Nullable Coin amount, Address address) { Protos.Output.Builder output = Protos.Output.newBuilder(); if (amount != null) { - if (amount.compareTo(NetworkParameters.MAX_MONEY) > 0) + final NetworkParameters params = address.getParameters(); + if (params.hasMaxMoney() && amount.compareTo(params.getMaxMoney()) > 0) throw new IllegalArgumentException("Amount too big: " + amount); output.setAmount(amount.value); } else { diff --git a/core/src/test/java/org/bitcoinj/core/TransactionTest.java b/core/src/test/java/org/bitcoinj/core/TransactionTest.java index 4c94b5ac1..2f97332ed 100644 --- a/core/src/test/java/org/bitcoinj/core/TransactionTest.java +++ b/core/src/test/java/org/bitcoinj/core/TransactionTest.java @@ -84,7 +84,7 @@ public class TransactionTest { @Test(expected = VerificationException.ExcessiveValue.class) public void exceedsMaxMoney2() throws Exception { - Coin half = NetworkParameters.MAX_MONEY.divide(2).add(Coin.SATOSHI); + Coin half = PARAMS.getMaxMoney().divide(2).add(Coin.SATOSHI); tx.getOutput(0).setValue(half); tx.addOutput(half, ADDRESS); tx.verify();