Disable max money check on networks with no supply cap

This commit is contained in:
Ross Nicoll 2016-02-02 18:47:20 +00:00
parent 8a41fd471f
commit 8841371922
6 changed files with 21 additions and 8 deletions

View File

@ -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) {

View File

@ -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);

View File

@ -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();
}
}
/**

View File

@ -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();
}
}

View File

@ -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 {

View File

@ -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();