mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-01-30 23:02:15 +00:00
Wrap coin-ish BigIntegers into Coin class.
This commit is contained in:
parent
d2e1b14d4c
commit
022e7c27fe
@ -19,7 +19,6 @@ package com.google.bitcoin.core;
|
||||
import com.google.bitcoin.script.Script;
|
||||
import com.google.bitcoin.wallet.AbstractKeyChainEventListener;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -27,12 +26,12 @@ import java.util.List;
|
||||
*/
|
||||
public abstract class AbstractWalletEventListener extends AbstractKeyChainEventListener implements WalletEventListener {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
onChange();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
onChange();
|
||||
}
|
||||
|
||||
|
@ -166,7 +166,7 @@ public class Block extends Message {
|
||||
* <p>The half-life is controlled by {@link com.google.bitcoin.core.NetworkParameters#getSubsidyDecreaseBlockCount()}.
|
||||
* </p>
|
||||
*/
|
||||
public BigInteger getBlockInflation(int height) {
|
||||
public Coin getBlockInflation(int height) {
|
||||
return Utils.toNanoCoins(50, 0).shiftRight(height / params.getSubsidyDecreaseBlockCount());
|
||||
}
|
||||
|
||||
@ -953,7 +953,7 @@ public class Block extends Message {
|
||||
static private int txCounter;
|
||||
|
||||
/** Adds a coinbase transaction to the block. This exists for unit tests. */
|
||||
void addCoinbaseTransaction(byte[] pubKeyTo, BigInteger value) {
|
||||
void addCoinbaseTransaction(byte[] pubKeyTo, Coin value) {
|
||||
unCacheTransactions();
|
||||
transactions = new ArrayList<Transaction>();
|
||||
Transaction coinbase = new Transaction(params);
|
||||
@ -989,7 +989,7 @@ public class Block extends Message {
|
||||
* In this variant you can specify a public key (pubkey) for use in generating coinbase blocks.
|
||||
*/
|
||||
Block createNextBlock(@Nullable Address to, @Nullable TransactionOutPoint prevOut, long time,
|
||||
byte[] pubKey, BigInteger coinbaseValue) {
|
||||
byte[] pubKey, Coin coinbaseValue) {
|
||||
Block b = new Block(params);
|
||||
b.setDifficultyTarget(difficultyTarget);
|
||||
b.addCoinbaseTransaction(pubKey, coinbaseValue);
|
||||
@ -1036,7 +1036,7 @@ public class Block extends Message {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Block createNextBlock(@Nullable Address to, BigInteger value) {
|
||||
public Block createNextBlock(@Nullable Address to, Coin value) {
|
||||
return createNextBlock(to, null, Utils.currentTimeSeconds(), pubkeyForTesting, value);
|
||||
}
|
||||
|
||||
@ -1046,7 +1046,7 @@ public class Block extends Message {
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public Block createNextBlockWithCoinbase(byte[] pubKey, BigInteger coinbaseValue) {
|
||||
public Block createNextBlockWithCoinbase(byte[] pubKey, Coin coinbaseValue) {
|
||||
return createNextBlock(null, null, Utils.currentTimeSeconds(), pubKey, coinbaseValue);
|
||||
}
|
||||
|
||||
|
132
core/src/main/java/com/google/bitcoin/core/Coin.java
Normal file
132
core/src/main/java/com/google/bitcoin/core/Coin.java
Normal file
@ -0,0 +1,132 @@
|
||||
/**
|
||||
* Copyright 2014 Andreas Schildbach
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* Represents a monetary Bitcoin value. This class is immutable.
|
||||
*/
|
||||
public final class Coin implements Comparable<Coin>, Serializable {
|
||||
|
||||
public static final Coin ZERO = new Coin(BigInteger.ZERO);
|
||||
public static final Coin ONE = new Coin(BigInteger.ONE);
|
||||
public static final Coin TEN = new Coin(BigInteger.TEN);
|
||||
|
||||
private final BigInteger value;
|
||||
|
||||
public Coin(final BigInteger value) {
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public Coin(final String value, final int radix) {
|
||||
this(new BigInteger(value, radix));
|
||||
}
|
||||
|
||||
public Coin(final byte[] value) {
|
||||
this(new BigInteger(value));
|
||||
}
|
||||
|
||||
public static Coin valueOf(final long value) {
|
||||
return new Coin(BigInteger.valueOf(value));
|
||||
}
|
||||
|
||||
public Coin add(final Coin value) {
|
||||
return new Coin(this.value.add(value.value));
|
||||
}
|
||||
|
||||
public Coin subtract(final Coin value) {
|
||||
return new Coin(this.value.subtract(value.value));
|
||||
}
|
||||
|
||||
public Coin multiply(final Coin value) {
|
||||
return new Coin(this.value.multiply(value.value));
|
||||
}
|
||||
|
||||
public Coin multiply(final long value) {
|
||||
return multiply(Coin.valueOf(value));
|
||||
}
|
||||
|
||||
public Coin divide(final Coin value) {
|
||||
return new Coin(this.value.divide(value.value));
|
||||
}
|
||||
|
||||
public Coin[] divideAndRemainder(final Coin value) {
|
||||
final BigInteger[] result = this.value.divideAndRemainder(value.value);
|
||||
return new Coin[] { new Coin(result[0]), new Coin(result[1]) };
|
||||
}
|
||||
|
||||
public Coin shiftLeft(final int n) {
|
||||
return new Coin(this.value.shiftLeft(n));
|
||||
}
|
||||
|
||||
public Coin shiftRight(final int n) {
|
||||
return new Coin(this.value.shiftRight(n));
|
||||
}
|
||||
|
||||
public int signum() {
|
||||
return this.value.signum();
|
||||
}
|
||||
|
||||
public Coin negate() {
|
||||
return new Coin(this.value.negate());
|
||||
}
|
||||
|
||||
public byte[] toByteArray() {
|
||||
return this.value.toByteArray();
|
||||
}
|
||||
|
||||
public long longValue() {
|
||||
return this.value.longValue();
|
||||
}
|
||||
|
||||
public double doubleValue() {
|
||||
return this.value.doubleValue();
|
||||
}
|
||||
|
||||
public BigInteger toBigInteger() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(final Object o) {
|
||||
if (o == this)
|
||||
return true;
|
||||
if (o == null || o.getClass() != getClass())
|
||||
return false;
|
||||
final Coin other = (Coin) o;
|
||||
if (!this.value.equals(other.value))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return this.value.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(final Coin other) {
|
||||
return this.value.compareTo(other.value);
|
||||
}
|
||||
}
|
@ -23,7 +23,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.ArrayList;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
@ -175,12 +174,12 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
||||
sigOps += tx.getSigOpCount();
|
||||
}
|
||||
}
|
||||
BigInteger totalFees = BigInteger.ZERO;
|
||||
BigInteger coinbaseValue = null;
|
||||
Coin totalFees = Coin.ZERO;
|
||||
Coin coinbaseValue = null;
|
||||
for (final Transaction tx : block.transactions) {
|
||||
boolean isCoinBase = tx.isCoinBase();
|
||||
BigInteger valueIn = BigInteger.ZERO;
|
||||
BigInteger valueOut = BigInteger.ZERO;
|
||||
Coin valueIn = Coin.ZERO;
|
||||
Coin valueOut = Coin.ZERO;
|
||||
final List<Script> prevOutScripts = new LinkedList<Script>();
|
||||
if (!isCoinBase) {
|
||||
// For each input of the transaction remove the corresponding output from the set of unspent
|
||||
@ -300,16 +299,16 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
||||
throw new VerificationException("Block failed BIP30 test!");
|
||||
}
|
||||
}
|
||||
BigInteger totalFees = BigInteger.ZERO;
|
||||
BigInteger coinbaseValue = null;
|
||||
Coin totalFees = Coin.ZERO;
|
||||
Coin coinbaseValue = null;
|
||||
|
||||
if (scriptVerificationExecutor.isShutdown())
|
||||
scriptVerificationExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||
List<Future<VerificationException>> listScriptVerificationResults = new ArrayList<Future<VerificationException>>(transactions.size());
|
||||
for(final Transaction tx : transactions) {
|
||||
boolean isCoinBase = tx.isCoinBase();
|
||||
BigInteger valueIn = BigInteger.ZERO;
|
||||
BigInteger valueOut = BigInteger.ZERO;
|
||||
Coin valueIn = Coin.ZERO;
|
||||
Coin valueOut = Coin.ZERO;
|
||||
final List<Script> prevOutScripts = new LinkedList<Script>();
|
||||
if (!isCoinBase) {
|
||||
for (int index = 0; index < tx.getInputs().size(); index++) {
|
||||
|
@ -17,7 +17,6 @@
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@ -27,17 +26,17 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
||||
public class InsufficientMoneyException extends Exception {
|
||||
/** Contains the number of satoshis that would have been required to complete the operation. */
|
||||
@Nullable
|
||||
public final BigInteger missing;
|
||||
public final Coin missing;
|
||||
|
||||
protected InsufficientMoneyException() {
|
||||
this.missing = null;
|
||||
}
|
||||
|
||||
public InsufficientMoneyException(BigInteger missing) {
|
||||
public InsufficientMoneyException(Coin missing) {
|
||||
this(missing, "Insufficient money, missing " + missing + " satoshis");
|
||||
}
|
||||
|
||||
public InsufficientMoneyException(BigInteger missing, String message) {
|
||||
public InsufficientMoneyException(Coin missing, String message) {
|
||||
super(message);
|
||||
this.missing = checkNotNull(missing);
|
||||
}
|
||||
|
@ -133,7 +133,7 @@ public abstract class NetworkParameters implements Serializable {
|
||||
/**
|
||||
* The maximum money to be generated
|
||||
*/
|
||||
public static final BigInteger MAX_MONEY = new BigInteger("21000000", 10).multiply(COIN);
|
||||
public static final Coin MAX_MONEY = new Coin("21000000", 10).multiply(COIN);
|
||||
|
||||
/** Alias for TestNet3Params.get(), use that instead. */
|
||||
@Deprecated
|
||||
|
@ -45,7 +45,6 @@ import javax.annotation.Nullable;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
@ -179,7 +178,7 @@ public class PeerGroup extends AbstractExecutionThreadService implements Transac
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
// We received a relevant transaction. We MAY need to recalculate and resend the Bloom filter, but only
|
||||
// if we have received a transaction that includes a relevant pay-to-pubkey output.
|
||||
//
|
||||
|
@ -17,7 +17,6 @@
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* A StoredTransactionOutput message contains the information necessary to check a spending transaction.
|
||||
@ -31,7 +30,7 @@ public class StoredTransactionOutput implements Serializable {
|
||||
* A transaction output has some value and a script used for authenticating that the redeemer is allowed to spend
|
||||
* this output.
|
||||
*/
|
||||
private BigInteger value;
|
||||
private Coin value;
|
||||
private byte[] scriptBytes;
|
||||
|
||||
/** Hash of the transaction to which we refer. */
|
||||
@ -53,7 +52,7 @@ public class StoredTransactionOutput implements Serializable {
|
||||
* @param height the height this output was created in
|
||||
* @param scriptBytes
|
||||
*/
|
||||
public StoredTransactionOutput(Sha256Hash hash, long index, BigInteger value, int height, boolean isCoinbase, byte[] scriptBytes) {
|
||||
public StoredTransactionOutput(Sha256Hash hash, long index, Coin value, int height, boolean isCoinbase, byte[] scriptBytes) {
|
||||
this.hash = hash;
|
||||
this.index = index;
|
||||
this.value = value;
|
||||
@ -73,7 +72,7 @@ public class StoredTransactionOutput implements Serializable {
|
||||
byte[] valueBytes = new byte[8];
|
||||
if (in.read(valueBytes, 0, 8) != 8)
|
||||
throw new EOFException();
|
||||
value = BigInteger.valueOf(Utils.readInt64(valueBytes, 0));
|
||||
value = Coin.valueOf(Utils.readInt64(valueBytes, 0));
|
||||
|
||||
int scriptBytesLength = ((in.read() & 0xFF) << 0) |
|
||||
((in.read() & 0xFF) << 8) |
|
||||
@ -103,7 +102,7 @@ public class StoredTransactionOutput implements Serializable {
|
||||
* The value which this Transaction output holds
|
||||
* @return the value
|
||||
*/
|
||||
public BigInteger getValue() {
|
||||
public Coin getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -157,7 +156,7 @@ public class StoredTransactionOutput implements Serializable {
|
||||
}
|
||||
|
||||
public void serializeToStream(OutputStream bos) throws IOException {
|
||||
Utils.uint64ToByteStreamLE(value, bos);
|
||||
Utils.uint64ToByteStreamLE(value.toBigInteger(), bos);
|
||||
|
||||
bos.write(0xFF & scriptBytes.length >> 0);
|
||||
bos.write(0xFF & scriptBytes.length >> 8);
|
||||
|
@ -33,7 +33,6 @@ import org.spongycastle.crypto.params.KeyParameter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.text.ParseException;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.*;
|
||||
@ -87,14 +86,14 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
* If fee is lower than this value (in satoshis), a default reference client will treat it as if there were no fee.
|
||||
* Currently this is 10000 satoshis.
|
||||
*/
|
||||
public static final BigInteger REFERENCE_DEFAULT_MIN_TX_FEE = BigInteger.valueOf(10000);
|
||||
public static final Coin REFERENCE_DEFAULT_MIN_TX_FEE = Coin.valueOf(10000);
|
||||
|
||||
/**
|
||||
* Any standard (ie pay-to-address) output smaller than this value (in satoshis) will most likely be rejected by the network.
|
||||
* This is calculated by assuming a standard output will be 34 bytes, and then using the formula used in
|
||||
* {@link TransactionOutput#getMinNonDustValue(BigInteger)}. Currently it's 5460 satoshis.
|
||||
* {@link TransactionOutput#getMinNonDustValue(Coin)}. Currently it's 5460 satoshis.
|
||||
*/
|
||||
public static final BigInteger MIN_NONDUST_OUTPUT = BigInteger.valueOf(5460);
|
||||
public static final Coin MIN_NONDUST_OUTPUT = Coin.valueOf(5460);
|
||||
|
||||
// These are serialized in both bitcoin and java serialization.
|
||||
private long version;
|
||||
@ -237,10 +236,10 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
* Calculates the sum of the outputs that are sending coins to a key in the wallet. The flag controls whether to
|
||||
* include spent outputs or not.
|
||||
*/
|
||||
BigInteger getValueSentToMe(Wallet wallet, boolean includeSpent) {
|
||||
Coin getValueSentToMe(Wallet wallet, boolean includeSpent) {
|
||||
maybeParse();
|
||||
// This is tested in WalletTest.
|
||||
BigInteger v = BigInteger.ZERO;
|
||||
Coin v = Coin.ZERO;
|
||||
for (TransactionOutput o : outputs) {
|
||||
if (!o.isMineOrWatched(wallet)) continue;
|
||||
if (!includeSpent && !o.isAvailableForSpending()) continue;
|
||||
@ -275,7 +274,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
/**
|
||||
* Calculates the sum of the outputs that are sending coins to a key in the wallet.
|
||||
*/
|
||||
public BigInteger getValueSentToMe(Wallet wallet) {
|
||||
public Coin getValueSentToMe(Wallet wallet) {
|
||||
return getValueSentToMe(wallet, true);
|
||||
}
|
||||
|
||||
@ -347,10 +346,10 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
*
|
||||
* @return sum in nanocoins.
|
||||
*/
|
||||
public BigInteger getValueSentFromMe(Wallet wallet) throws ScriptException {
|
||||
public Coin getValueSentFromMe(Wallet wallet) throws ScriptException {
|
||||
maybeParse();
|
||||
// This is tested in WalletTest.
|
||||
BigInteger v = BigInteger.ZERO;
|
||||
Coin v = Coin.ZERO;
|
||||
for (TransactionInput input : inputs) {
|
||||
// This input is taking value from a transaction in our wallet. To discover the value,
|
||||
// we must find the connected transaction.
|
||||
@ -373,7 +372,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
/**
|
||||
* Returns the difference of {@link Transaction#getValueSentFromMe(Wallet)} and {@link Transaction#getValueSentToMe(Wallet)}.
|
||||
*/
|
||||
public BigInteger getValue(Wallet wallet) throws ScriptException {
|
||||
public Coin getValue(Wallet wallet) throws ScriptException {
|
||||
return getValueSentToMe(wallet).subtract(getValueSentFromMe(wallet));
|
||||
}
|
||||
|
||||
@ -383,8 +382,8 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
*
|
||||
* @return fee, or null if it cannot be determined
|
||||
*/
|
||||
public BigInteger getFee() {
|
||||
BigInteger fee = BigInteger.ZERO;
|
||||
public Coin getFee() {
|
||||
Coin fee = Coin.ZERO;
|
||||
for (TransactionInput input : inputs) {
|
||||
if (input.getValue() == null)
|
||||
return null;
|
||||
@ -807,7 +806,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
/**
|
||||
* Creates an output based on the given address and value, adds it to this transaction, and returns the new output.
|
||||
*/
|
||||
public TransactionOutput addOutput(BigInteger value, Address address) {
|
||||
public TransactionOutput addOutput(Coin value, Address address) {
|
||||
return addOutput(new TransactionOutput(params, this, value, address));
|
||||
}
|
||||
|
||||
@ -815,7 +814,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
* Creates an output that pays to the given pubkey directly (no address) with the given value, adds it to this
|
||||
* transaction, and returns the new output.
|
||||
*/
|
||||
public TransactionOutput addOutput(BigInteger value, ECKey pubkey) {
|
||||
public TransactionOutput addOutput(Coin value, ECKey pubkey) {
|
||||
return addOutput(new TransactionOutput(params, this, value, pubkey));
|
||||
}
|
||||
|
||||
@ -823,7 +822,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
* Creates an output that pays to the given script. The address and key forms are specialisations of this method,
|
||||
* you won't normally need to use it unless you're doing unusual things.
|
||||
*/
|
||||
public TransactionOutput addOutput(BigInteger value, Script script) {
|
||||
public TransactionOutput addOutput(Coin value, Script script) {
|
||||
return addOutput(new TransactionOutput(params, this, value, script.getProgram()));
|
||||
}
|
||||
|
||||
@ -1263,7 +1262,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
||||
if (this.getMessageSize() > Block.MAX_BLOCK_SIZE)
|
||||
throw new VerificationException("Transaction larger than MAX_BLOCK_SIZE");
|
||||
|
||||
BigInteger valueOut = BigInteger.ZERO;
|
||||
Coin valueOut = Coin.ZERO;
|
||||
for (TransactionOutput output : outputs) {
|
||||
if (output.getValue().signum() < 0)
|
||||
throw new VerificationException("Transaction output negative");
|
||||
|
@ -25,7 +25,6 @@ import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
@ -58,7 +57,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
transient private WeakReference<Script> scriptSig;
|
||||
/** Value of the output connected to the input, if known. This field does not participate in equals()/hashCode(). */
|
||||
@Nullable
|
||||
private final BigInteger value;
|
||||
private final Coin value;
|
||||
// A pointer to the transaction that owns this input.
|
||||
private final Transaction parentTransaction;
|
||||
|
||||
@ -75,7 +74,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
}
|
||||
|
||||
public TransactionInput(NetworkParameters params, @Nullable Transaction parentTransaction, byte[] scriptBytes,
|
||||
TransactionOutPoint outpoint, @Nullable BigInteger value) {
|
||||
TransactionOutPoint outpoint, @Nullable Coin value) {
|
||||
super(params);
|
||||
this.scriptBytes = scriptBytes;
|
||||
this.outpoint = outpoint;
|
||||
@ -267,7 +266,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
||||
* @return Value of the output connected to this input, if known. Null if unknown.
|
||||
*/
|
||||
@Nullable
|
||||
public BigInteger getValue() {
|
||||
public Coin getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
|
@ -18,16 +18,17 @@ package com.google.bitcoin.core;
|
||||
|
||||
import com.google.bitcoin.script.Script;
|
||||
import com.google.bitcoin.script.ScriptBuilder;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.io.Serializable;
|
||||
import java.lang.ref.WeakReference;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
@ -42,7 +43,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
|
||||
// A transaction output has some value and a script used for authenticating that the redeemer is allowed to spend
|
||||
// this output.
|
||||
private BigInteger value;
|
||||
private Coin value;
|
||||
private byte[] scriptBytes;
|
||||
|
||||
// The script bytes are parsed and turned into a Script on demand.
|
||||
@ -91,22 +92,22 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
/**
|
||||
* Creates an output that sends 'value' to the given address (public key hash). The amount should be created with
|
||||
* something like {@link Utils#toNanoCoins(int, int)}. Typically you would use
|
||||
* {@link Transaction#addOutput(java.math.BigInteger, Address)} instead of creating a TransactionOutput directly.
|
||||
* {@link Transaction#addOutput(java.math.Coin, Address)} instead of creating a TransactionOutput directly.
|
||||
*/
|
||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, BigInteger value, Address to) {
|
||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, Coin value, Address to) {
|
||||
this(params, parent, value, ScriptBuilder.createOutputScript(to).getProgram());
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an output that sends 'value' to the given public key using a simple CHECKSIG script (no addresses). The
|
||||
* amount should be created with something like {@link Utils#toNanoCoins(int, int)}. Typically you would use
|
||||
* {@link Transaction#addOutput(java.math.BigInteger, ECKey)} instead of creating an output directly.
|
||||
* {@link Transaction#addOutput(java.math.Coin, ECKey)} instead of creating an output directly.
|
||||
*/
|
||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, BigInteger value, ECKey to) {
|
||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, Coin value, ECKey to) {
|
||||
this(params, parent, value, ScriptBuilder.createOutputScript(to).getProgram());
|
||||
}
|
||||
|
||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, BigInteger value, byte[] scriptBytes) {
|
||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, Coin 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.
|
||||
@ -134,11 +135,11 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
}
|
||||
|
||||
protected void parseLite() throws ProtocolException {
|
||||
// TODO: There is no reason to use BigInteger for values, they are always smaller than 21 million * COIN
|
||||
// The only reason to use BigInteger would be to properly read values from the reference implementation, however
|
||||
// TODO: There is no reason to use Coin for values, they are always smaller than 21 million * COIN
|
||||
// The only reason to use Coin would be to properly read values from the reference implementation, however
|
||||
// the reference implementation uses signed 64-bit integers for its values as well (though it probably shouldn't)
|
||||
long outputValue = readInt64();
|
||||
value = BigInteger.valueOf(outputValue);
|
||||
value = Coin.valueOf(outputValue);
|
||||
scriptLen = (int) readVarInt();
|
||||
length = cursor - offset + scriptLen;
|
||||
}
|
||||
@ -160,7 +161,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
* Returns the value of this output in nanocoins. This is the amount of currency that the destination address
|
||||
* receives.
|
||||
*/
|
||||
public BigInteger getValue() {
|
||||
public Coin getValue() {
|
||||
maybeParse();
|
||||
return value;
|
||||
}
|
||||
@ -168,7 +169,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
/**
|
||||
* Sets the value of this output in nanocoins.
|
||||
*/
|
||||
public void setValue(BigInteger value) {
|
||||
public void setValue(Coin value) {
|
||||
checkNotNull(value);
|
||||
unCache();
|
||||
this.value = value;
|
||||
@ -197,15 +198,15 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
* @param feePerKbRequired The fee required per kilobyte. Note that this is the same as the reference client's -minrelaytxfee * 3
|
||||
* If you want a safe default, use {@link Transaction#REFERENCE_DEFAULT_MIN_TX_FEE}*3
|
||||
*/
|
||||
public BigInteger getMinNonDustValue(BigInteger feePerKbRequired) {
|
||||
public Coin getMinNonDustValue(Coin feePerKbRequired) {
|
||||
// A typical output is 33 bytes (pubkey hash + opcodes) and requires an input of 148 bytes to spend so we add
|
||||
// that together to find out the total amount of data used to transfer this amount of value. Note that this
|
||||
// formula is wrong for anything that's not a pay-to-address output, unfortunately, we must follow the reference
|
||||
// clients wrongness in order to ensure we're considered standard. A better formula would either estimate the
|
||||
// size of data needed to satisfy all different script types, or just hard code 33 below.
|
||||
final BigInteger size = BigInteger.valueOf(this.bitcoinSerialize().length + 148);
|
||||
BigInteger[] nonDustAndRemainder = feePerKbRequired.multiply(size).divideAndRemainder(BigInteger.valueOf(1000));
|
||||
return nonDustAndRemainder[1].equals(BigInteger.ZERO) ? nonDustAndRemainder[0] : nonDustAndRemainder[0].add(BigInteger.ONE);
|
||||
final long size = this.bitcoinSerialize().length + 148;
|
||||
Coin[] nonDustAndRemainder = feePerKbRequired.multiply(size).divideAndRemainder(Coin.valueOf(1000));
|
||||
return nonDustAndRemainder[1].equals(Coin.ZERO) ? nonDustAndRemainder[0] : nonDustAndRemainder[0].add(Coin.ONE);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -213,8 +214,8 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
||||
* and mined by default miners. For normal pay to address outputs, this is 5460 satoshis, the same as
|
||||
* {@link Transaction#MIN_NONDUST_OUTPUT}.
|
||||
*/
|
||||
public BigInteger getMinNonDustValue() {
|
||||
return getMinNonDustValue(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(3)));
|
||||
public Coin getMinNonDustValue() {
|
||||
return getMinNonDustValue(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(3)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,7 +45,7 @@ import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterrup
|
||||
* 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);
|
||||
public static final Coin NEGATIVE_ONE = Coin.valueOf(-1);
|
||||
private static final MessageDigest digest;
|
||||
static {
|
||||
try {
|
||||
@ -68,7 +68,7 @@ public class Utils {
|
||||
* The term nanocoin is very misleading, though, because there are only 100 million
|
||||
* of them in a coin (whereas one would expect 1 billion.
|
||||
*/
|
||||
public static final BigInteger COIN = new BigInteger("100000000", 10);
|
||||
public static final Coin COIN = new Coin("100000000", 10);
|
||||
|
||||
/**
|
||||
* How many "nanocoins" there are in 0.01 BitCoins.
|
||||
@ -77,19 +77,19 @@ public class Utils {
|
||||
* The term nanocoin is very misleading, though, because there are only 100 million
|
||||
* of them in a coin (whereas one would expect 1 billion).
|
||||
*/
|
||||
public static final BigInteger CENT = new BigInteger("1000000", 10);
|
||||
public static final Coin CENT = new Coin("1000000", 10);
|
||||
private static BlockingQueue<Boolean> mockSleepQueue;
|
||||
|
||||
/**
|
||||
* Convert an amount expressed in the way humans are used to into nanocoins.
|
||||
*/
|
||||
public static BigInteger toNanoCoins(int coins, int cents) {
|
||||
public static Coin toNanoCoins(int coins, int cents) {
|
||||
checkArgument(cents < 100);
|
||||
checkArgument(cents >= 0);
|
||||
checkArgument(coins >= 0);
|
||||
checkArgument(coins < NetworkParameters.MAX_MONEY.divide(Utils.COIN).longValue());
|
||||
BigInteger bi = BigInteger.valueOf(coins).multiply(COIN);
|
||||
bi = bi.add(BigInteger.valueOf(cents).multiply(CENT));
|
||||
Coin bi = Coin.valueOf(coins).multiply(COIN);
|
||||
bi = bi.add(Coin.valueOf(cents).multiply(CENT));
|
||||
return bi;
|
||||
}
|
||||
|
||||
@ -121,12 +121,12 @@ public class Utils {
|
||||
*
|
||||
* @throws ArithmeticException if you try to specify fractional nanocoins, or nanocoins out of range.
|
||||
*/
|
||||
public static BigInteger toNanoCoins(String coins) {
|
||||
BigInteger bigint = new BigDecimal(coins).movePointRight(8).toBigIntegerExact();
|
||||
public static Coin toNanoCoins(String coins) {
|
||||
Coin bigint = new Coin(new BigDecimal(coins).movePointRight(8).toBigIntegerExact());
|
||||
if (bigint.signum() < 0)
|
||||
throw new ArithmeticException("Negative coins specified");
|
||||
if (bigint.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
||||
throw new ArithmeticException("Amount larger than the total quantity of Bitcoins possible specified.");
|
||||
throw new ArithmeticException("Coin larger than the total quantity of Bitcoins possible specified.");
|
||||
return bigint;
|
||||
}
|
||||
|
||||
@ -332,12 +332,12 @@ public class Utils {
|
||||
* Returns the given value in nanocoins as a 0.12 type string. More digits after the decimal place will be used
|
||||
* if necessary, but two will always be present.
|
||||
*/
|
||||
public static String bitcoinValueToFriendlyString(BigInteger value) {
|
||||
public static String bitcoinValueToFriendlyString(Coin value) {
|
||||
// TODO: This API is crap. This method should go away when we encapsulate money values.
|
||||
boolean negative = value.signum() < 0;
|
||||
if (negative)
|
||||
value = value.negate();
|
||||
BigDecimal bd = new BigDecimal(value, 8);
|
||||
BigDecimal bd = new BigDecimal(value.toBigInteger(), 8);
|
||||
String formatted = bd.toPlainString(); // Don't use scientific notation.
|
||||
int decimalPoint = formatted.indexOf(".");
|
||||
// Drop unnecessary zeros from the end.
|
||||
@ -355,19 +355,19 @@ public class Utils {
|
||||
* <p>
|
||||
* Returns the given value as a plain string denominated in BTC.
|
||||
* The result is unformatted with no trailing zeroes.
|
||||
* For instance, an input value of BigInteger.valueOf(150000) nanocoin gives an output string of "0.0015" BTC
|
||||
* For instance, an input value of Coin.valueOf(150000) nanocoin gives an output string of "0.0015" BTC
|
||||
* </p>
|
||||
*
|
||||
* @param value The value in nanocoins to convert to a string (denominated in BTC)
|
||||
* @throws IllegalArgumentException
|
||||
* If the input value is null
|
||||
*/
|
||||
public static String bitcoinValueToPlainString(BigInteger value) {
|
||||
public static String bitcoinValueToPlainString(Coin value) {
|
||||
if (value == null) {
|
||||
throw new IllegalArgumentException("Value cannot be null");
|
||||
}
|
||||
|
||||
BigDecimal valueInBTC = new BigDecimal(value).divide(new BigDecimal(Utils.COIN));
|
||||
BigDecimal valueInBTC = new BigDecimal(value.toBigInteger()).divide(new BigDecimal(Utils.COIN.toBigInteger()));
|
||||
return valueInBTC.toPlainString();
|
||||
}
|
||||
|
||||
|
@ -1094,8 +1094,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
log.warn("There are now {} risk dropped transactions being kept in memory", riskDropped.size());
|
||||
return;
|
||||
}
|
||||
BigInteger valueSentToMe = tx.getValueSentToMe(this);
|
||||
BigInteger valueSentFromMe = tx.getValueSentFromMe(this);
|
||||
Coin valueSentToMe = tx.getValueSentToMe(this);
|
||||
Coin valueSentFromMe = tx.getValueSentFromMe(this);
|
||||
if (log.isInfoEnabled()) {
|
||||
log.info(String.format("Received a pending transaction %s that spends %s BTC from our own wallet," +
|
||||
" and sends us %s BTC", tx.getHashAsString(), Utils.bitcoinValueToFriendlyString(valueSentFromMe),
|
||||
@ -1272,14 +1272,14 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
int relativityOffset) throws VerificationException {
|
||||
// Runs in a peer thread.
|
||||
checkState(lock.isHeldByCurrentThread());
|
||||
BigInteger prevBalance = getBalance();
|
||||
Coin prevBalance = getBalance();
|
||||
Sha256Hash txHash = tx.getHash();
|
||||
boolean bestChain = blockType == BlockChain.NewBlockType.BEST_CHAIN;
|
||||
boolean sideChain = blockType == BlockChain.NewBlockType.SIDE_CHAIN;
|
||||
|
||||
BigInteger valueSentFromMe = tx.getValueSentFromMe(this);
|
||||
BigInteger valueSentToMe = tx.getValueSentToMe(this);
|
||||
BigInteger valueDifference = valueSentToMe.subtract(valueSentFromMe);
|
||||
Coin valueSentFromMe = tx.getValueSentFromMe(this);
|
||||
Coin valueSentToMe = tx.getValueSentToMe(this);
|
||||
Coin valueDifference = valueSentToMe.subtract(valueSentFromMe);
|
||||
|
||||
log.info("Received tx{} for {} BTC: {} [{}] in block {}", sideChain ? " on a side chain" : "",
|
||||
bitcoinValueToFriendlyString(valueDifference), tx.getHashAsString(), relativityOffset,
|
||||
@ -1364,7 +1364,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
// own spends. If users want to know when a broadcast tx becomes confirmed, they need to use tx confidence
|
||||
// listeners.
|
||||
if (!insideReorg && bestChain) {
|
||||
BigInteger newBalance = getBalance(); // This is slow.
|
||||
Coin newBalance = getBalance(); // This is slow.
|
||||
log.info("Balance is now: " + bitcoinValueToFriendlyString(newBalance));
|
||||
if (!wasPending) {
|
||||
int diff = valueDifference.signum();
|
||||
@ -1694,7 +1694,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
if (pending.containsKey(tx.getHash()))
|
||||
return false;
|
||||
log.info("commitTx of {}", tx.getHashAsString());
|
||||
BigInteger balance = getBalance();
|
||||
Coin balance = getBalance();
|
||||
tx.setUpdateTime(Utils.now());
|
||||
// Mark the outputs we're spending as spent so we won't try and use them in future creations. This will also
|
||||
// move any transactions that are now fully spent to the spent map so we can skip them when creating future
|
||||
@ -1708,9 +1708,9 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
addWalletTransaction(Pool.PENDING, tx);
|
||||
|
||||
try {
|
||||
BigInteger valueSentFromMe = tx.getValueSentFromMe(this);
|
||||
BigInteger valueSentToMe = tx.getValueSentToMe(this);
|
||||
BigInteger newBalance = balance.add(valueSentToMe).subtract(valueSentFromMe);
|
||||
Coin valueSentFromMe = tx.getValueSentFromMe(this);
|
||||
Coin valueSentToMe = tx.getValueSentToMe(this);
|
||||
Coin newBalance = balance.add(valueSentToMe).subtract(valueSentFromMe);
|
||||
if (valueSentToMe.signum() > 0) {
|
||||
checkBalanceFuturesLocked(null);
|
||||
queueOnCoinsReceived(tx, balance, newBalance);
|
||||
@ -2015,7 +2015,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* fees) - the wallet will calculate all that for you and update tx later.</p>
|
||||
*
|
||||
* <p>Be careful when adding outputs that you check the min output value
|
||||
* ({@link TransactionOutput#getMinNonDustValue(BigInteger)}) to avoid the whole transaction being rejected
|
||||
* ({@link TransactionOutput#getMinNonDustValue(Coin)}) to avoid the whole transaction being rejected
|
||||
* because one output is dust.</p>
|
||||
*
|
||||
* <p>If there are already inputs to the transaction, make sure their out point has a connected output,
|
||||
@ -2056,7 +2056,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* <p>You might also consider adding a {@link SendRequest#feePerKb} to set the fee per kb of transaction size
|
||||
* (rounded down to the nearest kb) as that is how transactions are sorted when added to a block by miners.</p>
|
||||
*/
|
||||
public BigInteger fee = null;
|
||||
public Coin fee = null;
|
||||
|
||||
/**
|
||||
* <p>A transaction can have a fee attached, which is defined as the difference between the input values
|
||||
@ -2072,13 +2072,13 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
*
|
||||
* <p>You might also consider using a {@link SendRequest#fee} to set the fee added for the first kb of size.</p>
|
||||
*/
|
||||
public BigInteger feePerKb = DEFAULT_FEE_PER_KB;
|
||||
public Coin feePerKb = DEFAULT_FEE_PER_KB;
|
||||
|
||||
/**
|
||||
* If you want to modify the default fee for your entire app without having to change each SendRequest you make,
|
||||
* you can do it here. This is primarily useful for unit tests.
|
||||
*/
|
||||
public static BigInteger DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
public static Coin DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
|
||||
/**
|
||||
* <p>Requires that there be enough fee for a default reference client to at least relay the transaction.
|
||||
@ -2123,7 +2123,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* <p>Be very careful when value is smaller than {@link Transaction#MIN_NONDUST_OUTPUT} as the transaction will
|
||||
* likely be rejected by the network in this case.</p>
|
||||
*/
|
||||
public static SendRequest to(Address destination, BigInteger value) {
|
||||
public static SendRequest to(Address destination, Coin value) {
|
||||
SendRequest req = new SendRequest();
|
||||
final NetworkParameters parameters = destination.getParameters();
|
||||
checkNotNull(parameters, "Address is for an unknown network");
|
||||
@ -2136,11 +2136,11 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* <p>Creates a new SendRequest to the given pubkey for the given value.</p>
|
||||
*
|
||||
* <p>Be careful to check the output's value is reasonable using
|
||||
* {@link TransactionOutput#getMinNonDustValue(BigInteger)} afterwards or you risk having the transaction
|
||||
* rejected by the network. Note that using {@link SendRequest#to(Address, java.math.BigInteger)} will result
|
||||
* {@link TransactionOutput#getMinNonDustValue(Coin)} afterwards or you risk having the transaction
|
||||
* rejected by the network. Note that using {@link SendRequest#to(Address, java.math.Coin)} will result
|
||||
* in a smaller output, and thus the ability to use a smaller output value without rejection.</p>
|
||||
*/
|
||||
public static SendRequest to(NetworkParameters params, ECKey destination, BigInteger value) {
|
||||
public static SendRequest to(NetworkParameters params, ECKey destination, Coin value) {
|
||||
SendRequest req = new SendRequest();
|
||||
req.tx = new Transaction(params);
|
||||
req.tx.addOutput(value, destination);
|
||||
@ -2159,7 +2159,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
final NetworkParameters parameters = destination.getParameters();
|
||||
checkNotNull(parameters, "Address is for an unknown network");
|
||||
req.tx = new Transaction(parameters);
|
||||
req.tx.addOutput(BigInteger.ZERO, destination);
|
||||
req.tx.addOutput(Coin.ZERO, destination);
|
||||
req.emptyWallet = true;
|
||||
return req;
|
||||
}
|
||||
@ -2170,11 +2170,11 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* {@link Wallet#getChangeAddress()}, so you must have added at least one key.</p>
|
||||
*
|
||||
* <p>If you just want to send money quickly, you probably want
|
||||
* {@link Wallet#sendCoins(TransactionBroadcaster, Address, java.math.BigInteger)} instead. That will create the sending
|
||||
* {@link Wallet#sendCoins(TransactionBroadcaster, Address, java.math.Coin)} instead. That will create the sending
|
||||
* transaction, commit to the wallet and broadcast it to the network all in one go. This method is lower level
|
||||
* and lets you see the proposed transaction before anything is done with it.</p>
|
||||
*
|
||||
* <p>This is a helper method that is equivalent to using {@link Wallet.SendRequest#to(Address, java.math.BigInteger)}
|
||||
* <p>This is a helper method that is equivalent to using {@link Wallet.SendRequest#to(Address, java.math.Coin)}
|
||||
* followed by {@link Wallet#completeTx(Wallet.SendRequest)} and returning the requests transaction object.
|
||||
* Note that this means a fee may be automatically added if required, if you want more control over the process,
|
||||
* just do those two steps yourself.</p>
|
||||
@ -2193,7 +2193,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* coins as spent until commitTx is called on the result.
|
||||
* @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
|
||||
*/
|
||||
public Transaction createSend(Address address, BigInteger nanocoins) throws InsufficientMoneyException {
|
||||
public Transaction createSend(Address address, Coin nanocoins) throws InsufficientMoneyException {
|
||||
SendRequest req = SendRequest.to(address, nanocoins);
|
||||
if (params == UnitTestParams.get())
|
||||
req.shuffleOutputs = false;
|
||||
@ -2243,7 +2243,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* @return An object containing the transaction that was created, and a future for the broadcast of it.
|
||||
* @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
|
||||
*/
|
||||
public SendResult sendCoins(TransactionBroadcaster broadcaster, Address to, BigInteger value) throws InsufficientMoneyException {
|
||||
public SendResult sendCoins(TransactionBroadcaster broadcaster, Address to, Coin value) throws InsufficientMoneyException {
|
||||
SendRequest request = SendRequest.to(to, value);
|
||||
return sendCoins(broadcaster, request);
|
||||
}
|
||||
@ -2335,17 +2335,17 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
try {
|
||||
checkArgument(!req.completed, "Given SendRequest has already been completed.");
|
||||
// Calculate the amount of value we need to import.
|
||||
BigInteger value = BigInteger.ZERO;
|
||||
Coin value = Coin.ZERO;
|
||||
for (TransactionOutput output : req.tx.getOutputs()) {
|
||||
value = value.add(output.getValue());
|
||||
}
|
||||
BigInteger totalOutput = value;
|
||||
Coin totalOutput = value;
|
||||
|
||||
log.info("Completing send tx with {} outputs totalling {} satoshis (not including fees)",
|
||||
req.tx.getOutputs().size(), value);
|
||||
|
||||
// If any inputs have already been added, we don't need to get their value from wallet
|
||||
BigInteger totalInput = BigInteger.ZERO;
|
||||
Coin totalInput = Coin.ZERO;
|
||||
for (TransactionInput input : req.tx.getInputs())
|
||||
if (input.getConnectedOutput() != null)
|
||||
totalInput = totalInput.add(input.getConnectedOutput().getValue());
|
||||
@ -2397,8 +2397,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
req.tx.addInput(output);
|
||||
|
||||
if (req.ensureMinRequiredFee && req.emptyWallet) {
|
||||
final BigInteger baseFee = req.fee == null ? BigInteger.ZERO : req.fee;
|
||||
final BigInteger feePerKb = req.feePerKb == null ? BigInteger.ZERO : req.feePerKb;
|
||||
final Coin baseFee = req.fee == null ? Coin.ZERO : req.fee;
|
||||
final Coin feePerKb = req.feePerKb == null ? Coin.ZERO : req.feePerKb;
|
||||
Transaction tx = req.tx;
|
||||
if (!adjustOutputDownwardsForFee(tx, bestCoinSelection, baseFee, feePerKb))
|
||||
throw new CouldNotAdjustDownwards();
|
||||
@ -2411,7 +2411,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
totalOutput = totalOutput.add(bestChangeOutput.getValue());
|
||||
log.info(" with {} coins change", bitcoinValueToFriendlyString(bestChangeOutput.getValue()));
|
||||
}
|
||||
final BigInteger calculatedFee = totalInput.subtract(totalOutput);
|
||||
final Coin calculatedFee = totalInput.subtract(totalOutput);
|
||||
if (calculatedFee.signum() > 0) {
|
||||
log.info(" with a fee of {}", bitcoinValueToFriendlyString(calculatedFee));
|
||||
}
|
||||
@ -2445,12 +2445,12 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
}
|
||||
|
||||
/** Reduce the value of the first output of a transaction to pay the given feePerKb as appropriate for its size. */
|
||||
private boolean adjustOutputDownwardsForFee(Transaction tx, CoinSelection coinSelection, BigInteger baseFee, BigInteger feePerKb) {
|
||||
private boolean adjustOutputDownwardsForFee(Transaction tx, CoinSelection coinSelection, Coin baseFee, Coin feePerKb) {
|
||||
TransactionOutput output = tx.getOutput(0);
|
||||
// Check if we need additional fee due to the transaction's size
|
||||
int size = tx.bitcoinSerialize().length;
|
||||
size += estimateBytesForSigning(coinSelection);
|
||||
BigInteger fee = baseFee.add(BigInteger.valueOf((size / 1000) + 1).multiply(feePerKb));
|
||||
Coin fee = baseFee.add(Coin.valueOf((size / 1000) + 1).multiply(feePerKb));
|
||||
output.setValue(output.getValue().subtract(fee));
|
||||
// Check if we need additional fee due to the output's value
|
||||
if (output.getValue().compareTo(Utils.CENT) < 0 && fee.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0)
|
||||
@ -2538,21 +2538,21 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* Returns the AVAILABLE balance of this wallet. See {@link BalanceType#AVAILABLE} for details on what this
|
||||
* means.
|
||||
*/
|
||||
public BigInteger getBalance() {
|
||||
public Coin getBalance() {
|
||||
return getBalance(BalanceType.AVAILABLE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the balance of this wallet as calculated by the provided balanceType.
|
||||
*/
|
||||
public BigInteger getBalance(BalanceType balanceType) {
|
||||
public Coin getBalance(BalanceType balanceType) {
|
||||
lock.lock();
|
||||
try {
|
||||
if (balanceType == BalanceType.AVAILABLE) {
|
||||
return getBalance(coinSelector);
|
||||
} else if (balanceType == BalanceType.ESTIMATED) {
|
||||
LinkedList<TransactionOutput> all = calculateAllSpendCandidates(false);
|
||||
BigInteger value = BigInteger.ZERO;
|
||||
Coin value = Coin.ZERO;
|
||||
for (TransactionOutput out : all) value = value.add(out.getValue());
|
||||
return value;
|
||||
} else {
|
||||
@ -2567,7 +2567,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* Returns the balance that would be considered spendable by the given coin selector. Just asks it to select
|
||||
* as many coins as possible and returns the total.
|
||||
*/
|
||||
public BigInteger getBalance(CoinSelector selector) {
|
||||
public Coin getBalance(CoinSelector selector) {
|
||||
lock.lock();
|
||||
try {
|
||||
checkNotNull(selector);
|
||||
@ -2580,7 +2580,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
}
|
||||
|
||||
/** Returns the available balance, including any unspent balance at watched addresses */
|
||||
public BigInteger getWatchedBalance() {
|
||||
public Coin getWatchedBalance() {
|
||||
return getWatchedBalance(coinSelector);
|
||||
}
|
||||
|
||||
@ -2588,7 +2588,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* Returns the balance that would be considered spendable by the given coin selector, including
|
||||
* any unspent balance at watched addresses.
|
||||
*/
|
||||
public BigInteger getWatchedBalance(CoinSelector selector) {
|
||||
public Coin getWatchedBalance(CoinSelector selector) {
|
||||
lock.lock();
|
||||
try {
|
||||
checkNotNull(selector);
|
||||
@ -2619,8 +2619,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
lock.lock();
|
||||
try {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
BigInteger estimatedBalance = getBalance(BalanceType.ESTIMATED);
|
||||
BigInteger availableBalance = getBalance(BalanceType.AVAILABLE);
|
||||
Coin estimatedBalance = getBalance(BalanceType.ESTIMATED);
|
||||
Coin availableBalance = getBalance(BalanceType.AVAILABLE);
|
||||
builder.append(String.format("Wallet containing %s BTC (available: %s BTC) in:%n",
|
||||
bitcoinValueToPlainString(estimatedBalance), bitcoinValueToPlainString(availableBalance)));
|
||||
builder.append(String.format(" %d pending transactions%n", pending.size()));
|
||||
@ -2861,7 +2861,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
notifyNewBestBlock(block);
|
||||
}
|
||||
checkState(isConsistent());
|
||||
final BigInteger balance = getBalance();
|
||||
final Coin balance = getBalance();
|
||||
log.info("post-reorg balance is {}", Utils.bitcoinValueToFriendlyString(balance));
|
||||
// Inform event listeners that a re-org took place.
|
||||
queueOnReorganize();
|
||||
@ -3307,8 +3307,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
}
|
||||
|
||||
private static class BalanceFutureRequest {
|
||||
public SettableFuture<BigInteger> future;
|
||||
public BigInteger value;
|
||||
public SettableFuture<Coin> future;
|
||||
public Coin value;
|
||||
public BalanceType type;
|
||||
}
|
||||
@GuardedBy("lock") private List<BalanceFutureRequest> balanceFutureRequests = Lists.newLinkedList();
|
||||
@ -3327,11 +3327,11 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
* you can use {@link com.google.bitcoin.utils.Threading#waitForUserCode()} to block until the future had a
|
||||
* chance to be updated.</p>
|
||||
*/
|
||||
public ListenableFuture<BigInteger> getBalanceFuture(final BigInteger value, final BalanceType type) {
|
||||
public ListenableFuture<Coin> getBalanceFuture(final Coin value, final BalanceType type) {
|
||||
lock.lock();
|
||||
try {
|
||||
final SettableFuture<BigInteger> future = SettableFuture.create();
|
||||
final BigInteger current = getBalance(type);
|
||||
final SettableFuture<Coin> future = SettableFuture.create();
|
||||
final Coin current = getBalance(type);
|
||||
if (current.compareTo(value) >= 0) {
|
||||
// Already have enough.
|
||||
future.set(current);
|
||||
@ -3352,13 +3352,13 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
}
|
||||
|
||||
// Runs any balance futures in the user code thread.
|
||||
private void checkBalanceFuturesLocked(@Nullable BigInteger avail) {
|
||||
private void checkBalanceFuturesLocked(@Nullable Coin avail) {
|
||||
checkState(lock.isHeldByCurrentThread());
|
||||
BigInteger estimated = null;
|
||||
Coin estimated = null;
|
||||
final ListIterator<BalanceFutureRequest> it = balanceFutureRequests.listIterator();
|
||||
while (it.hasNext()) {
|
||||
final BalanceFutureRequest req = it.next();
|
||||
BigInteger val = null;
|
||||
Coin val = null;
|
||||
if (req.type == BalanceType.AVAILABLE) {
|
||||
if (avail == null) avail = getBalance(BalanceType.AVAILABLE);
|
||||
if (avail.compareTo(req.value) < 0) continue;
|
||||
@ -3370,7 +3370,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
}
|
||||
// Found one that's finished.
|
||||
it.remove();
|
||||
final BigInteger v = checkNotNull(val);
|
||||
final Coin v = checkNotNull(val);
|
||||
// Don't run any user-provided future listeners with our lock held.
|
||||
Threading.USER_THREAD.execute(new Runnable() {
|
||||
@Override public void run() {
|
||||
@ -3483,7 +3483,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
}
|
||||
}
|
||||
|
||||
private void queueOnCoinsReceived(final Transaction tx, final BigInteger balance, final BigInteger newBalance) {
|
||||
private void queueOnCoinsReceived(final Transaction tx, final Coin balance, final Coin newBalance) {
|
||||
checkState(lock.isHeldByCurrentThread());
|
||||
for (final ListenerRegistration<WalletEventListener> registration : eventListeners) {
|
||||
registration.executor.execute(new Runnable() {
|
||||
@ -3495,7 +3495,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
}
|
||||
}
|
||||
|
||||
private void queueOnCoinsSent(final Transaction tx, final BigInteger prevBalance, final BigInteger newBalance) {
|
||||
private void queueOnCoinsSent(final Transaction tx, final Coin prevBalance, final Coin newBalance) {
|
||||
checkState(lock.isHeldByCurrentThread());
|
||||
for (final ListenerRegistration<WalletEventListener> registration : eventListeners) {
|
||||
registration.executor.execute(new Runnable() {
|
||||
@ -3540,7 +3540,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
private CoinSelection bestCoinSelection;
|
||||
private TransactionOutput bestChangeOutput;
|
||||
|
||||
public FeeCalculation(SendRequest req, BigInteger value, List<TransactionInput> originalInputs,
|
||||
public FeeCalculation(SendRequest req, Coin value, List<TransactionInput> originalInputs,
|
||||
boolean needAtLeastReferenceFee, LinkedList<TransactionOutput> candidates) throws InsufficientMoneyException {
|
||||
checkState(lock.isHeldByCurrentThread());
|
||||
// There are 3 possibilities for what adding change might do:
|
||||
@ -3550,7 +3550,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
// If we get either of the last 2, we keep note of what the inputs looked like at the time and try to
|
||||
// add inputs as we go up the list (keeping track of minimum inputs for each category). At the end, we pick
|
||||
// the best input set as the one which generates the lowest total fee.
|
||||
BigInteger additionalValueForNextCategory = null;
|
||||
Coin additionalValueForNextCategory = null;
|
||||
CoinSelection selection3 = null;
|
||||
CoinSelection selection2 = null;
|
||||
TransactionOutput selection2Change = null;
|
||||
@ -3559,14 +3559,14 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
// We keep track of the last size of the transaction we calculated but only if the act of adding inputs and
|
||||
// change resulted in the size crossing a 1000 byte boundary. Otherwise it stays at zero.
|
||||
int lastCalculatedSize = 0;
|
||||
BigInteger valueNeeded, valueMissing = null;
|
||||
Coin valueNeeded, valueMissing = null;
|
||||
while (true) {
|
||||
resetTxInputs(req, originalInputs);
|
||||
|
||||
BigInteger fees = req.fee == null ? BigInteger.ZERO : req.fee;
|
||||
Coin fees = req.fee == null ? Coin.ZERO : req.fee;
|
||||
if (lastCalculatedSize > 0) {
|
||||
// If the size is exactly 1000 bytes then we'll over-pay, but this should be rare.
|
||||
fees = fees.add(BigInteger.valueOf((lastCalculatedSize / 1000) + 1).multiply(req.feePerKb));
|
||||
fees = fees.add(Coin.valueOf((lastCalculatedSize / 1000) + 1).multiply(req.feePerKb));
|
||||
} else {
|
||||
fees = fees.add(req.feePerKb); // First time around the loop.
|
||||
}
|
||||
@ -3576,7 +3576,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
valueNeeded = value.add(fees);
|
||||
if (additionalValueForNextCategory != null)
|
||||
valueNeeded = valueNeeded.add(additionalValueForNextCategory);
|
||||
BigInteger additionalValueSelected = additionalValueForNextCategory;
|
||||
Coin additionalValueSelected = additionalValueForNextCategory;
|
||||
|
||||
// Of the coins we could spend, pick some that we actually will spend.
|
||||
CoinSelector selector = req.coinSelector == null ? coinSelector : req.coinSelector;
|
||||
@ -3598,12 +3598,12 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
boolean eitherCategory2Or3 = false;
|
||||
boolean isCategory3 = false;
|
||||
|
||||
BigInteger change = selection.valueGathered.subtract(valueNeeded);
|
||||
Coin change = selection.valueGathered.subtract(valueNeeded);
|
||||
if (additionalValueSelected != null)
|
||||
change = change.add(additionalValueSelected);
|
||||
|
||||
// If change is < 0.01 BTC, we will need to have at least minfee to be accepted by the network
|
||||
if (req.ensureMinRequiredFee && !change.equals(BigInteger.ZERO) &&
|
||||
if (req.ensureMinRequiredFee && !change.equals(Coin.ZERO) &&
|
||||
change.compareTo(Utils.CENT) < 0 && fees.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0) {
|
||||
// This solution may fit into category 2, but it may also be category 3, we'll check that later
|
||||
eitherCategory2Or3 = true;
|
||||
@ -3627,7 +3627,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
// This solution definitely fits in category 3
|
||||
isCategory3 = true;
|
||||
additionalValueForNextCategory = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(
|
||||
Transaction.MIN_NONDUST_OUTPUT.add(BigInteger.ONE));
|
||||
Transaction.MIN_NONDUST_OUTPUT.add(Coin.ONE));
|
||||
} else {
|
||||
size += changeOutput.bitcoinSerialize().length + VarInt.sizeOf(req.tx.getOutputs().size()) - VarInt.sizeOf(req.tx.getOutputs().size() - 1);
|
||||
// This solution is either category 1 or 2
|
||||
@ -3638,7 +3638,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
if (eitherCategory2Or3) {
|
||||
// This solution definitely fits in category 3 (we threw away change because it was smaller than MIN_TX_FEE)
|
||||
isCategory3 = true;
|
||||
additionalValueForNextCategory = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE);
|
||||
additionalValueForNextCategory = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3694,7 +3694,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
throw new InsufficientMoneyException(valueMissing);
|
||||
}
|
||||
|
||||
BigInteger lowestFee = null;
|
||||
Coin lowestFee = null;
|
||||
bestCoinSelection = null;
|
||||
bestChangeOutput = null;
|
||||
if (selection1 != null) {
|
||||
@ -3707,7 +3707,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
}
|
||||
|
||||
if (selection2 != null) {
|
||||
BigInteger fee = selection2.valueGathered.subtract(checkNotNull(selection2Change).getValue());
|
||||
Coin fee = selection2.valueGathered.subtract(checkNotNull(selection2Change).getValue());
|
||||
if (lowestFee == null || fee.compareTo(lowestFee) < 0) {
|
||||
lowestFee = fee;
|
||||
bestCoinSelection = selection2;
|
||||
@ -3896,14 +3896,14 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
||||
// bug that was fixed in 0.10, thus, making a re-key transaction depend on those would cause it to
|
||||
// never confirm at all.
|
||||
CoinSelector selector = new KeyTimeCoinSelector(this, keyRotationTimestamp, true);
|
||||
CoinSelection toMove = selector.select(BigInteger.ZERO, calculateAllSpendCandidates(true));
|
||||
if (toMove.valueGathered.equals(BigInteger.ZERO)) return null; // Nothing to do.
|
||||
CoinSelection toMove = selector.select(Coin.ZERO, calculateAllSpendCandidates(true));
|
||||
if (toMove.valueGathered.equals(Coin.ZERO)) return null; // Nothing to do.
|
||||
rekeyTx = new Transaction(params);
|
||||
for (TransactionOutput output : toMove.gathered) {
|
||||
rekeyTx.addInput(output);
|
||||
}
|
||||
rekeyTx.addOutput(toMove.valueGathered, safeKey);
|
||||
if (!adjustOutputDownwardsForFee(rekeyTx, toMove, BigInteger.ZERO, Transaction.REFERENCE_DEFAULT_MIN_TX_FEE)) {
|
||||
if (!adjustOutputDownwardsForFee(rekeyTx, toMove, Coin.ZERO, Transaction.REFERENCE_DEFAULT_MIN_TX_FEE)) {
|
||||
log.error("Failed to adjust rekey tx for fees.");
|
||||
return null;
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ package com.google.bitcoin.core;
|
||||
import com.google.bitcoin.script.Script;
|
||||
import com.google.bitcoin.wallet.KeyChainEventListener;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -40,7 +39,7 @@ public interface WalletEventListener extends KeyChainEventListener {
|
||||
* @param prevBalance Balance before the coins were received.
|
||||
* @param newBalance Current balance of the wallet. This is the 'estimated' balance.
|
||||
*/
|
||||
void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance);
|
||||
void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance);
|
||||
|
||||
/**
|
||||
* This is called when a transaction is seen that sends coins <b>from</b> this wallet, either
|
||||
@ -58,7 +57,7 @@ public interface WalletEventListener extends KeyChainEventListener {
|
||||
* @param prevBalance The wallets balance before this transaction was seen.
|
||||
* @param newBalance The wallets balance after this transaction was seen. This is the 'estimated' balance.
|
||||
*/
|
||||
void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance);
|
||||
void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance);
|
||||
|
||||
// TODO: Finish onReorganize to be more useful.
|
||||
/**
|
||||
|
@ -4,8 +4,6 @@ import com.google.bitcoin.core.*;
|
||||
import com.google.bitcoin.protocols.channels.PaymentChannelCloseException;
|
||||
import com.google.bitcoin.protocols.channels.ServerConnectionEventHandler;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* An event listener that relays events to a native C++ object. A pointer to that object is stored in
|
||||
* this class using JNI on the native side, thus several instances of this can point to different actual
|
||||
@ -18,7 +16,7 @@ public class NativePaymentChannelServerConnectionEventHandler extends ServerConn
|
||||
public native void channelOpen(Sha256Hash channelId);
|
||||
|
||||
@Override
|
||||
public native void paymentIncrease(BigInteger by, BigInteger to);
|
||||
public native void paymentIncrease(Coin by, Coin to);
|
||||
|
||||
@Override
|
||||
public native void channelClosed(PaymentChannelCloseException.CloseReason reason);
|
||||
|
@ -16,13 +16,13 @@
|
||||
|
||||
package com.google.bitcoin.jni;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.ECKey;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
import com.google.bitcoin.core.WalletEventListener;
|
||||
import com.google.bitcoin.script.Script;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -34,10 +34,10 @@ public class NativeWalletEventListener implements WalletEventListener {
|
||||
public long ptr;
|
||||
|
||||
@Override
|
||||
public native void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance);
|
||||
public native void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance);
|
||||
|
||||
@Override
|
||||
public native void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance);
|
||||
public native void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance);
|
||||
|
||||
@Override
|
||||
public native void onReorganize(Wallet wallet);
|
||||
|
@ -16,11 +16,11 @@
|
||||
|
||||
package com.google.bitcoin.protocols.channels;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.InsufficientMoneyException;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
/**
|
||||
* A class implementing this interface supports the basic operations of a payment channel. An implementation is provided
|
||||
@ -80,7 +80,7 @@ public interface IPaymentChannelClient {
|
||||
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
||||
* @return a future that completes when the server acknowledges receipt and acceptance of the payment.
|
||||
*/
|
||||
ListenableFuture<BigInteger> incrementPayment(BigInteger size) throws ValueOutOfRangeException, IllegalStateException;
|
||||
ListenableFuture<Coin> incrementPayment(Coin size) throws ValueOutOfRangeException, IllegalStateException;
|
||||
|
||||
/**
|
||||
* Implements the connection between this client and the server, providing an interface which allows messages to be
|
||||
@ -118,7 +118,7 @@ public interface IPaymentChannelClient {
|
||||
|
||||
/**
|
||||
* <p>Indicates the channel has been successfully opened and
|
||||
* {@link com.google.bitcoin.protocols.channels.PaymentChannelClient#incrementPayment(java.math.BigInteger)}
|
||||
* {@link com.google.bitcoin.protocols.channels.PaymentChannelClient#incrementPayment(java.math.Coin)}
|
||||
* may be called at will.</p>
|
||||
*
|
||||
* <p>Called while holding a lock on the {@link com.google.bitcoin.protocols.channels.PaymentChannelClient}
|
||||
|
@ -29,7 +29,6 @@ import org.bitcoin.paymentchannel.Protos;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -85,14 +84,14 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
|
||||
// Information used during channel initialization to send to the server or check what the server sends to us
|
||||
private final ECKey myKey;
|
||||
private final BigInteger maxValue;
|
||||
private final Coin maxValue;
|
||||
|
||||
private BigInteger missing;
|
||||
private Coin missing;
|
||||
|
||||
@GuardedBy("lock") private long minPayment;
|
||||
|
||||
@GuardedBy("lock") SettableFuture<BigInteger> increasePaymentFuture;
|
||||
@GuardedBy("lock") BigInteger lastPaymentActualAmount;
|
||||
@GuardedBy("lock") SettableFuture<Coin> increasePaymentFuture;
|
||||
@GuardedBy("lock") Coin lastPaymentActualAmount;
|
||||
|
||||
/**
|
||||
* <p>The maximum amount of time for which we will accept the server locking up our funds for the multisig
|
||||
@ -122,7 +121,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
* @param conn A callback listener which represents the connection to the server (forwards messages we generate to
|
||||
* the server)
|
||||
*/
|
||||
public PaymentChannelClient(Wallet wallet, ECKey myKey, BigInteger maxValue, Sha256Hash serverId, ClientConnection conn) {
|
||||
public PaymentChannelClient(Wallet wallet, ECKey myKey, Coin maxValue, Sha256Hash serverId, ClientConnection conn) {
|
||||
this.wallet = checkNotNull(wallet);
|
||||
this.myKey = checkNotNull(myKey);
|
||||
this.maxValue = checkNotNull(maxValue);
|
||||
@ -136,13 +135,13 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
* <p>When InsufficientMoneyException is thrown due to the server requesting too much value, an instance of
|
||||
* PaymentChannelClient needs access to how many satoshis are missing.</p>
|
||||
*/
|
||||
public BigInteger getMissing() {
|
||||
public Coin getMissing() {
|
||||
return missing;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@GuardedBy("lock")
|
||||
private CloseReason receiveInitiate(Protos.Initiate initiate, BigInteger contractValue, Protos.Error.Builder errorBuilder) throws VerificationException, InsufficientMoneyException {
|
||||
private CloseReason receiveInitiate(Protos.Initiate initiate, Coin contractValue, Protos.Error.Builder errorBuilder) throws VerificationException, InsufficientMoneyException {
|
||||
log.info("Got INITIATE message:\n{}", initiate.toString());
|
||||
|
||||
checkState(initiate.getExpireTimeSecs() > 0 && initiate.getMinAcceptedChannelSize() >= 0);
|
||||
@ -156,7 +155,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
return CloseReason.TIME_WINDOW_TOO_LARGE;
|
||||
}
|
||||
|
||||
BigInteger minChannelSize = BigInteger.valueOf(initiate.getMinAcceptedChannelSize());
|
||||
Coin minChannelSize = Coin.valueOf(initiate.getMinAcceptedChannelSize());
|
||||
if (contractValue.compareTo(minChannelSize) < 0) {
|
||||
log.error("Server requested too much value");
|
||||
errorBuilder.setCode(Protos.Error.ErrorCode.CHANNEL_VALUE_TOO_LARGE);
|
||||
@ -171,7 +170,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
log.error("Server requested a min payment of {} but we expected {}", initiate.getMinPayment(), MIN_PAYMENT);
|
||||
errorBuilder.setCode(Protos.Error.ErrorCode.MIN_PAYMENT_TOO_LARGE);
|
||||
errorBuilder.setExpectedValue(MIN_PAYMENT);
|
||||
missing = BigInteger.valueOf(initiate.getMinPayment() - MIN_PAYMENT);
|
||||
missing = Coin.valueOf(initiate.getMinPayment() - MIN_PAYMENT);
|
||||
return CloseReason.SERVER_REQUESTED_TOO_MUCH_VALUE;
|
||||
}
|
||||
|
||||
@ -218,7 +217,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
try {
|
||||
// Make an initial payment of the dust limit, and put it into the message as well. The size of the
|
||||
// server-requested dust limit was already sanity checked by this point.
|
||||
PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(BigInteger.valueOf(minPayment));
|
||||
PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(Coin.valueOf(minPayment));
|
||||
Protos.UpdatePayment.Builder initialMsg = contractMsg.getInitialPaymentBuilder();
|
||||
initialMsg.setSignature(ByteString.copyFrom(payment.signature.encodeToBitcoin()));
|
||||
initialMsg.setClientChangeValue(state.getValueRefunded().longValue());
|
||||
@ -470,7 +469,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
* @return a future that completes when the server acknowledges receipt and acceptance of the payment.
|
||||
*/
|
||||
@Override
|
||||
public ListenableFuture<BigInteger> incrementPayment(BigInteger size) throws ValueOutOfRangeException, IllegalStateException {
|
||||
public ListenableFuture<Coin> incrementPayment(Coin size) throws ValueOutOfRangeException, IllegalStateException {
|
||||
lock.lock();
|
||||
try {
|
||||
if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN)
|
||||
@ -505,8 +504,8 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
||||
}
|
||||
|
||||
private void receivePaymentAck() {
|
||||
SettableFuture<BigInteger> future;
|
||||
BigInteger value;
|
||||
SettableFuture<Coin> future;
|
||||
Coin value;
|
||||
|
||||
lock.lock();
|
||||
try {
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
package com.google.bitcoin.protocols.channels;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.ECKey;
|
||||
import com.google.bitcoin.core.InsufficientMoneyException;
|
||||
import com.google.bitcoin.core.Sha256Hash;
|
||||
@ -24,10 +25,10 @@ import com.google.bitcoin.net.NioClient;
|
||||
import com.google.bitcoin.net.ProtobufParser;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.google.common.util.concurrent.SettableFuture;
|
||||
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
|
||||
/**
|
||||
@ -60,7 +61,7 @@ public class PaymentChannelClientConnection {
|
||||
* @throws ValueOutOfRangeException if the balance of wallet is lower than maxValue.
|
||||
*/
|
||||
public PaymentChannelClientConnection(InetSocketAddress server, int timeoutSeconds, Wallet wallet, ECKey myKey,
|
||||
BigInteger maxValue, String serverId) throws IOException, ValueOutOfRangeException {
|
||||
Coin maxValue, String serverId) throws IOException, ValueOutOfRangeException {
|
||||
// Glue the object which vends/ingests protobuf messages in order to manage state to the network object which
|
||||
// reads/writes them to the wire in length prefixed form.
|
||||
channelClient = new PaymentChannelClient(wallet, myKey, maxValue, Sha256Hash.create(serverId.getBytes()),
|
||||
@ -119,7 +120,7 @@ public class PaymentChannelClientConnection {
|
||||
* an error before the channel has reached the open state.</p>
|
||||
*
|
||||
* <p>After this future completes successfully, you may call
|
||||
* {@link PaymentChannelClientConnection#incrementPayment(java.math.BigInteger)} to begin paying the server.</p>
|
||||
* {@link PaymentChannelClientConnection#incrementPayment(java.math.Coin)} to begin paying the server.</p>
|
||||
*/
|
||||
public ListenableFuture<PaymentChannelClientConnection> getChannelOpenFuture() {
|
||||
return channelOpenFuture;
|
||||
@ -134,7 +135,7 @@ public class PaymentChannelClientConnection {
|
||||
* @throws IllegalStateException If the channel has been closed or is not yet open
|
||||
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
||||
*/
|
||||
public ListenableFuture<BigInteger> incrementPayment(BigInteger size) throws ValueOutOfRangeException, IllegalStateException {
|
||||
public ListenableFuture<Coin> incrementPayment(Coin size) throws ValueOutOfRangeException, IllegalStateException {
|
||||
return channelClient.incrementPayment(size);
|
||||
}
|
||||
|
||||
|
@ -31,7 +31,6 @@ import com.google.common.util.concurrent.ListenableFuture;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
@ -75,20 +74,20 @@ public class PaymentChannelClientState {
|
||||
// and transactions that spend it.
|
||||
private final ECKey myKey, serverMultisigKey;
|
||||
// How much value (in satoshis) is locked up into the channel.
|
||||
private final BigInteger totalValue;
|
||||
private final Coin totalValue;
|
||||
// When the channel will automatically settle in favor of the client, if the server halts before protocol termination
|
||||
// specified in terms of block timestamps (so it can off real time by a few hours).
|
||||
private final long expiryTime;
|
||||
|
||||
// The refund is a time locked transaction that spends all the money of the channel back to the client.
|
||||
private Transaction refundTx;
|
||||
private BigInteger refundFees;
|
||||
private Coin refundFees;
|
||||
// The multi-sig contract locks the value of the channel up such that the agreement of both parties is required
|
||||
// to spend it.
|
||||
private Transaction multisigContract;
|
||||
private Script multisigScript;
|
||||
// How much value is currently allocated to us. Starts as being same as totalValue.
|
||||
private BigInteger valueToMe;
|
||||
private Coin valueToMe;
|
||||
|
||||
/**
|
||||
* The different logical states the channel can be in. The channel starts out as NEW, and then steps through the
|
||||
@ -156,7 +155,7 @@ public class PaymentChannelClientState {
|
||||
* @throws VerificationException If either myKey's pubkey or serverMultisigKey's pubkey are non-canonical (ie invalid)
|
||||
*/
|
||||
public PaymentChannelClientState(Wallet wallet, ECKey myKey, ECKey serverMultisigKey,
|
||||
BigInteger value, long expiryTimeInSeconds) throws VerificationException {
|
||||
Coin value, long expiryTimeInSeconds) throws VerificationException {
|
||||
checkArgument(value.signum() > 0);
|
||||
this.wallet = checkNotNull(wallet);
|
||||
initWalletListeners();
|
||||
@ -174,7 +173,7 @@ public class PaymentChannelClientState {
|
||||
}
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
synchronized (PaymentChannelClientState.this) {
|
||||
if (multisigContract == null) return;
|
||||
if (isSettlementTransaction(tx)) {
|
||||
@ -253,7 +252,7 @@ public class PaymentChannelClientState {
|
||||
editContractSendRequest(req);
|
||||
req.shuffleOutputs = false; // TODO: Fix things so shuffling is usable.
|
||||
wallet.completeTx(req);
|
||||
BigInteger multisigFee = req.fee;
|
||||
Coin multisigFee = req.fee;
|
||||
multisigContract = req.tx;
|
||||
// Build a refund transaction that protects us in the case of a bad server that's just trying to cause havoc
|
||||
// by locking up peoples money (perhaps as a precursor to a ransom attempt). We time lock it so the server
|
||||
@ -266,7 +265,7 @@ public class PaymentChannelClientState {
|
||||
refundTx.setLockTime(expiryTime);
|
||||
if (totalValue.compareTo(Utils.CENT) < 0) {
|
||||
// Must pay min fee.
|
||||
final BigInteger valueAfterFee = totalValue.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
||||
final Coin valueAfterFee = totalValue.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
||||
if (Transaction.MIN_NONDUST_OUTPUT.compareTo(valueAfterFee) > 0)
|
||||
throw new ValueOutOfRangeException("totalValue too small to use");
|
||||
refundTx.addOutput(valueAfterFee, myKey.toAddress(params));
|
||||
@ -292,7 +291,7 @@ public class PaymentChannelClientState {
|
||||
|
||||
/**
|
||||
* Returns the transaction that locks the money to the agreement of both parties. Do not mutate the result.
|
||||
* Once this step is done, you can use {@link PaymentChannelClientState#incrementPaymentBy(java.math.BigInteger)} to
|
||||
* Once this step is done, you can use {@link PaymentChannelClientState#incrementPaymentBy(java.math.Coin)} to
|
||||
* start paying the server.
|
||||
*/
|
||||
public synchronized Transaction getMultisigContract() {
|
||||
@ -348,7 +347,7 @@ public class PaymentChannelClientState {
|
||||
state = State.SAVE_STATE_IN_WALLET;
|
||||
}
|
||||
|
||||
private synchronized Transaction makeUnsignedChannelContract(BigInteger valueToMe) throws ValueOutOfRangeException {
|
||||
private synchronized Transaction makeUnsignedChannelContract(Coin valueToMe) throws ValueOutOfRangeException {
|
||||
Transaction tx = new Transaction(wallet.getParams());
|
||||
tx.addInput(multisigContract.getOutput(0));
|
||||
// Our output always comes first.
|
||||
@ -373,7 +372,7 @@ public class PaymentChannelClientState {
|
||||
/** Container for a signature and an amount that was sent. */
|
||||
public static class IncrementedPayment {
|
||||
public TransactionSignature signature;
|
||||
public BigInteger amount;
|
||||
public Coin amount;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -391,17 +390,17 @@ public class PaymentChannelClientState {
|
||||
* @throws ValueOutOfRangeException If size is negative or the channel does not have sufficient money in it to
|
||||
* complete this payment.
|
||||
*/
|
||||
public synchronized IncrementedPayment incrementPaymentBy(BigInteger size) throws ValueOutOfRangeException {
|
||||
public synchronized IncrementedPayment incrementPaymentBy(Coin size) throws ValueOutOfRangeException {
|
||||
checkState(state == State.READY);
|
||||
checkNotExpired();
|
||||
checkNotNull(size); // Validity of size will be checked by makeUnsignedChannelContract.
|
||||
if (size.signum() < 0)
|
||||
throw new ValueOutOfRangeException("Tried to decrement payment");
|
||||
BigInteger newValueToMe = valueToMe.subtract(size);
|
||||
Coin newValueToMe = valueToMe.subtract(size);
|
||||
if (newValueToMe.compareTo(Transaction.MIN_NONDUST_OUTPUT) < 0 && newValueToMe.signum() > 0) {
|
||||
log.info("New value being sent back as change was smaller than minimum nondust output, sending all");
|
||||
size = valueToMe;
|
||||
newValueToMe = BigInteger.ZERO;
|
||||
newValueToMe = Coin.ZERO;
|
||||
}
|
||||
if (newValueToMe.signum() < 0)
|
||||
throw new ValueOutOfRangeException("Channel has too little money to pay " + size + " satoshis");
|
||||
@ -410,7 +409,7 @@ public class PaymentChannelClientState {
|
||||
Transaction.SigHash mode;
|
||||
// If we spent all the money we put into this channel, we (by definition) don't care what the outputs are, so
|
||||
// we sign with SIGHASH_NONE to let the server do what it wants.
|
||||
if (newValueToMe.equals(BigInteger.ZERO))
|
||||
if (newValueToMe.equals(Coin.ZERO))
|
||||
mode = Transaction.SigHash.NONE;
|
||||
else
|
||||
mode = Transaction.SigHash.SINGLE;
|
||||
@ -500,7 +499,7 @@ public class PaymentChannelClientState {
|
||||
* Returns the fees that will be paid if the refund transaction has to be claimed because the server failed to settle
|
||||
* the channel properly. May only be called after {@link PaymentChannelClientState#initiate()}
|
||||
*/
|
||||
public synchronized BigInteger getRefundTxFees() {
|
||||
public synchronized Coin getRefundTxFees() {
|
||||
checkState(state.compareTo(State.NEW) > 0);
|
||||
return refundFees;
|
||||
}
|
||||
@ -518,14 +517,14 @@ public class PaymentChannelClientState {
|
||||
/**
|
||||
* Gets the total value of this channel (ie the maximum payment possible)
|
||||
*/
|
||||
public BigInteger getTotalValue() {
|
||||
public Coin getTotalValue() {
|
||||
return totalValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the current amount refunded to us from the multisig contract (ie totalValue-valueSentToServer)
|
||||
*/
|
||||
public synchronized BigInteger getValueRefunded() {
|
||||
public synchronized Coin getValueRefunded() {
|
||||
checkState(state == State.READY);
|
||||
return valueToMe;
|
||||
}
|
||||
@ -533,7 +532,7 @@ public class PaymentChannelClientState {
|
||||
/**
|
||||
* Returns the amount of money sent on this channel so far.
|
||||
*/
|
||||
public synchronized BigInteger getValueSpent() {
|
||||
public synchronized Coin getValueSpent() {
|
||||
return getTotalValue().subtract(getValueRefunded());
|
||||
}
|
||||
}
|
||||
|
@ -27,7 +27,6 @@ import org.bitcoin.paymentchannel.Protos;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -102,7 +101,7 @@ public class PaymentChannelServer {
|
||||
* @param by The increase in total payment
|
||||
* @param to The new total payment to us (not including fees which may be required to claim the payment)
|
||||
*/
|
||||
public void paymentIncrease(BigInteger by, BigInteger to);
|
||||
public void paymentIncrease(Coin by, Coin to);
|
||||
}
|
||||
private final ServerConnection conn;
|
||||
|
||||
@ -119,7 +118,7 @@ public class PaymentChannelServer {
|
||||
@GuardedBy("lock") private ECKey myKey;
|
||||
|
||||
// The minimum accepted channel value
|
||||
private final BigInteger minAcceptedChannelSize;
|
||||
private final Coin minAcceptedChannelSize;
|
||||
|
||||
// The state manager for this channel
|
||||
@GuardedBy("lock") private PaymentChannelServerState state;
|
||||
@ -151,7 +150,7 @@ public class PaymentChannelServer {
|
||||
* the client and will close the connection on request)
|
||||
*/
|
||||
public PaymentChannelServer(TransactionBroadcaster broadcaster, Wallet wallet,
|
||||
BigInteger minAcceptedChannelSize, ServerConnection conn) {
|
||||
Coin minAcceptedChannelSize, ServerConnection conn) {
|
||||
this.broadcaster = checkNotNull(broadcaster);
|
||||
this.wallet = checkNotNull(wallet);
|
||||
this.minAcceptedChannelSize = checkNotNull(minAcceptedChannelSize);
|
||||
@ -310,10 +309,10 @@ public class PaymentChannelServer {
|
||||
private void receiveUpdatePaymentMessage(Protos.UpdatePayment msg, boolean sendAck) throws VerificationException, ValueOutOfRangeException, InsufficientMoneyException {
|
||||
log.info("Got a payment update");
|
||||
|
||||
BigInteger lastBestPayment = state.getBestValueToMe();
|
||||
final BigInteger refundSize = BigInteger.valueOf(msg.getClientChangeValue());
|
||||
Coin lastBestPayment = state.getBestValueToMe();
|
||||
final Coin refundSize = Coin.valueOf(msg.getClientChangeValue());
|
||||
boolean stillUsable = state.incrementPayment(refundSize, msg.getSignature().toByteArray());
|
||||
BigInteger bestPaymentChange = state.getBestValueToMe().subtract(lastBestPayment);
|
||||
Coin bestPaymentChange = state.getBestValueToMe().subtract(lastBestPayment);
|
||||
|
||||
if (bestPaymentChange.signum() > 0)
|
||||
conn.paymentIncrease(bestPaymentChange, state.getBestValueToMe());
|
||||
|
@ -17,17 +17,19 @@
|
||||
|
||||
package com.google.bitcoin.protocols.channels;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.Sha256Hash;
|
||||
import com.google.bitcoin.core.TransactionBroadcaster;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
import com.google.bitcoin.net.NioServer;
|
||||
import com.google.bitcoin.net.ProtobufParser;
|
||||
import com.google.bitcoin.net.StreamParserFactory;
|
||||
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
@ -46,7 +48,7 @@ public class PaymentChannelServerListener {
|
||||
|
||||
// The event handler factory which creates new ServerConnectionEventHandler per connection
|
||||
private final HandlerFactory eventHandlerFactory;
|
||||
private final BigInteger minAcceptedChannelSize;
|
||||
private final Coin minAcceptedChannelSize;
|
||||
|
||||
private NioServer server;
|
||||
private final int timeoutSeconds;
|
||||
@ -80,7 +82,7 @@ public class PaymentChannelServerListener {
|
||||
eventHandler.channelOpen(contractHash);
|
||||
}
|
||||
|
||||
@Override public void paymentIncrease(BigInteger by, BigInteger to) {
|
||||
@Override public void paymentIncrease(Coin by, Coin to) {
|
||||
eventHandler.paymentIncrease(by, to);
|
||||
}
|
||||
});
|
||||
@ -161,7 +163,7 @@ public class PaymentChannelServerListener {
|
||||
* @param eventHandlerFactory A factory which generates event handlers which are created for each new connection
|
||||
*/
|
||||
public PaymentChannelServerListener(TransactionBroadcaster broadcaster, Wallet wallet,
|
||||
final int timeoutSeconds, BigInteger minAcceptedChannelSize,
|
||||
final int timeoutSeconds, Coin minAcceptedChannelSize,
|
||||
HandlerFactory eventHandlerFactory) throws IOException {
|
||||
this.wallet = checkNotNull(wallet);
|
||||
this.broadcaster = checkNotNull(broadcaster);
|
||||
|
@ -30,7 +30,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Arrays;
|
||||
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
@ -101,9 +100,9 @@ public class PaymentChannelServerState {
|
||||
private byte[] bestValueSignature;
|
||||
|
||||
// The total value locked into the multi-sig output and the value to us in the last signature the client provided
|
||||
private BigInteger totalValue;
|
||||
private BigInteger bestValueToMe = BigInteger.ZERO;
|
||||
private BigInteger feePaidForPayment;
|
||||
private Coin totalValue;
|
||||
private Coin bestValueToMe = Coin.ZERO;
|
||||
private Coin feePaidForPayment;
|
||||
|
||||
// The refund/change transaction output that goes back to the client
|
||||
private TransactionOutput clientOutput;
|
||||
@ -126,7 +125,7 @@ public class PaymentChannelServerState {
|
||||
this.totalValue = multisigContract.getOutput(0).getValue();
|
||||
this.bestValueToMe = checkNotNull(storedServerChannel.bestValueToMe);
|
||||
this.bestValueSignature = storedServerChannel.bestValueSignature;
|
||||
checkArgument(bestValueToMe.equals(BigInteger.ZERO) || bestValueSignature != null);
|
||||
checkArgument(bestValueToMe.equals(Coin.ZERO) || bestValueSignature != null);
|
||||
this.storedServerChannel = storedServerChannel;
|
||||
storedServerChannel.state = this;
|
||||
this.state = State.READY;
|
||||
@ -263,9 +262,9 @@ public class PaymentChannelServerState {
|
||||
}
|
||||
|
||||
// Create a payment transaction with valueToMe going back to us
|
||||
private synchronized Wallet.SendRequest makeUnsignedChannelContract(BigInteger valueToMe) {
|
||||
private synchronized Wallet.SendRequest makeUnsignedChannelContract(Coin valueToMe) {
|
||||
Transaction tx = new Transaction(wallet.getParams());
|
||||
if (!totalValue.subtract(valueToMe).equals(BigInteger.ZERO)) {
|
||||
if (!totalValue.subtract(valueToMe).equals(Coin.ZERO)) {
|
||||
clientOutput.setValue(totalValue.subtract(valueToMe));
|
||||
tx.addOutput(clientOutput);
|
||||
}
|
||||
@ -283,17 +282,17 @@ public class PaymentChannelServerState {
|
||||
* @throws VerificationException If the signature does not verify or size is out of range (incl being rejected by the network as dust).
|
||||
* @return true if there is more value left on the channel, false if it is now fully used up.
|
||||
*/
|
||||
public synchronized boolean incrementPayment(BigInteger refundSize, byte[] signatureBytes) throws VerificationException, ValueOutOfRangeException, InsufficientMoneyException {
|
||||
public synchronized boolean incrementPayment(Coin refundSize, byte[] signatureBytes) throws VerificationException, ValueOutOfRangeException, InsufficientMoneyException {
|
||||
checkState(state == State.READY);
|
||||
checkNotNull(refundSize);
|
||||
checkNotNull(signatureBytes);
|
||||
TransactionSignature signature = TransactionSignature.decodeFromBitcoin(signatureBytes, true);
|
||||
// We allow snapping to zero for the payment amount because it's treated specially later, but not less than
|
||||
// the dust level because that would prevent the transaction from being relayed/mined.
|
||||
final boolean fullyUsedUp = refundSize.equals(BigInteger.ZERO);
|
||||
final boolean fullyUsedUp = refundSize.equals(Coin.ZERO);
|
||||
if (refundSize.compareTo(clientOutput.getMinNonDustValue()) < 0 && !fullyUsedUp)
|
||||
throw new ValueOutOfRangeException("Attempt to refund negative value or value too small to be accepted by the network");
|
||||
BigInteger newValueToMe = totalValue.subtract(refundSize);
|
||||
Coin newValueToMe = totalValue.subtract(refundSize);
|
||||
if (newValueToMe.signum() < 0)
|
||||
throw new ValueOutOfRangeException("Attempt to refund more than the contract allows.");
|
||||
if (newValueToMe.compareTo(bestValueToMe) < 0)
|
||||
@ -439,14 +438,14 @@ public class PaymentChannelServerState {
|
||||
/**
|
||||
* Gets the highest payment to ourselves (which we will receive on settle(), not including fees)
|
||||
*/
|
||||
public synchronized BigInteger getBestValueToMe() {
|
||||
public synchronized Coin getBestValueToMe() {
|
||||
return bestValueToMe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the fee paid in the final payment transaction (only available if settle() did not throw an exception)
|
||||
*/
|
||||
public synchronized BigInteger getFeePaid() {
|
||||
public synchronized Coin getFeePaid() {
|
||||
checkState(state == State.CLOSED || state == State.CLOSING);
|
||||
return feePaidForPayment;
|
||||
}
|
||||
|
@ -16,10 +16,10 @@
|
||||
|
||||
package com.google.bitcoin.protocols.channels;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.Sha256Hash;
|
||||
import com.google.bitcoin.net.ProtobufParser;
|
||||
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
@ -70,7 +70,7 @@ public abstract class ServerConnectionEventHandler {
|
||||
* @param by The increase in total payment
|
||||
* @param to The new total payment to us (not including fees which may be required to claim the payment)
|
||||
*/
|
||||
public abstract void paymentIncrease(BigInteger by, BigInteger to);
|
||||
public abstract void paymentIncrease(Coin by, Coin to);
|
||||
|
||||
/**
|
||||
* <p>Called when the channel was closed for some reason. May be called without a call to
|
||||
|
@ -26,7 +26,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Date;
|
||||
import java.util.Set;
|
||||
import java.util.Timer;
|
||||
@ -69,8 +68,8 @@ public class StoredPaymentChannelClientStates implements WalletExtension {
|
||||
}
|
||||
|
||||
/** Returns the outstanding amount of money sent back to us for all channels to this server added together. */
|
||||
public BigInteger getBalanceForServer(Sha256Hash id) {
|
||||
BigInteger balance = BigInteger.ZERO;
|
||||
public Coin getBalanceForServer(Sha256Hash id) {
|
||||
Coin balance = Coin.ZERO;
|
||||
lock.lock();
|
||||
try {
|
||||
Set<StoredClientChannel> setChannels = mapChannels.get(id);
|
||||
@ -120,7 +119,7 @@ public class StoredPaymentChannelClientStates implements WalletExtension {
|
||||
synchronized (channel) {
|
||||
// Check if the channel is usable (has money, inactive) and if so, activate it.
|
||||
log.info("Considering channel {} contract {}", channel.hashCode(), channel.contract.getHash());
|
||||
if (channel.close != null || channel.valueToMe.equals(BigInteger.ZERO)) {
|
||||
if (channel.close != null || channel.valueToMe.equals(Coin.ZERO)) {
|
||||
log.info(" ... but is closed or empty");
|
||||
continue;
|
||||
}
|
||||
@ -256,8 +255,8 @@ public class StoredPaymentChannelClientStates implements WalletExtension {
|
||||
new Transaction(params, storedState.getContractTransaction().toByteArray()),
|
||||
refundTransaction,
|
||||
ECKey.fromPrivate(storedState.getMyKey().toByteArray()),
|
||||
BigInteger.valueOf(storedState.getValueToMe()),
|
||||
BigInteger.valueOf(storedState.getRefundFees()), false);
|
||||
Coin.valueOf(storedState.getValueToMe()),
|
||||
Coin.valueOf(storedState.getRefundFees()), false);
|
||||
if (storedState.hasCloseTransactionHash())
|
||||
channel.close = containingWallet.getTransaction(new Sha256Hash(storedState.toByteArray()));
|
||||
putChannel(channel, false);
|
||||
@ -292,13 +291,13 @@ class StoredClientChannel {
|
||||
// The transaction that closed the channel (generated by the server)
|
||||
Transaction close;
|
||||
ECKey myKey;
|
||||
BigInteger valueToMe, refundFees;
|
||||
Coin valueToMe, refundFees;
|
||||
|
||||
// In-memory flag to indicate intent to resume this channel (or that the channel is already in use)
|
||||
boolean active = false;
|
||||
|
||||
StoredClientChannel(Sha256Hash id, Transaction contract, Transaction refund, ECKey myKey, BigInteger valueToMe,
|
||||
BigInteger refundFees, boolean active) {
|
||||
StoredClientChannel(Sha256Hash id, Transaction contract, Transaction refund, ECKey myKey, Coin valueToMe,
|
||||
Coin refundFees, boolean active) {
|
||||
this.id = id;
|
||||
this.contract = contract;
|
||||
this.refund = refund;
|
||||
|
@ -24,7 +24,6 @@ import net.jcip.annotations.GuardedBy;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.locks.ReentrantLock;
|
||||
|
||||
@ -183,7 +182,7 @@ public class StoredPaymentChannelServerStates implements WalletExtension {
|
||||
new TransactionOutput(params, null, storedState.getClientOutput().toByteArray(), 0),
|
||||
storedState.getRefundTransactionUnlockTimeSecs(),
|
||||
ECKey.fromPrivate(storedState.getMyKey().toByteArray()),
|
||||
BigInteger.valueOf(storedState.getBestValueToMe()),
|
||||
Coin.valueOf(storedState.getBestValueToMe()),
|
||||
storedState.hasBestValueSignature() ? storedState.getBestValueSignature().toByteArray() : null);
|
||||
putChannel(channel);
|
||||
}
|
||||
|
@ -19,7 +19,6 @@ package com.google.bitcoin.protocols.channels;
|
||||
import com.google.bitcoin.core.*;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.math.BigInteger;
|
||||
import java.util.Date;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkArgument;
|
||||
@ -30,7 +29,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
||||
* time approaches.
|
||||
*/
|
||||
public class StoredServerChannel {
|
||||
BigInteger bestValueToMe;
|
||||
Coin bestValueToMe;
|
||||
byte[] bestValueSignature;
|
||||
long refundTransactionUnlockTimeSecs;
|
||||
Transaction contract;
|
||||
@ -43,7 +42,7 @@ public class StoredServerChannel {
|
||||
PaymentChannelServerState state = null;
|
||||
|
||||
StoredServerChannel(@Nullable PaymentChannelServerState state, Transaction contract, TransactionOutput clientOutput,
|
||||
long refundTransactionUnlockTimeSecs, ECKey myKey, BigInteger bestValueToMe, @Nullable byte[] bestValueSignature) {
|
||||
long refundTransactionUnlockTimeSecs, ECKey myKey, Coin bestValueToMe, @Nullable byte[] bestValueSignature) {
|
||||
this.contract = contract;
|
||||
this.clientOutput = clientOutput;
|
||||
this.refundTransactionUnlockTimeSecs = refundTransactionUnlockTimeSecs;
|
||||
@ -57,7 +56,7 @@ public class StoredServerChannel {
|
||||
* <p>Updates the best value to the server to the given newValue and newSignature without any checking.</p>
|
||||
* <p>Does <i>NOT</i> notify the wallet of an update to the {@link StoredPaymentChannelServerStates}.</p>
|
||||
*/
|
||||
synchronized void updateValueToMe(BigInteger newValue, byte[] newSignature) {
|
||||
synchronized void updateValueToMe(Coin newValue, byte[] newSignature) {
|
||||
this.bestValueToMe = newValue;
|
||||
this.bestValueSignature = newSignature;
|
||||
}
|
||||
@ -107,11 +106,11 @@ public class StoredServerChannel {
|
||||
final String newline = String.format("%n");
|
||||
return String.format("Stored server channel (%s)%n" +
|
||||
" Key: %s%n" +
|
||||
" Value to me: %d%n" +
|
||||
" Value to me: %s%n" +
|
||||
" Client output: %s%n" +
|
||||
" Refund unlock: %s (%d unix time)%n" +
|
||||
" Contract: %s%n",
|
||||
connectedHandler != null ? "connected" : "disconnected", myKey, bestValueToMe,
|
||||
connectedHandler != null ? "connected" : "disconnected", myKey, bestValueToMe.toString(),
|
||||
clientOutput, new Date(refundTransactionUnlockTimeSecs * 1000), refundTransactionUnlockTimeSecs,
|
||||
contract.toString().replaceAll(newline, newline + " "));
|
||||
}
|
||||
|
@ -18,6 +18,7 @@
|
||||
package com.google.bitcoin.protocols.payments;
|
||||
|
||||
import com.google.bitcoin.core.Address;
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
import com.google.bitcoin.crypto.X509Utils;
|
||||
@ -30,7 +31,6 @@ import org.bitcoin.protocols.payments.Protos;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.Serializable;
|
||||
import java.math.BigInteger;
|
||||
import java.security.*;
|
||||
import java.security.cert.*;
|
||||
import java.security.cert.Certificate;
|
||||
@ -67,7 +67,7 @@ public class PaymentProtocol {
|
||||
* @return created payment request, in its builder form
|
||||
*/
|
||||
public static Protos.PaymentRequest.Builder createPaymentRequest(NetworkParameters params,
|
||||
@Nullable BigInteger amount, Address toAddress, @Nullable String memo, @Nullable String paymentUrl,
|
||||
@Nullable Coin amount, Address toAddress, @Nullable String memo, @Nullable String paymentUrl,
|
||||
@Nullable byte[] merchantData) {
|
||||
return createPaymentRequest(params, ImmutableList.of(createPayToAddressOutput(amount, toAddress)), memo,
|
||||
paymentUrl, merchantData);
|
||||
@ -282,7 +282,7 @@ public class PaymentProtocol {
|
||||
* @return created payment message
|
||||
*/
|
||||
public static Protos.Payment createPaymentMessage(List<Transaction> transactions,
|
||||
@Nullable BigInteger refundAmount, @Nullable Address refundAddress, @Nullable String memo,
|
||||
@Nullable Coin refundAmount, @Nullable Address refundAddress, @Nullable String memo,
|
||||
@Nullable byte[] merchantData) {
|
||||
if (refundAddress != null) {
|
||||
if (refundAmount == null)
|
||||
@ -387,7 +387,7 @@ public class PaymentProtocol {
|
||||
* @param address address to pay to
|
||||
* @return output
|
||||
*/
|
||||
public static Protos.Output createPayToAddressOutput(@Nullable BigInteger amount, Address address) {
|
||||
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)
|
||||
@ -404,10 +404,10 @@ public class PaymentProtocol {
|
||||
* Value object to hold amount/script pairs.
|
||||
*/
|
||||
public static class Output implements Serializable {
|
||||
public final @Nullable BigInteger amount;
|
||||
public final @Nullable Coin amount;
|
||||
public final byte[] scriptData;
|
||||
|
||||
public Output(@Nullable BigInteger amount, byte[] scriptData) {
|
||||
public Output(@Nullable Coin amount, byte[] scriptData) {
|
||||
this.amount = amount;
|
||||
this.scriptData = scriptData;
|
||||
}
|
||||
|
@ -30,7 +30,6 @@ import org.bitcoin.protocols.payments.Protos;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.io.*;
|
||||
import java.math.BigInteger;
|
||||
import java.net.*;
|
||||
import java.security.KeyStoreException;
|
||||
import java.util.ArrayList;
|
||||
@ -71,7 +70,7 @@ public class PaymentSession {
|
||||
private final TrustStoreLoader trustStoreLoader;
|
||||
private Protos.PaymentRequest paymentRequest;
|
||||
private Protos.PaymentDetails paymentDetails;
|
||||
private BigInteger totalValue = BigInteger.ZERO;
|
||||
private Coin totalValue = Coin.ZERO;
|
||||
|
||||
/**
|
||||
* Stores the calculated PKI verification data, or null if none is available.
|
||||
@ -224,7 +223,7 @@ public class PaymentSession {
|
||||
public List<PaymentProtocol.Output> getOutputs() {
|
||||
List<PaymentProtocol.Output> outputs = new ArrayList<PaymentProtocol.Output>(paymentDetails.getOutputsCount());
|
||||
for (Protos.Output output : paymentDetails.getOutputsList()) {
|
||||
BigInteger amount = output.hasAmount() ? BigInteger.valueOf(output.getAmount()) : null;
|
||||
Coin amount = output.hasAmount() ? Coin.valueOf(output.getAmount()) : null;
|
||||
outputs.add(new PaymentProtocol.Output(amount, output.getScript().toByteArray()));
|
||||
}
|
||||
return outputs;
|
||||
@ -243,7 +242,7 @@ public class PaymentSession {
|
||||
/**
|
||||
* Returns the total amount of bitcoins requested.
|
||||
*/
|
||||
public BigInteger getValue() {
|
||||
public Coin getValue() {
|
||||
return totalValue;
|
||||
}
|
||||
|
||||
@ -297,7 +296,7 @@ public class PaymentSession {
|
||||
public Wallet.SendRequest getSendRequest() {
|
||||
Transaction tx = new Transaction(params);
|
||||
for (Protos.Output output : paymentDetails.getOutputsList())
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(output.getAmount()), output.getScript().toByteArray()));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(output.getAmount()), output.getScript().toByteArray()));
|
||||
return Wallet.SendRequest.forTx(tx);
|
||||
}
|
||||
|
||||
@ -397,7 +396,7 @@ public class PaymentSession {
|
||||
throw new PaymentProtocolException.InvalidOutputs("No outputs");
|
||||
for (Protos.Output output : paymentDetails.getOutputsList()) {
|
||||
if (output.hasAmount())
|
||||
totalValue = totalValue.add(BigInteger.valueOf(output.getAmount()));
|
||||
totalValue = totalValue.add(Coin.valueOf(output.getAmount()));
|
||||
}
|
||||
// This won't ever happen in practice. It would only happen if the user provided outputs
|
||||
// that are obviously invalid. Still, we don't want to silently overflow.
|
||||
|
@ -650,7 +650,7 @@ public class H2FullPrunedBlockStore implements FullPrunedBlockStore {
|
||||
}
|
||||
// Parse it.
|
||||
int height = results.getInt(1);
|
||||
BigInteger value = new BigInteger(results.getBytes(2));
|
||||
Coin value = new Coin(results.getBytes(2));
|
||||
// Tell the StoredTransactionOutput that we are a coinbase, as that is encoded in height
|
||||
return new StoredTransactionOutput(hash, index, value, height, true, results.getBytes(3));
|
||||
} catch (SQLException ex) {
|
||||
|
@ -744,7 +744,7 @@ public class PostgresFullPrunedBlockStore implements FullPrunedBlockStore {
|
||||
}
|
||||
// Parse it.
|
||||
int height = results.getInt(1);
|
||||
BigInteger value = new BigInteger(results.getBytes(2));
|
||||
Coin value = new Coin(results.getBytes(2));
|
||||
// Tell the StoredTransactionOutput that we are a coinbase, as that is encoded in height
|
||||
StoredTransactionOutput txout = new StoredTransactionOutput(hash, index, value, height, true, results.getBytes(3));
|
||||
return txout;
|
||||
|
@ -503,7 +503,7 @@ public class WalletProtobufSerializer {
|
||||
}
|
||||
|
||||
for (Protos.TransactionOutput outputProto : txProto.getTransactionOutputList()) {
|
||||
BigInteger value = BigInteger.valueOf(outputProto.getValue());
|
||||
Coin value = Coin.valueOf(outputProto.getValue());
|
||||
byte[] scriptBytes = outputProto.getScriptBytes().toByteArray();
|
||||
TransactionOutput output = new TransactionOutput(params, tx, value, scriptBytes);
|
||||
tx.addOutput(output);
|
||||
@ -515,7 +515,7 @@ public class WalletProtobufSerializer {
|
||||
inputProto.getTransactionOutPointIndex() & 0xFFFFFFFFL,
|
||||
byteStringToHash(inputProto.getTransactionOutPointHash())
|
||||
);
|
||||
BigInteger value = inputProto.hasValue() ? BigInteger.valueOf(inputProto.getValue()) : null;
|
||||
Coin value = inputProto.hasValue() ? Coin.valueOf(inputProto.getValue()) : null;
|
||||
TransactionInput input = new TransactionInput(params, tx, scriptBytes, outpoint, value);
|
||||
if (inputProto.hasSequence()) {
|
||||
input.setSequenceNumber(inputProto.getSequence());
|
||||
|
@ -22,7 +22,6 @@ import com.google.bitcoin.store.BlockStoreException;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.nio.ByteBuffer;
|
||||
|
||||
/**
|
||||
@ -33,7 +32,7 @@ public class FakeTxBuilder {
|
||||
* Create a fake TX of sufficient realism to exercise the unit tests. Two outputs, one to us, one to somewhere
|
||||
* else to simulate change. There is one random input.
|
||||
*/
|
||||
public static Transaction createFakeTxWithChangeAddress(NetworkParameters params, BigInteger nanocoins, Address to, Address changeOutput) {
|
||||
public static Transaction createFakeTxWithChangeAddress(NetworkParameters params, Coin nanocoins, Address to, Address changeOutput) {
|
||||
Transaction t = new Transaction(params);
|
||||
TransactionOutput outputToMe = new TransactionOutput(params, t, nanocoins, to);
|
||||
t.addOutput(outputToMe);
|
||||
@ -54,7 +53,7 @@ public class FakeTxBuilder {
|
||||
* Create a fake TX of sufficient realism to exercise the unit tests. Two outputs, one to us, one to somewhere
|
||||
* else to simulate change. There is one random input.
|
||||
*/
|
||||
public static Transaction createFakeTx(NetworkParameters params, BigInteger nanocoins, Address to) {
|
||||
public static Transaction createFakeTx(NetworkParameters params, Coin nanocoins, Address to) {
|
||||
return createFakeTxWithChangeAddress(params, nanocoins, to, new ECKey().toAddress(params));
|
||||
}
|
||||
|
||||
@ -62,7 +61,7 @@ public class FakeTxBuilder {
|
||||
* Create a fake TX of sufficient realism to exercise the unit tests. Two outputs, one to us, one to somewhere
|
||||
* else to simulate change. There is one random input.
|
||||
*/
|
||||
public static Transaction createFakeTx(NetworkParameters params, BigInteger nanocoins, ECKey to) {
|
||||
public static Transaction createFakeTx(NetworkParameters params, Coin nanocoins, ECKey to) {
|
||||
Transaction t = new Transaction(params);
|
||||
TransactionOutput outputToMe = new TransactionOutput(params, t, nanocoins, to);
|
||||
t.addOutput(outputToMe);
|
||||
@ -82,7 +81,7 @@ public class FakeTxBuilder {
|
||||
/**
|
||||
* Transaction[0] is a feeder transaction, supplying BTC to Transaction[1]
|
||||
*/
|
||||
public static Transaction[] createFakeTx(NetworkParameters params, BigInteger nanocoins,
|
||||
public static Transaction[] createFakeTx(NetworkParameters params, Coin nanocoins,
|
||||
Address to, Address from) {
|
||||
// Create fake TXes of sufficient realism to exercise the unit tests. This transaction send BTC from the
|
||||
// from address, to the to address with to one to somewhere else to simulate change.
|
||||
@ -134,7 +133,7 @@ public class FakeTxBuilder {
|
||||
*/
|
||||
public static DoubleSpends createFakeDoubleSpendTxns(NetworkParameters params, Address to) {
|
||||
DoubleSpends doubleSpends = new DoubleSpends();
|
||||
BigInteger value = Utils.toNanoCoins(1, 0);
|
||||
Coin value = Utils.toNanoCoins(1, 0);
|
||||
Address someBadGuy = new ECKey().toAddress(params);
|
||||
|
||||
doubleSpends.t1 = new Transaction(params);
|
||||
|
@ -29,7 +29,6 @@ import com.google.common.util.concurrent.SettableFuture;
|
||||
import javax.annotation.Nullable;
|
||||
import javax.net.SocketFactory;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
@ -82,7 +81,7 @@ public class TestWithNetworkConnections {
|
||||
BriefLogFormatter.init();
|
||||
|
||||
unitTestParams = UnitTestParams.get();
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||
this.blockStore = blockStore;
|
||||
wallet = new Wallet(unitTestParams);
|
||||
key = wallet.freshReceiveKey();
|
||||
|
@ -24,7 +24,6 @@ import com.google.bitcoin.utils.BriefLogFormatter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeBlock;
|
||||
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeTx;
|
||||
@ -49,7 +48,7 @@ public class TestWithWallet {
|
||||
|
||||
public void setUp() throws Exception {
|
||||
BriefLogFormatter.init();
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||
wallet = new Wallet(params);
|
||||
myKey = wallet.currentReceiveKey();
|
||||
myAddress = myKey.toAddress(params);
|
||||
@ -83,17 +82,17 @@ public class TestWithWallet {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Transaction sendMoneyToWallet(Wallet wallet, BigInteger value, Address toAddress, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
||||
protected Transaction sendMoneyToWallet(Wallet wallet, Coin value, Address toAddress, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
||||
return sendMoneyToWallet(wallet, createFakeTx(params, value, toAddress), type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Transaction sendMoneyToWallet(Wallet wallet, BigInteger value, ECKey toPubKey, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
||||
protected Transaction sendMoneyToWallet(Wallet wallet, Coin value, ECKey toPubKey, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
||||
return sendMoneyToWallet(wallet, createFakeTx(params, value, toPubKey), type);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
protected Transaction sendMoneyToWallet(BigInteger value, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
||||
protected Transaction sendMoneyToWallet(Coin value, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
||||
return sendMoneyToWallet(this.wallet, createFakeTx(params, value, myAddress), type);
|
||||
}
|
||||
}
|
||||
|
@ -20,14 +20,16 @@ package com.google.bitcoin.uri;
|
||||
|
||||
import com.google.bitcoin.core.Address;
|
||||
import com.google.bitcoin.core.AddressFormatException;
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.Utils;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URLDecoder;
|
||||
@ -207,7 +209,7 @@ public class BitcoinURI {
|
||||
if (FIELD_AMOUNT.equals(nameToken)) {
|
||||
// Decode the amount (contains an optional decimal component to 8dp).
|
||||
try {
|
||||
BigInteger amount = Utils.toNanoCoins(valueToken);
|
||||
Coin amount = Utils.toNanoCoins(valueToken);
|
||||
putWithValidation(FIELD_AMOUNT, amount);
|
||||
} catch (NumberFormatException e) {
|
||||
throw new OptionalFieldValidationException(String.format("'%s' is not a valid amount", valueToken), e);
|
||||
@ -263,8 +265,8 @@ public class BitcoinURI {
|
||||
* @return The amount name encoded using a pure integer value based at
|
||||
* 10,000,000 units is 1 BTC. May be null if no amount is specified
|
||||
*/
|
||||
public BigInteger getAmount() {
|
||||
return (BigInteger) parameterMap.get(FIELD_AMOUNT);
|
||||
public Coin getAmount() {
|
||||
return (Coin) parameterMap.get(FIELD_AMOUNT);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -313,7 +315,7 @@ public class BitcoinURI {
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
public static String convertToBitcoinURI(Address address, BigInteger amount, String label, String message) {
|
||||
public static String convertToBitcoinURI(Address address, Coin amount, String label, String message) {
|
||||
return convertToBitcoinURI(address.toString(), amount, label, message);
|
||||
}
|
||||
|
||||
@ -326,11 +328,11 @@ public class BitcoinURI {
|
||||
* @param message A message
|
||||
* @return A String containing the Bitcoin URI
|
||||
*/
|
||||
public static String convertToBitcoinURI(String address, @Nullable BigInteger amount, @Nullable String label,
|
||||
public static String convertToBitcoinURI(String address, @Nullable Coin amount, @Nullable String label,
|
||||
@Nullable String message) {
|
||||
checkNotNull(address);
|
||||
if (amount != null && amount.signum() < 0) {
|
||||
throw new IllegalArgumentException("Amount must be positive");
|
||||
throw new IllegalArgumentException("Coin must be positive");
|
||||
}
|
||||
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
@ -1,22 +1,22 @@
|
||||
package com.google.bitcoin.wallet;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.TransactionOutput;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* Represents the results of a
|
||||
* {@link com.google.bitcoin.wallet.CoinSelector#select(java.math.BigInteger, java.util.LinkedList)} operation. A
|
||||
* {@link com.google.bitcoin.wallet.CoinSelector#select(java.math.Coin, java.util.LinkedList)} operation. A
|
||||
* coin selection represents a list of spendable transaction outputs that sum together to give valueGathered.
|
||||
* Different coin selections could be produced by different coin selectors from the same input set, according
|
||||
* to their varying policies.
|
||||
*/
|
||||
public class CoinSelection {
|
||||
public BigInteger valueGathered;
|
||||
public Coin valueGathered;
|
||||
public Collection<TransactionOutput> gathered;
|
||||
|
||||
public CoinSelection(BigInteger valueGathered, Collection<TransactionOutput> gathered) {
|
||||
public CoinSelection(Coin valueGathered, Collection<TransactionOutput> gathered) {
|
||||
this.valueGathered = valueGathered;
|
||||
this.gathered = gathered;
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package com.google.bitcoin.wallet;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.TransactionOutput;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.LinkedList;
|
||||
|
||||
/**
|
||||
@ -17,5 +17,5 @@ public interface CoinSelector {
|
||||
* this call and can be edited freely. See the docs for CoinSelection to learn more, or look a the implementation
|
||||
* of {@link com.google.bitcoin.wallet.DefaultCoinSelector}.
|
||||
*/
|
||||
public CoinSelection select(BigInteger target, LinkedList<TransactionOutput> candidates);
|
||||
public CoinSelection select(Coin target, LinkedList<TransactionOutput> candidates);
|
||||
}
|
||||
|
@ -1,5 +1,6 @@
|
||||
package com.google.bitcoin.wallet;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
import com.google.bitcoin.core.TransactionConfidence;
|
||||
@ -16,7 +17,7 @@ import java.util.*;
|
||||
* "spending" more priority than would be required to get the transaction we are creating confirmed.
|
||||
*/
|
||||
public class DefaultCoinSelector implements CoinSelector {
|
||||
public CoinSelection select(BigInteger biTarget, LinkedList<TransactionOutput> candidates) {
|
||||
public CoinSelection select(Coin biTarget, LinkedList<TransactionOutput> candidates) {
|
||||
long target = biTarget.longValue();
|
||||
HashSet<TransactionOutput> selected = new HashSet<TransactionOutput>();
|
||||
// Sort the inputs by age*value so we get the highest "coindays" spent.
|
||||
@ -39,7 +40,7 @@ public class DefaultCoinSelector implements CoinSelector {
|
||||
}
|
||||
// Total may be lower than target here, if the given candidates were insufficient to create to requested
|
||||
// transaction.
|
||||
return new CoinSelection(BigInteger.valueOf(total), selected);
|
||||
return new CoinSelection(Coin.valueOf(total), selected);
|
||||
}
|
||||
|
||||
@VisibleForTesting static void sortOutputs(ArrayList<TransactionOutput> outputs) {
|
||||
@ -53,10 +54,10 @@ public class DefaultCoinSelector implements CoinSelector {
|
||||
depth1 = conf1.getDepthInBlocks();
|
||||
if (conf2.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING)
|
||||
depth2 = conf2.getDepthInBlocks();
|
||||
BigInteger aValue = a.getValue();
|
||||
BigInteger bValue = b.getValue();
|
||||
BigInteger aCoinDepth = aValue.multiply(BigInteger.valueOf(depth1));
|
||||
BigInteger bCoinDepth = bValue.multiply(BigInteger.valueOf(depth2));
|
||||
Coin aValue = a.getValue();
|
||||
Coin bValue = b.getValue();
|
||||
BigInteger aCoinDepth = aValue.toBigInteger().multiply(BigInteger.valueOf(depth1));
|
||||
BigInteger bCoinDepth = bValue.toBigInteger().multiply(BigInteger.valueOf(depth2));
|
||||
int c1 = bCoinDepth.compareTo(aCoinDepth);
|
||||
if (c1 != 0) return c1;
|
||||
// The "coin*days" destroyed are equal, sort by value alone to get the lowest transaction size.
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package com.google.bitcoin.wallet;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
import com.google.bitcoin.core.TransactionConfidence;
|
||||
@ -24,13 +25,11 @@ import com.google.bitcoin.core.TransactionInput;
|
||||
import com.google.bitcoin.core.TransactionOutput;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
import com.google.bitcoin.script.ScriptChunk;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.List;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkState;
|
||||
@ -48,7 +47,7 @@ public class DefaultRiskAnalysis implements RiskAnalysis {
|
||||
* rejected by the network. Currently it's 546 satoshis. This is different from {@link Transaction#MIN_NONDUST_OUTPUT}
|
||||
* because of an upcoming fee change in Bitcoin Core 0.9.
|
||||
*/
|
||||
public static final BigInteger MIN_ANALYSIS_NONDUST_OUTPUT = BigInteger.valueOf(546);
|
||||
public static final Coin MIN_ANALYSIS_NONDUST_OUTPUT = Coin.valueOf(546);
|
||||
|
||||
protected final Transaction tx;
|
||||
protected final List<Transaction> dependencies;
|
||||
|
@ -22,7 +22,6 @@ import com.google.common.collect.Lists;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.LinkedList;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
@ -48,10 +47,10 @@ public class KeyTimeCoinSelector implements CoinSelector {
|
||||
}
|
||||
|
||||
@Override
|
||||
public CoinSelection select(BigInteger target, LinkedList<TransactionOutput> candidates) {
|
||||
public CoinSelection select(Coin target, LinkedList<TransactionOutput> candidates) {
|
||||
try {
|
||||
LinkedList<TransactionOutput> gathered = Lists.newLinkedList();
|
||||
BigInteger valueGathered = BigInteger.ZERO;
|
||||
Coin valueGathered = Coin.ZERO;
|
||||
for (TransactionOutput output : candidates) {
|
||||
if (ignorePending && !isConfirmed(output))
|
||||
continue;
|
||||
|
@ -5978,7 +5978,7 @@ public final class Protos {
|
||||
internal_static_payments_Output_fieldAccessorTable = new
|
||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||
internal_static_payments_Output_descriptor,
|
||||
new java.lang.String[] { "Amount", "Script", });
|
||||
new java.lang.String[] { "Coin", "Script", });
|
||||
internal_static_payments_PaymentDetails_descriptor =
|
||||
getDescriptor().getMessageTypes().get(1);
|
||||
internal_static_payments_PaymentDetails_fieldAccessorTable = new
|
||||
|
@ -65,7 +65,7 @@ public class BlockChainTest {
|
||||
public void setUp() throws Exception {
|
||||
BriefLogFormatter.initVerbose();
|
||||
testNetChain = new BlockChain(testNet, new Wallet(testNet), new MemoryBlockStore(testNet));
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||
|
||||
unitTestParams = UnitTestParams.get();
|
||||
wallet = new Wallet(unitTestParams) {
|
||||
@ -278,7 +278,7 @@ public class BlockChainTest {
|
||||
b1.addTransaction(t2);
|
||||
b1.solve();
|
||||
chain.add(b1);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -300,7 +300,7 @@ public class BlockChainTest {
|
||||
assertNotNull(coinbaseTransaction);
|
||||
|
||||
// The coinbase tx is not yet available to spend.
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(50, 0));
|
||||
assertTrue(!coinbaseTransaction.isMature());
|
||||
|
||||
@ -321,7 +321,7 @@ public class BlockChainTest {
|
||||
chain.add(b2);
|
||||
|
||||
// Wallet still does not have the coinbase transaction available for spend.
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(50, 0));
|
||||
|
||||
// The coinbase transaction is still not mature.
|
||||
|
@ -164,7 +164,7 @@ public class BlockTest {
|
||||
//assertTrue(tx.length == tx.bitcoinSerialize().length && tx.length == 8);
|
||||
byte[] outputScript = new byte[10];
|
||||
Arrays.fill(outputScript, (byte) ScriptOpCodes.OP_FALSE);
|
||||
tx.addOutput(new TransactionOutput(params, null, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, null, Coin.valueOf(1), outputScript));
|
||||
tx.addInput(new TransactionInput(params, null, new byte[] {(byte) ScriptOpCodes.OP_FALSE},
|
||||
new TransactionOutPoint(params, 0, Sha256Hash.create(new byte[] {1}))));
|
||||
int origTxLength = 8 + 2 + 8 + 1 + 10 + 40 + 1 + 1;
|
||||
|
@ -22,6 +22,7 @@ import com.google.bitcoin.store.MemoryBlockStore;
|
||||
import com.google.bitcoin.testing.FakeTxBuilder;
|
||||
import com.google.bitcoin.utils.BriefLogFormatter;
|
||||
import com.google.bitcoin.utils.Threading;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
@ -53,7 +54,7 @@ public class ChainSplitTest {
|
||||
public void setUp() throws Exception {
|
||||
BriefLogFormatter.init();
|
||||
Utils.setMockClock(); // Use mock clock
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||
unitTestParams = UnitTestParams.get();
|
||||
wallet = new Wallet(unitTestParams);
|
||||
ECKey key1 = wallet.freshReceiveKey();
|
||||
@ -164,11 +165,11 @@ public class ChainSplitTest {
|
||||
assertTrue(chain.add(b2));
|
||||
// genesis -> b1 -> b2
|
||||
// \-> b3 -> b4
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
Block b3 = b1.createNextBlock(coinsTo);
|
||||
Block b4 = b3.createNextBlock(someOtherGuy);
|
||||
assertTrue(chain.add(b3));
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertTrue(chain.add(b4));
|
||||
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
|
||||
}
|
||||
@ -183,7 +184,7 @@ public class ChainSplitTest {
|
||||
Transaction spend = wallet.createSend(dest, Utils.toNanoCoins(10, 0));
|
||||
wallet.commitTx(spend);
|
||||
// Waiting for confirmation ... make it eligible for selection.
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
spend.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByAddress(new byte[]{1, 2, 3, 4})));
|
||||
spend.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByAddress(new byte[]{5,6,7,8})));
|
||||
assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
|
||||
@ -276,7 +277,7 @@ public class ChainSplitTest {
|
||||
// -> b2
|
||||
Block b2 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
|
||||
chain.add(b2);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
// genesis -> b1 -> b3
|
||||
// -> b2
|
||||
Block b3 = b1.createNextBlock(someOtherGuy);
|
||||
@ -399,7 +400,7 @@ public class ChainSplitTest {
|
||||
final ArrayList<Transaction> txns = new ArrayList<Transaction>(3);
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
txns.add(tx);
|
||||
}
|
||||
});
|
||||
@ -552,7 +553,7 @@ public class ChainSplitTest {
|
||||
wallet.commitTx(t3);
|
||||
chain.add(FakeTxBuilder.makeSolvedTestBlock(b1, t2, t3));
|
||||
|
||||
final BigInteger coins0point98 = Utils.COIN.subtract(Utils.CENT).subtract(Utils.CENT);
|
||||
final Coin coins0point98 = Utils.COIN.subtract(Utils.CENT).subtract(Utils.CENT);
|
||||
assertEquals(coins0point98, wallet.getBalance());
|
||||
|
||||
// Now round trip the wallet and force a re-org.
|
||||
@ -577,7 +578,7 @@ public class ChainSplitTest {
|
||||
final ArrayList<Transaction> txns = new ArrayList<Transaction>(3);
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
txns.add(tx);
|
||||
}
|
||||
}, Threading.SAME_THREAD);
|
||||
|
@ -42,7 +42,7 @@ public class CoinbaseBlockTest {
|
||||
private static final int BLOCK_OF_INTEREST = 169482;
|
||||
private static final int BLOCK_LENGTH_AS_HEX = 37357;
|
||||
private static final long BLOCK_NONCE = 3973947400L;
|
||||
private static final BigInteger BALANCE_AFTER_BLOCK = BigInteger.valueOf(22223642);
|
||||
private static final Coin BALANCE_AFTER_BLOCK = Coin.valueOf(22223642);
|
||||
|
||||
@Test
|
||||
public void testReceiveCoinbaseTransaction() throws Exception {
|
||||
@ -70,7 +70,7 @@ public class CoinbaseBlockTest {
|
||||
wallet.importKey(miningKey);
|
||||
|
||||
// Initial balance should be zero by construction.
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
|
||||
// Give the wallet the first transaction in the block - this is the coinbase tx.
|
||||
List<Transaction> transactions = block.getTransactions();
|
||||
@ -79,7 +79,7 @@ public class CoinbaseBlockTest {
|
||||
|
||||
// Coinbase transaction should have been received successfully but be unavailable to spend (too young).
|
||||
assertEquals(BALANCE_AFTER_BLOCK, wallet.getBalance(BalanceType.ESTIMATED));
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance(BalanceType.AVAILABLE));
|
||||
assertEquals(Coin.ZERO, wallet.getBalance(BalanceType.AVAILABLE));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -65,9 +65,9 @@ class Rule {
|
||||
|
||||
class TransactionOutPointWithValue {
|
||||
public TransactionOutPoint outpoint;
|
||||
public BigInteger value;
|
||||
public Coin value;
|
||||
Script scriptPubKey;
|
||||
public TransactionOutPointWithValue(TransactionOutPoint outpoint, BigInteger value, Script scriptPubKey) {
|
||||
public TransactionOutPointWithValue(TransactionOutPoint outpoint, Coin value, Script scriptPubKey) {
|
||||
this.outpoint = outpoint;
|
||||
this.value = value;
|
||||
this.scriptPubKey = scriptPubKey;
|
||||
@ -217,7 +217,7 @@ public class FullBlockTestGenerator {
|
||||
// \-> b9 (4)
|
||||
// \-> b3 (1) -> b4 (2)
|
||||
//
|
||||
Block b9 = createNextBlock(b6, chainHeadHeight + 5, out4, BigInteger.valueOf(1));
|
||||
Block b9 = createNextBlock(b6, chainHeadHeight + 5, out4, Coin.valueOf(1));
|
||||
blocks.add(new BlockAndValidity(blockToHeightMap, b9, false, true, b6.getHash(), chainHeadHeight + 4, "b9"));
|
||||
|
||||
// Create a fork that ends in a block with too much fee (the one that causes the reorg)
|
||||
@ -228,7 +228,7 @@ public class FullBlockTestGenerator {
|
||||
Block b10 = createNextBlock(b5, chainHeadHeight + 4, out3, null);
|
||||
blocks.add(new BlockAndValidity(blockToHeightMap, b10, true, false, b6.getHash(), chainHeadHeight + 4, "b10"));
|
||||
|
||||
Block b11 = createNextBlock(b10, chainHeadHeight + 5, out4, BigInteger.valueOf(1));
|
||||
Block b11 = createNextBlock(b10, chainHeadHeight + 5, out4, Coin.valueOf(1));
|
||||
blocks.add(new BlockAndValidity(blockToHeightMap, b11, false, true, b6.getHash(), chainHeadHeight + 4, "b11"));
|
||||
|
||||
// Try again, but with a valid fork first
|
||||
@ -254,7 +254,7 @@ public class FullBlockTestGenerator {
|
||||
|
||||
TransactionOutPointWithValue out5 = spendableOutputs.poll();
|
||||
|
||||
Block b14 = createNextBlock(b13, chainHeadHeight + 6, out5, BigInteger.valueOf(1));
|
||||
Block b14 = createNextBlock(b13, chainHeadHeight + 6, out5, Coin.valueOf(1));
|
||||
// This will be "validly" added, though its actually invalid, it will just be marked orphan
|
||||
// and will be discarded when an attempt is made to reorg to it.
|
||||
// TODO: Use a WeakReference to check that it is freed properly after the reorg
|
||||
@ -278,10 +278,10 @@ public class FullBlockTestGenerator {
|
||||
Transaction tx = new Transaction(params);
|
||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps];
|
||||
Arrays.fill(outputScript, (byte) OP_CHECKSIG);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b15.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b15.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b15.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b15.addTransaction(tx);
|
||||
}
|
||||
b15.solve();
|
||||
@ -303,10 +303,10 @@ public class FullBlockTestGenerator {
|
||||
Transaction tx = new Transaction(params);
|
||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps + 1];
|
||||
Arrays.fill(outputScript, (byte) OP_CHECKSIG);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b16.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b16.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b16.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b16.addTransaction(tx);
|
||||
}
|
||||
b16.solve();
|
||||
@ -321,10 +321,10 @@ public class FullBlockTestGenerator {
|
||||
Block b17 = createNextBlock(b15, chainHeadHeight + 7, out6, null);
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {}));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b3.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b3.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b3.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b17.addTransaction(tx);
|
||||
}
|
||||
b17.solve();
|
||||
@ -339,10 +339,10 @@ public class FullBlockTestGenerator {
|
||||
Block b18 = createNextBlock(b13, chainHeadHeight + 6, out5, null);
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {}));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b3.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b3.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b3.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b18.addTransaction(tx);
|
||||
}
|
||||
b18.solve();
|
||||
@ -384,10 +384,10 @@ public class FullBlockTestGenerator {
|
||||
// Signature size is non-deterministic, so it may take several runs before finding any off-by-one errors
|
||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIZE - b23.getMessageSize() - 138];
|
||||
Arrays.fill(outputScript, (byte) OP_FALSE);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b23.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b23.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b23.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b23.addTransaction(tx);
|
||||
}
|
||||
b23.solve();
|
||||
@ -403,10 +403,10 @@ public class FullBlockTestGenerator {
|
||||
// Signature size is non-deterministic, so it may take several runs before finding any off-by-one errors
|
||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIZE - b24.getMessageSize() - 135];
|
||||
Arrays.fill(outputScript, (byte) OP_FALSE);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b24.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b24.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b24.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b24.addTransaction(tx);
|
||||
}
|
||||
b24.solve();
|
||||
@ -479,10 +479,10 @@ public class FullBlockTestGenerator {
|
||||
Transaction tx = new Transaction(params);
|
||||
byte[] outputScript = new byte[(Block.MAX_BLOCK_SIGOPS - sigOps)/20];
|
||||
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIG);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b31.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b31.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b31.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b31.addTransaction(tx);
|
||||
}
|
||||
b31.solve();
|
||||
@ -506,10 +506,10 @@ public class FullBlockTestGenerator {
|
||||
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIG);
|
||||
for (int i = 0; i < (Block.MAX_BLOCK_SIGOPS - sigOps)%20; i++)
|
||||
outputScript[i] = (byte) OP_CHECKSIG;
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b32.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b32.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b32.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b32.addTransaction(tx);
|
||||
}
|
||||
b32.solve();
|
||||
@ -526,10 +526,10 @@ public class FullBlockTestGenerator {
|
||||
Transaction tx = new Transaction(params);
|
||||
byte[] outputScript = new byte[(Block.MAX_BLOCK_SIGOPS - sigOps)/20];
|
||||
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIGVERIFY);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b33.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b33.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b33.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b33.addTransaction(tx);
|
||||
}
|
||||
b33.solve();
|
||||
@ -553,10 +553,10 @@ public class FullBlockTestGenerator {
|
||||
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIGVERIFY);
|
||||
for (int i = 0; i < (Block.MAX_BLOCK_SIGOPS - sigOps)%20; i++)
|
||||
outputScript[i] = (byte) OP_CHECKSIG;
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b34.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b34.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b34.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b34.addTransaction(tx);
|
||||
}
|
||||
b34.solve();
|
||||
@ -573,10 +573,10 @@ public class FullBlockTestGenerator {
|
||||
Transaction tx = new Transaction(params);
|
||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps];
|
||||
Arrays.fill(outputScript, (byte) OP_CHECKSIGVERIFY);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b35.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b35.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b35.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b35.addTransaction(tx);
|
||||
}
|
||||
b35.solve();
|
||||
@ -598,10 +598,10 @@ public class FullBlockTestGenerator {
|
||||
Transaction tx = new Transaction(params);
|
||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps + 1];
|
||||
Arrays.fill(outputScript, (byte) OP_CHECKSIGVERIFY);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b36.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b36.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b36.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b36.addTransaction(tx);
|
||||
}
|
||||
b36.solve();
|
||||
@ -618,7 +618,7 @@ public class FullBlockTestGenerator {
|
||||
Block b37 = createNextBlock(b35, chainHeadHeight + 12, out11, null);
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {}));
|
||||
addOnlyInputToTransaction(tx, out11); // double spend out11
|
||||
b37.addTransaction(tx);
|
||||
}
|
||||
@ -628,11 +628,11 @@ public class FullBlockTestGenerator {
|
||||
Block b38 = createNextBlock(b35, chainHeadHeight + 12, out11, null);
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {}));
|
||||
// Attempt to spend b37's first non-coinbase tx, at which point b37 was still considered valid
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b37.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b37.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b37.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b38.addTransaction(tx);
|
||||
}
|
||||
b38.solve();
|
||||
@ -676,11 +676,11 @@ public class FullBlockTestGenerator {
|
||||
}
|
||||
scriptPubKey.write(OP_EQUAL);
|
||||
|
||||
BigInteger lastOutputValue = out11.value.subtract(BigInteger.valueOf(1));
|
||||
Coin lastOutputValue = out11.value.subtract(Coin.valueOf(1));
|
||||
TransactionOutPoint lastOutPoint;
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), scriptPubKey.toByteArray()));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), scriptPubKey.toByteArray()));
|
||||
tx.addOutput(new TransactionOutput(params, tx, lastOutputValue, new byte[]{OP_1}));
|
||||
addOnlyInputToTransaction(tx, out11);
|
||||
lastOutPoint = new TransactionOutPoint(params, 1, tx.getHash());
|
||||
@ -692,8 +692,8 @@ public class FullBlockTestGenerator {
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
|
||||
lastOutputValue = lastOutputValue.subtract(BigInteger.valueOf(1));
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), scriptPubKey.toByteArray()));
|
||||
lastOutputValue = lastOutputValue.subtract(Coin.valueOf(1));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), scriptPubKey.toByteArray()));
|
||||
tx.addOutput(new TransactionOutput(params, tx, lastOutputValue, new byte[]{OP_1}));
|
||||
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_1}, lastOutPoint));
|
||||
lastOutPoint = new TransactionOutPoint(params, 1, tx.getHash());
|
||||
@ -729,7 +729,7 @@ public class FullBlockTestGenerator {
|
||||
byte[] scriptSig = null;
|
||||
for (int i = 1; i <= numTxes; i++) {
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {OP_1}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {OP_1}));
|
||||
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_1}, lastOutPoint));
|
||||
|
||||
TransactionInput input = new TransactionInput(params, tx, new byte[]{},
|
||||
@ -770,7 +770,7 @@ public class FullBlockTestGenerator {
|
||||
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_1}, lastOutPoint));
|
||||
byte[] scriptPubKey = new byte[Block.MAX_BLOCK_SIGOPS - sigOps + 1];
|
||||
Arrays.fill(scriptPubKey, (byte) OP_CHECKSIG);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, scriptPubKey));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, scriptPubKey));
|
||||
b40.addTransaction(tx);
|
||||
}
|
||||
b40.solve();
|
||||
@ -795,7 +795,7 @@ public class FullBlockTestGenerator {
|
||||
byte[] scriptSig = null;
|
||||
for (int i = 1; i <= numTxes; i++) {
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin
|
||||
.valueOf(1), new byte[] {OP_1}));
|
||||
tx.addInput(new TransactionInput(params, tx,
|
||||
new byte[] {OP_1}, lastOutPoint));
|
||||
@ -847,7 +847,7 @@ public class FullBlockTestGenerator {
|
||||
new byte[] {OP_1}, lastOutPoint));
|
||||
byte[] scriptPubKey = new byte[Block.MAX_BLOCK_SIGOPS - sigOps];
|
||||
Arrays.fill(scriptPubKey, (byte) OP_CHECKSIG);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, scriptPubKey));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, scriptPubKey));
|
||||
b41.addTransaction(tx);
|
||||
}
|
||||
b41.solve();
|
||||
@ -885,14 +885,14 @@ public class FullBlockTestGenerator {
|
||||
byte[] outScriptBytes = ScriptBuilder.createOutputScript(ECKey.fromPublicOnly(coinbaseOutKeyPubKey)).getProgram();
|
||||
{
|
||||
b44.setDifficultyTarget(b43.getDifficultyTarget());
|
||||
b44.addCoinbaseTransaction(coinbaseOutKeyPubKey, BigInteger.ZERO);
|
||||
b44.addCoinbaseTransaction(coinbaseOutKeyPubKey, Coin.ZERO);
|
||||
|
||||
Transaction t = new Transaction(params);
|
||||
// Entirely invalid scriptPubKey to ensure we aren't pre-verifying too much
|
||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(1), outScriptBytes));
|
||||
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
||||
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(1), outScriptBytes));
|
||||
// Spendable output
|
||||
t.addOutput(new TransactionOutput(params, t, BigInteger.ZERO, new byte[] {OP_1}));
|
||||
t.addOutput(new TransactionOutput(params, t, Coin.ZERO, new byte[] {OP_1}));
|
||||
addOnlyInputToTransaction(t, out14);
|
||||
b44.addTransaction(t);
|
||||
|
||||
@ -912,10 +912,10 @@ public class FullBlockTestGenerator {
|
||||
|
||||
Transaction t = new Transaction(params);
|
||||
// Entirely invalid scriptPubKey to ensure we aren't pre-verifying too much
|
||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(1), outScriptBytes));
|
||||
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
||||
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(1), outScriptBytes));
|
||||
// Spendable output
|
||||
t.addOutput(new TransactionOutput(params, t, BigInteger.ZERO, new byte[] {OP_1}));
|
||||
t.addOutput(new TransactionOutput(params, t, Coin.ZERO, new byte[] {OP_1}));
|
||||
addOnlyInputToTransaction(t, out15);
|
||||
try {
|
||||
b45.addTransaction(t);
|
||||
@ -989,7 +989,7 @@ public class FullBlockTestGenerator {
|
||||
{
|
||||
Transaction coinbase = new Transaction(params);
|
||||
coinbase.addInput(new TransactionInput(params, coinbase, new byte[]{(byte) 0xff, 110, 1}));
|
||||
coinbase.addOutput(new TransactionOutput(params, coinbase, BigInteger.ONE, outScriptBytes));
|
||||
coinbase.addOutput(new TransactionOutput(params, coinbase, Coin.ONE, outScriptBytes));
|
||||
b51.addTransaction(coinbase, false);
|
||||
}
|
||||
b51.solve();
|
||||
@ -999,10 +999,10 @@ public class FullBlockTestGenerator {
|
||||
Block b52 = createNextBlock(b44, chainHeadHeight + 16, out15, null);
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {}));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b52.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b52.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b52.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b52.addTransaction(tx);
|
||||
b52.addTransaction(tx);
|
||||
}
|
||||
@ -1047,10 +1047,10 @@ public class FullBlockTestGenerator {
|
||||
Transaction b56txToDuplicate;
|
||||
{
|
||||
b56txToDuplicate = new Transaction(params);
|
||||
b56txToDuplicate.addOutput(new TransactionOutput(params, b56txToDuplicate, BigInteger.valueOf(1), new byte[] {}));
|
||||
b56txToDuplicate.addOutput(new TransactionOutput(params, b56txToDuplicate, Coin.valueOf(1), new byte[] {}));
|
||||
addOnlyInputToTransaction(b56txToDuplicate, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b57.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b57.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b57.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b57.addTransaction(b56txToDuplicate);
|
||||
}
|
||||
b57.solve();
|
||||
@ -1081,7 +1081,7 @@ public class FullBlockTestGenerator {
|
||||
Block b58 = createNextBlock(b57, chainHeadHeight + 18, out17, null);
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] {}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] {}));
|
||||
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_1},
|
||||
new TransactionOutPoint(params, 3, b58.getTransactions().get(1).getHash())));
|
||||
b58.addTransaction(tx);
|
||||
@ -1094,7 +1094,7 @@ public class FullBlockTestGenerator {
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx,
|
||||
b59.getTransactions().get(1).getOutputs().get(2).getValue().add(BigInteger.ONE), new byte[] {}));
|
||||
b59.getTransactions().get(1).getOutputs().get(2).getValue().add(Coin.ONE), new byte[] {}));
|
||||
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_1},
|
||||
new TransactionOutPoint(params, 2, b59.getTransactions().get(1).getHash())));
|
||||
b59.addTransaction(tx);
|
||||
@ -1132,7 +1132,7 @@ public class FullBlockTestGenerator {
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.setLockTime(0xffffffffL);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] {OP_TRUE}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] {OP_TRUE}));
|
||||
addOnlyInputToTransaction(tx, out18, 0);
|
||||
b62.addTransaction(tx);
|
||||
Preconditions.checkState(!tx.isFinal(chainHeadHeight + 17, b62.getTimeSeconds()));
|
||||
@ -1164,10 +1164,10 @@ public class FullBlockTestGenerator {
|
||||
// Signature size is non-deterministic, so it may take several runs before finding any off-by-one errors
|
||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIZE - b64Created.getMessageSize() - 138];
|
||||
Arrays.fill(outputScript, (byte) OP_FALSE);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b64Created.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b64Created.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b64Created.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b64Created.addTransaction(tx);
|
||||
b64Created.solve();
|
||||
|
||||
@ -1210,7 +1210,7 @@ public class FullBlockTestGenerator {
|
||||
addOnlyInputToTransaction(tx1, out19, 0);
|
||||
b65.addTransaction(tx1);
|
||||
Transaction tx2 = new Transaction(params);
|
||||
tx2.addOutput(new TransactionOutput(params, tx2, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
||||
tx2.addOutput(new TransactionOutput(params, tx2, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||
tx2.addInput(new TransactionInput(params, tx2, new byte[]{OP_TRUE},
|
||||
new TransactionOutPoint(params, 0, tx1.getHash())));
|
||||
b65.addTransaction(tx2);
|
||||
@ -1234,7 +1234,7 @@ public class FullBlockTestGenerator {
|
||||
tx1.addOutput(new TransactionOutput(params, tx1, out20.value, new byte[]{OP_TRUE}));
|
||||
addOnlyInputToTransaction(tx1, out20, 0);
|
||||
Transaction tx2 = new Transaction(params);
|
||||
tx2.addOutput(new TransactionOutput(params, tx2, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
||||
tx2.addOutput(new TransactionOutput(params, tx2, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||
tx2.addInput(new TransactionInput(params, tx2, new byte[]{OP_TRUE},
|
||||
new TransactionOutPoint(params, 0, tx1.getHash())));
|
||||
b66.addTransaction(tx2);
|
||||
@ -1254,7 +1254,7 @@ public class FullBlockTestGenerator {
|
||||
addOnlyInputToTransaction(tx1, out20, 0);
|
||||
b67.addTransaction(tx1);
|
||||
Transaction tx2 = new Transaction(params);
|
||||
tx2.addOutput(new TransactionOutput(params, tx2, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
||||
tx2.addOutput(new TransactionOutput(params, tx2, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||
tx2.addInput(new TransactionInput(params, tx2, new byte[]{OP_TRUE},
|
||||
new TransactionOutPoint(params, 0, tx1.getHash())));
|
||||
b67.addTransaction(tx2);
|
||||
@ -1271,20 +1271,20 @@ public class FullBlockTestGenerator {
|
||||
// -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20)
|
||||
// \-> b68 (20)
|
||||
//
|
||||
Block b68 = createNextBlock(b65, chainHeadHeight + 21, null, BigInteger.TEN);
|
||||
Block b68 = createNextBlock(b65, chainHeadHeight + 21, null, Coin.TEN);
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, out20.value.subtract(BigInteger.valueOf(9)), new byte[]{OP_TRUE}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, out20.value.subtract(Coin.valueOf(9)), new byte[]{OP_TRUE}));
|
||||
addOnlyInputToTransaction(tx, out20, 0);
|
||||
b68.addTransaction(tx);
|
||||
}
|
||||
b68.solve();
|
||||
blocks.add(new BlockAndValidity(blockToHeightMap, b68, false, true, b65.getHash(), chainHeadHeight + 20, "b68"));
|
||||
|
||||
Block b69 = createNextBlock(b65, chainHeadHeight + 21, null, BigInteger.TEN);
|
||||
Block b69 = createNextBlock(b65, chainHeadHeight + 21, null, Coin.TEN);
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, out20.value.subtract(BigInteger.TEN), new byte[]{OP_TRUE}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, out20.value.subtract(Coin.TEN), new byte[]{OP_TRUE}));
|
||||
addOnlyInputToTransaction(tx, out20, 0);
|
||||
b69.addTransaction(tx);
|
||||
}
|
||||
@ -1304,7 +1304,7 @@ public class FullBlockTestGenerator {
|
||||
Block b70 = createNextBlock(b69, chainHeadHeight + 22, out21, null);
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_TRUE},
|
||||
new TransactionOutPoint(params, 0, new Sha256Hash("23c70ed7c0506e9178fc1a987f40a33946d4ad4c962b5ae3a52546da53af0c5c"))));
|
||||
b70.addTransaction(tx);
|
||||
@ -1319,10 +1319,10 @@ public class FullBlockTestGenerator {
|
||||
Block b72 = createNextBlock(b69, chainHeadHeight + 22, out21, null);
|
||||
{
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b72.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b72.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b72.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b72.addTransaction(tx);
|
||||
}
|
||||
b72.solve();
|
||||
@ -1356,10 +1356,10 @@ public class FullBlockTestGenerator {
|
||||
// If we push an element that is too large, the CHECKSIGs after that push are still counted
|
||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps] = OP_PUSHDATA4;
|
||||
Utils.uint32ToByteArrayLE(Script.MAX_SCRIPT_ELEMENT_SIZE + 1, outputScript, Block.MAX_BLOCK_SIGOPS - sigOps + 1);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b73.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b73.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b73.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b73.addTransaction(tx);
|
||||
}
|
||||
b73.solve();
|
||||
@ -1380,10 +1380,10 @@ public class FullBlockTestGenerator {
|
||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 3] = (byte)0xff;
|
||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 4] = (byte)0xff;
|
||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 5] = (byte)0xff;
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b74.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b74.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b74.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b74.addTransaction(tx);
|
||||
}
|
||||
b74.solve();
|
||||
@ -1404,10 +1404,10 @@ public class FullBlockTestGenerator {
|
||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 2] = (byte)0xff;
|
||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 3] = (byte)0xff;
|
||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 4] = (byte)0xff;
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b75.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b75.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b75.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b75.addTransaction(tx);
|
||||
}
|
||||
b75.solve();
|
||||
@ -1431,10 +1431,10 @@ public class FullBlockTestGenerator {
|
||||
// If we push an element that is filled with CHECKSIGs, they (obviously) arent counted
|
||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps] = OP_PUSHDATA4;
|
||||
Utils.uint32ToByteArrayLE(Block.MAX_BLOCK_SIGOPS, outputScript, Block.MAX_BLOCK_SIGOPS - sigOps + 1);
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b76.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b76.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b76.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b76.addTransaction(tx);
|
||||
}
|
||||
b76.solve();
|
||||
@ -1460,10 +1460,10 @@ public class FullBlockTestGenerator {
|
||||
Block b78 = createNextBlock(b77, chainHeadHeight + 26, out25, null);
|
||||
Transaction b78tx = new Transaction(params);
|
||||
{
|
||||
b78tx.addOutput(new TransactionOutput(params, b78tx, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
||||
b78tx.addOutput(new TransactionOutput(params, b78tx, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||
addOnlyInputToTransaction(b78tx, new TransactionOutPointWithValue(
|
||||
new TransactionOutPoint(params, 1, b77.getTransactions().get(1).getHash()),
|
||||
BigInteger.valueOf(1), b77.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
Coin.valueOf(1), b77.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||
b78.addTransaction(b78tx);
|
||||
}
|
||||
b78.solve();
|
||||
@ -1472,7 +1472,7 @@ public class FullBlockTestGenerator {
|
||||
Block b79 = createNextBlock(b78, chainHeadHeight + 27, out26, null);
|
||||
Transaction b79tx = new Transaction(params);
|
||||
{
|
||||
b79tx.addOutput(new TransactionOutput(params, b79tx, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
||||
b79tx.addOutput(new TransactionOutput(params, b79tx, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||
b79tx.addInput(new TransactionInput(params, b79tx, new byte[]{OP_TRUE}, new TransactionOutPoint(params, 0, b78tx.getHash())));
|
||||
b79.addTransaction(b79tx);
|
||||
}
|
||||
@ -1541,8 +1541,8 @@ public class FullBlockTestGenerator {
|
||||
while (block.getMessageSize() < Block.MAX_BLOCK_SIZE - 500) {
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addInput(new TransactionInput(params, tx, new byte[] { OP_TRUE }, lastOutput));
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] { OP_TRUE }));
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] { OP_TRUE }));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] { OP_TRUE }));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] { OP_TRUE }));
|
||||
lastOutput = new TransactionOutPoint(params, 1, tx.getHash());
|
||||
hashesToSpend.add(tx.getHash());
|
||||
block.addTransaction(tx);
|
||||
@ -1560,7 +1560,7 @@ public class FullBlockTestGenerator {
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addInput(new TransactionInput(params, tx, new byte[] { OP_TRUE },
|
||||
new TransactionOutPoint(params, 0, hashes.next())));
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] { OP_TRUE }));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] { OP_TRUE }));
|
||||
block.addTransaction(tx);
|
||||
}
|
||||
block.solve();
|
||||
@ -1586,7 +1586,7 @@ public class FullBlockTestGenerator {
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_TRUE},
|
||||
new TransactionOutPoint(params, 0, hashesToSpend.get(0))));
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] { OP_TRUE }));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] { OP_TRUE }));
|
||||
b1002.addTransaction(tx);
|
||||
}
|
||||
b1002.solve();
|
||||
@ -1602,7 +1602,7 @@ public class FullBlockTestGenerator {
|
||||
Transaction tx = new Transaction(params);
|
||||
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_TRUE},
|
||||
new TransactionOutPoint(params, 0, hashesToSpend.get(0))));
|
||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] { OP_TRUE }));
|
||||
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] { OP_TRUE }));
|
||||
b1004.addTransaction(tx);
|
||||
}
|
||||
b1004.solve();
|
||||
@ -1620,22 +1620,22 @@ public class FullBlockTestGenerator {
|
||||
|
||||
private byte uniquenessCounter = 0;
|
||||
private Block createNextBlock(Block baseBlock, int nextBlockHeight, TransactionOutPointWithValue prevOut,
|
||||
BigInteger additionalCoinbaseValue) throws ScriptException {
|
||||
Coin additionalCoinbaseValue) throws ScriptException {
|
||||
Integer height = blockToHeightMap.get(baseBlock.getHash());
|
||||
if (height != null)
|
||||
Preconditions.checkState(height == nextBlockHeight - 1);
|
||||
BigInteger coinbaseValue = Utils.toNanoCoins(50, 0).shiftRight(nextBlockHeight / params.getSubsidyDecreaseBlockCount())
|
||||
.add((prevOut != null ? prevOut.value.subtract(BigInteger.ONE) : BigInteger.ZERO))
|
||||
.add(additionalCoinbaseValue == null ? BigInteger.ZERO : additionalCoinbaseValue);
|
||||
Coin coinbaseValue = Utils.toNanoCoins(50, 0).shiftRight(nextBlockHeight / params.getSubsidyDecreaseBlockCount())
|
||||
.add((prevOut != null ? prevOut.value.subtract(Coin.ONE) : Coin.ZERO))
|
||||
.add(additionalCoinbaseValue == null ? Coin.ZERO : additionalCoinbaseValue);
|
||||
Block block = baseBlock.createNextBlockWithCoinbase(coinbaseOutKeyPubKey, coinbaseValue);
|
||||
if (prevOut != null) {
|
||||
Transaction t = new Transaction(params);
|
||||
// Entirely invalid scriptPubKey to ensure we aren't pre-verifying too much
|
||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(1),
|
||||
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
||||
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(1),
|
||||
ScriptBuilder.createOutputScript(ECKey.fromPublicOnly(coinbaseOutKeyPubKey)).getProgram()));
|
||||
// Spendable output
|
||||
t.addOutput(new TransactionOutput(params, t, BigInteger.ZERO, new byte[] {OP_1, uniquenessCounter++}));
|
||||
t.addOutput(new TransactionOutput(params, t, Coin.ZERO, new byte[] {OP_1, uniquenessCounter++}));
|
||||
addOnlyInputToTransaction(t, prevOut);
|
||||
block.addTransaction(t);
|
||||
block.solve();
|
||||
|
@ -34,7 +34,6 @@ import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.junit.runners.Parameterized;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
@ -179,7 +178,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
||||
expectedPeers.add(peerOf(p2));
|
||||
assertEquals(tmp, expectedPeers);
|
||||
|
||||
BigInteger value = Utils.toNanoCoins(1, 0);
|
||||
Coin value = Utils.toNanoCoins(1, 0);
|
||||
Transaction t1 = FakeTxBuilder.createFakeTx(unitTestParams, value, address);
|
||||
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
||||
inv.addTransaction(t1);
|
||||
|
@ -34,7 +34,6 @@ import org.junit.runners.Parameterized;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketException;
|
||||
import java.nio.channels.CancelledKeyException;
|
||||
@ -245,7 +244,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
|
||||
peer.setDownloadData(true);
|
||||
// Make a transaction and tell the peer we have it.
|
||||
BigInteger value = Utils.toNanoCoins(1, 0);
|
||||
Coin value = Utils.toNanoCoins(1, 0);
|
||||
Transaction tx = createFakeTx(unitTestParams, value, address);
|
||||
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
||||
InventoryItem item = new InventoryItem(InventoryItem.Type.Transaction, tx.getHash());
|
||||
@ -278,7 +277,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
InboundMessageQueuer writeTarget2 = connect(peer2, peerVersion);
|
||||
|
||||
// Make a tx and advertise it to one of the peers.
|
||||
BigInteger value = Utils.toNanoCoins(1, 0);
|
||||
Coin value = Utils.toNanoCoins(1, 0);
|
||||
Transaction tx = createFakeTx(unitTestParams, value, this.address);
|
||||
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
||||
InventoryItem item = new InventoryItem(InventoryItem.Type.Transaction, tx.getHash());
|
||||
@ -418,7 +417,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
Block b2 = makeSolvedTestBlock(b1);
|
||||
Transaction t = new Transaction(unitTestParams);
|
||||
t.addInput(b1.getTransactions().get(0).getOutput(0));
|
||||
t.addOutput(new TransactionOutput(unitTestParams, t, BigInteger.ZERO, new byte[Block.MAX_BLOCK_SIZE - 1000]));
|
||||
t.addOutput(new TransactionOutput(unitTestParams, t, Coin.ZERO, new byte[Block.MAX_BLOCK_SIZE - 1000]));
|
||||
b2.addTransaction(t);
|
||||
|
||||
// Request the block.
|
||||
@ -659,7 +658,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
final Transaction[] vtx = new Transaction[1];
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
vtx[0] = tx;
|
||||
}
|
||||
});
|
||||
@ -732,7 +731,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
final Transaction[] vtx = new Transaction[1];
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
vtx[0] = tx;
|
||||
}
|
||||
});
|
||||
@ -817,7 +816,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
||||
public void exceptionListener() throws Exception {
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
throw new NullPointerException("boo!");
|
||||
}
|
||||
});
|
||||
|
@ -16,11 +16,10 @@
|
||||
|
||||
package com.google.bitcoin.core;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import static com.google.bitcoin.core.Utils.*;
|
||||
import static org.junit.Assert.*;
|
||||
|
||||
@ -59,7 +58,7 @@ public class UtilsTest {
|
||||
public void testFormatting() {
|
||||
assertEquals("1.00", bitcoinValueToFriendlyString(toNanoCoins(1, 0)));
|
||||
assertEquals("1.23", bitcoinValueToFriendlyString(toNanoCoins(1, 23)));
|
||||
assertEquals("0.001", bitcoinValueToFriendlyString(BigInteger.valueOf(COIN.longValue() / 1000)));
|
||||
assertEquals("0.001", bitcoinValueToFriendlyString(Coin.valueOf(COIN.longValue() / 1000)));
|
||||
assertEquals("-1.23", bitcoinValueToFriendlyString(toNanoCoins(1, 23).negate()));
|
||||
}
|
||||
|
||||
@ -76,7 +75,7 @@ public class UtilsTest {
|
||||
assertTrue(e.getMessage().contains("Value cannot be null"));
|
||||
}
|
||||
|
||||
assertEquals("0.0015", bitcoinValueToPlainString(BigInteger.valueOf(150000)));
|
||||
assertEquals("0.0015", bitcoinValueToPlainString(Coin.valueOf(150000)));
|
||||
assertEquals("1.23", bitcoinValueToPlainString(toNanoCoins("1.23")));
|
||||
|
||||
assertEquals("0.1", bitcoinValueToPlainString(toNanoCoins("0.1")));
|
||||
|
@ -152,7 +152,7 @@ public class WalletTest extends TestWithWallet {
|
||||
private Transaction cleanupCommon(Address destination) throws Exception {
|
||||
receiveATransaction(wallet, myAddress);
|
||||
|
||||
BigInteger v2 = toNanoCoins(0, 50);
|
||||
Coin v2 = toNanoCoins(0, 50);
|
||||
SendRequest req = SendRequest.to(destination, v2);
|
||||
req.fee = toNanoCoins(0, 1);
|
||||
wallet.completeTx(req);
|
||||
@ -164,7 +164,7 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
// At this point we have one pending and one spent
|
||||
|
||||
BigInteger v1 = toNanoCoins(0, 10);
|
||||
Coin v1 = toNanoCoins(0, 10);
|
||||
Transaction t = sendMoneyToWallet(wallet, v1, myAddress, null);
|
||||
Threading.waitForUserCode();
|
||||
sendMoneyToWallet(wallet, t, null);
|
||||
@ -199,7 +199,7 @@ public class WalletTest extends TestWithWallet {
|
||||
Transaction t = cleanupCommon(destination);
|
||||
|
||||
// Now we have another incoming pending. Spend everything.
|
||||
BigInteger v3 = toNanoCoins(0, 58);
|
||||
Coin v3 = toNanoCoins(0, 58);
|
||||
SendRequest req = SendRequest.to(destination, v3);
|
||||
|
||||
// Force selection of the incoming coin so that we can spend it
|
||||
@ -235,7 +235,7 @@ public class WalletTest extends TestWithWallet {
|
||||
receiveATransaction(wallet, toAddress);
|
||||
|
||||
// Try to send too much and fail.
|
||||
BigInteger vHuge = toNanoCoins(10, 0);
|
||||
Coin vHuge = toNanoCoins(10, 0);
|
||||
Wallet.SendRequest req = Wallet.SendRequest.to(destination, vHuge);
|
||||
try {
|
||||
wallet.completeTx(req);
|
||||
@ -245,7 +245,7 @@ public class WalletTest extends TestWithWallet {
|
||||
}
|
||||
|
||||
// Prepare to send.
|
||||
BigInteger v2 = toNanoCoins(0, 50);
|
||||
Coin v2 = toNanoCoins(0, 50);
|
||||
req = Wallet.SendRequest.to(destination, v2);
|
||||
req.fee = toNanoCoins(0, 1);
|
||||
|
||||
@ -306,9 +306,9 @@ public class WalletTest extends TestWithWallet {
|
||||
}
|
||||
|
||||
private void receiveATransaction(Wallet wallet, Address toAddress) throws Exception {
|
||||
BigInteger v1 = Utils.toNanoCoins(1, 0);
|
||||
final ListenableFuture<BigInteger> availFuture = wallet.getBalanceFuture(v1, Wallet.BalanceType.AVAILABLE);
|
||||
final ListenableFuture<BigInteger> estimatedFuture = wallet.getBalanceFuture(v1, Wallet.BalanceType.ESTIMATED);
|
||||
Coin v1 = Utils.toNanoCoins(1, 0);
|
||||
final ListenableFuture<Coin> availFuture = wallet.getBalanceFuture(v1, Wallet.BalanceType.AVAILABLE);
|
||||
final ListenableFuture<Coin> estimatedFuture = wallet.getBalanceFuture(v1, Wallet.BalanceType.ESTIMATED);
|
||||
assertFalse(availFuture.isDone());
|
||||
assertFalse(estimatedFuture.isDone());
|
||||
// Send some pending coins to the wallet.
|
||||
@ -316,7 +316,7 @@ public class WalletTest extends TestWithWallet {
|
||||
Threading.waitForUserCode();
|
||||
final ListenableFuture<Transaction> depthFuture = t1.getConfidence().getDepthFuture(1);
|
||||
assertFalse(depthFuture.isDone());
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(v1, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||
assertFalse(availFuture.isDone());
|
||||
// Our estimated balance has reached the requested level.
|
||||
@ -352,7 +352,7 @@ public class WalletTest extends TestWithWallet {
|
||||
final LinkedList<Transaction> txns = Lists.newLinkedList();
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
txns.add(tx);
|
||||
}
|
||||
});
|
||||
@ -369,7 +369,7 @@ public class WalletTest extends TestWithWallet {
|
||||
}
|
||||
|
||||
private void spendUnconfirmedChange(Wallet wallet, Transaction t2, KeyParameter aesKey) throws Exception {
|
||||
BigInteger v3 = toNanoCoins(0, 49);
|
||||
Coin v3 = toNanoCoins(0, 49);
|
||||
assertEquals(v3, wallet.getBalance());
|
||||
Wallet.SendRequest req = Wallet.SendRequest.to(new ECKey().toAddress(params), toNanoCoins(0, 48));
|
||||
req.aesKey = aesKey;
|
||||
@ -395,7 +395,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// Having a test for deprecated method getFromAddress() is no evil so we suppress the warning here.
|
||||
public void customTransactionSpending() throws Exception {
|
||||
// We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
|
||||
BigInteger v1 = Utils.toNanoCoins(3, 0);
|
||||
Coin v1 = Utils.toNanoCoins(3, 0);
|
||||
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
assertEquals(v1, wallet.getBalance());
|
||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||
@ -403,9 +403,9 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
ECKey k2 = new ECKey();
|
||||
Address a2 = k2.toAddress(params);
|
||||
BigInteger v2 = toNanoCoins(0, 50);
|
||||
BigInteger v3 = toNanoCoins(0, 75);
|
||||
BigInteger v4 = toNanoCoins(1, 25);
|
||||
Coin v2 = toNanoCoins(0, 50);
|
||||
Coin v3 = toNanoCoins(0, 75);
|
||||
Coin v4 = toNanoCoins(1, 25);
|
||||
|
||||
Transaction t2 = new Transaction(params);
|
||||
t2.addOutput(v2, a2);
|
||||
@ -431,13 +431,13 @@ public class WalletTest extends TestWithWallet {
|
||||
public void sideChain() throws Exception {
|
||||
// The wallet receives a coin on the main chain, then on a side chain. Balance is equal to both added together
|
||||
// as we assume the side chain tx is pending and will be included shortly.
|
||||
BigInteger v1 = Utils.toNanoCoins(1, 0);
|
||||
Coin v1 = Utils.toNanoCoins(1, 0);
|
||||
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
assertEquals(v1, wallet.getBalance());
|
||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||
assertEquals(1, wallet.getTransactions(true).size());
|
||||
|
||||
BigInteger v2 = toNanoCoins(0, 50);
|
||||
Coin v2 = toNanoCoins(0, 50);
|
||||
sendMoneyToWallet(v2, AbstractBlockChain.NewBlockType.SIDE_CHAIN);
|
||||
assertEquals(2, wallet.getTransactions(true).size());
|
||||
assertEquals(v1, wallet.getBalance());
|
||||
@ -447,9 +447,9 @@ public class WalletTest extends TestWithWallet {
|
||||
@Test
|
||||
public void balance() throws Exception {
|
||||
// Receive 5 coins then half a coin.
|
||||
BigInteger v1 = toNanoCoins(5, 0);
|
||||
BigInteger v2 = toNanoCoins(0, 50);
|
||||
BigInteger expected = toNanoCoins(5, 50);
|
||||
Coin v1 = toNanoCoins(5, 0);
|
||||
Coin v2 = toNanoCoins(0, 50);
|
||||
Coin expected = toNanoCoins(5, 50);
|
||||
assertEquals(0, wallet.getTransactions(true).size());
|
||||
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||
@ -458,7 +458,7 @@ public class WalletTest extends TestWithWallet {
|
||||
assertEquals(expected, wallet.getBalance());
|
||||
|
||||
// Now spend one coin.
|
||||
BigInteger v3 = toNanoCoins(1, 0);
|
||||
Coin v3 = toNanoCoins(1, 0);
|
||||
Transaction spend = wallet.createSend(new ECKey().toAddress(params), v3);
|
||||
wallet.commitTx(spend);
|
||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
|
||||
@ -474,7 +474,7 @@ public class WalletTest extends TestWithWallet {
|
||||
wallet.receiveFromBlock(spend, b3, BlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
|
||||
// Change is confirmed. We started with 5.50 so we should have 4.50 left.
|
||||
BigInteger v4 = toNanoCoins(4, 50);
|
||||
Coin v4 = toNanoCoins(4, 50);
|
||||
assertEquals(v4, wallet.getBalance(Wallet.BalanceType.AVAILABLE));
|
||||
}
|
||||
|
||||
@ -486,12 +486,12 @@ public class WalletTest extends TestWithWallet {
|
||||
@Test
|
||||
public void blockChainCatchup() throws Exception {
|
||||
// Test that we correctly process transactions arriving from the chain, with callbacks for inbound and outbound.
|
||||
final BigInteger bigints[] = new BigInteger[4];
|
||||
final Coin bigints[] = new Coin[4];
|
||||
final Transaction txn[] = new Transaction[2];
|
||||
final LinkedList<Transaction> confTxns = new LinkedList<Transaction>();
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
super.onCoinsReceived(wallet, tx, prevBalance, newBalance);
|
||||
bigints[0] = prevBalance;
|
||||
bigints[1] = newBalance;
|
||||
@ -499,7 +499,7 @@ public class WalletTest extends TestWithWallet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
super.onCoinsSent(wallet, tx, prevBalance, newBalance);
|
||||
bigints[2] = prevBalance;
|
||||
bigints[3] = newBalance;
|
||||
@ -514,13 +514,13 @@ public class WalletTest extends TestWithWallet {
|
||||
});
|
||||
|
||||
// Receive some money.
|
||||
BigInteger oneCoin = Utils.toNanoCoins(1, 0);
|
||||
Coin oneCoin = Utils.toNanoCoins(1, 0);
|
||||
Transaction tx1 = sendMoneyToWallet(oneCoin, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
Threading.waitForUserCode();
|
||||
assertEquals(null, txn[1]); // onCoinsSent not called.
|
||||
assertEquals(tx1, confTxns.getFirst()); // onTransactionConfidenceChanged called
|
||||
assertEquals(txn[0].getHash(), tx1.getHash());
|
||||
assertEquals(BigInteger.ZERO, bigints[0]);
|
||||
assertEquals(Coin.ZERO, bigints[0]);
|
||||
assertEquals(oneCoin, bigints[1]);
|
||||
assertEquals(TransactionConfidence.ConfidenceType.BUILDING, tx1.getConfidence().getConfidenceType());
|
||||
assertEquals(1, tx1.getConfidence().getAppearedAtChainHeight());
|
||||
@ -555,7 +555,7 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
@Test
|
||||
public void balances() throws Exception {
|
||||
BigInteger nanos = Utils.toNanoCoins(1, 0);
|
||||
Coin nanos = Utils.toNanoCoins(1, 0);
|
||||
Transaction tx1 = sendMoneyToWallet(nanos, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
assertEquals(nanos, tx1.getValueSentToMe(wallet, true));
|
||||
// Send 0.10 to somebody else.
|
||||
@ -563,7 +563,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// Reserialize.
|
||||
Transaction send2 = new Transaction(params, send1.bitcoinSerialize());
|
||||
assertEquals(nanos, send2.getValueSentFromMe(wallet));
|
||||
assertEquals(BigInteger.ZERO.subtract(toNanoCoins(0, 10)), send2.getValue(wallet));
|
||||
assertEquals(Coin.ZERO.subtract(toNanoCoins(0, 10)), send2.getValue(wallet));
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -640,11 +640,11 @@ public class WalletTest extends TestWithWallet {
|
||||
public void bounce() throws Exception {
|
||||
// This test covers bug 64 (False double spends). Check that if we create a spend and it's immediately sent
|
||||
// back to us, this isn't considered as a double spend.
|
||||
BigInteger coin1 = Utils.toNanoCoins(1, 0);
|
||||
Coin coin1 = Utils.toNanoCoins(1, 0);
|
||||
sendMoneyToWallet(coin1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
// Send half to some other guy. Sending only half then waiting for a confirm is important to ensure the tx is
|
||||
// in the unspent pool, not pending or spent.
|
||||
BigInteger coinHalf = Utils.toNanoCoins(0, 50);
|
||||
Coin coinHalf = Utils.toNanoCoins(0, 50);
|
||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||
assertEquals(1, wallet.getTransactions(true).size());
|
||||
Address someOtherGuy = new ECKey().toAddress(params);
|
||||
@ -675,7 +675,7 @@ public class WalletTest extends TestWithWallet {
|
||||
send2 = new Transaction(params, send2.bitcoinSerialize());
|
||||
// Broadcast send1, it's now pending.
|
||||
wallet.commitTx(send1);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
// Receive a block that overrides the send1 using send2.
|
||||
sendMoneyToWallet(send2, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
// send1 got rolled back and replaced with a smaller send that only used one of our received coins, thus ...
|
||||
@ -691,8 +691,8 @@ public class WalletTest extends TestWithWallet {
|
||||
// This can (and has!) happened when a wallet is cloned between devices, and both devices decide to make the
|
||||
// same spend simultaneously - for example due a re-keying operation. It can also happen if there are malicious
|
||||
// nodes in the P2P network that are mutating transactions on the fly as occurred during Feb 2014.
|
||||
final BigInteger value = Utils.toNanoCoins(1, 0);
|
||||
final BigInteger value2 = Utils.toNanoCoins(2, 0);
|
||||
final Coin value = Utils.toNanoCoins(1, 0);
|
||||
final Coin value2 = Utils.toNanoCoins(2, 0);
|
||||
// Give us three coins and make sure we have some change.
|
||||
sendMoneyToWallet(value.add(value2), AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
final Address address = new ECKey().toAddress(params);
|
||||
@ -707,7 +707,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// Now spend the change. This transaction should die permanently when the mutant appears in the chain.
|
||||
Transaction send3 = checkNotNull(wallet.createSend(address, value));
|
||||
wallet.commitTx(send3);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
final LinkedList<Transaction> dead = new LinkedList<Transaction>();
|
||||
final TransactionConfidence.Listener listener = new TransactionConfidence.Listener() {
|
||||
@Override
|
||||
@ -758,7 +758,7 @@ public class WalletTest extends TestWithWallet {
|
||||
});
|
||||
|
||||
// Receive 1 BTC.
|
||||
BigInteger nanos = Utils.toNanoCoins(1, 0);
|
||||
Coin nanos = Utils.toNanoCoins(1, 0);
|
||||
sendMoneyToWallet(nanos, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
Transaction received = wallet.getTransactions(false).iterator().next();
|
||||
// Create a send to a merchant.
|
||||
@ -794,7 +794,7 @@ public class WalletTest extends TestWithWallet {
|
||||
@Test
|
||||
public void pending1() throws Exception {
|
||||
// Check that if we receive a pending transaction that is then confirmed, we are notified as appropriate.
|
||||
final BigInteger nanos = Utils.toNanoCoins(1, 0);
|
||||
final Coin nanos = Utils.toNanoCoins(1, 0);
|
||||
final Transaction t1 = createFakeTx(params, nanos, myAddress);
|
||||
|
||||
// First one is "called" second is "pending".
|
||||
@ -803,11 +803,11 @@ public class WalletTest extends TestWithWallet {
|
||||
final int[] walletChanged = new int[1];
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
// Check we got the expected transaction.
|
||||
assertEquals(tx, t1);
|
||||
// Check that it's considered to be pending inclusion in the block chain.
|
||||
assertEquals(prevBalance, BigInteger.ZERO);
|
||||
assertEquals(prevBalance, Coin.ZERO);
|
||||
assertEquals(newBalance, nanos);
|
||||
flags[0] = true;
|
||||
flags[1] = tx.isPending();
|
||||
@ -867,21 +867,21 @@ public class WalletTest extends TestWithWallet {
|
||||
public void pending2() throws Exception {
|
||||
// Check that if we receive a pending tx we did not send, it updates our spent flags correctly.
|
||||
final Transaction txn[] = new Transaction[1];
|
||||
final BigInteger bigints[] = new BigInteger[2];
|
||||
final Coin bigints[] = new Coin[2];
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
txn[0] = tx;
|
||||
bigints[0] = prevBalance;
|
||||
bigints[1] = newBalance;
|
||||
}
|
||||
});
|
||||
// Receive some coins.
|
||||
BigInteger nanos = Utils.toNanoCoins(1, 0);
|
||||
Coin nanos = Utils.toNanoCoins(1, 0);
|
||||
sendMoneyToWallet(nanos, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
// Create a spend with them, but don't commit it (ie it's from somewhere else but using our keys). This TX
|
||||
// will have change as we don't spend our entire balance.
|
||||
BigInteger halfNanos = Utils.toNanoCoins(0, 50);
|
||||
Coin halfNanos = Utils.toNanoCoins(0, 50);
|
||||
Transaction t2 = wallet.createSend(new ECKey().toAddress(params), halfNanos);
|
||||
// Now receive it as pending.
|
||||
if (wallet.isPendingTransactionRelevant(t2))
|
||||
@ -900,7 +900,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// Check that if we receive a pending tx, and it's overridden by a double spend from the main chain, we
|
||||
// are notified that it's dead. This should work even if the pending tx inputs are NOT ours, ie, they don't
|
||||
// connect to anything.
|
||||
BigInteger nanos = Utils.toNanoCoins(1, 0);
|
||||
Coin nanos = Utils.toNanoCoins(1, 0);
|
||||
|
||||
// Create two transactions that share the same input tx.
|
||||
Address badGuy = new ECKey().toAddress(params);
|
||||
@ -918,7 +918,7 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
final Transaction[] called = new Transaction[2];
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
called[0] = tx;
|
||||
}
|
||||
|
||||
@ -933,7 +933,7 @@ public class WalletTest extends TestWithWallet {
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
if (wallet.isPendingTransactionRelevant(t1))
|
||||
wallet.receivePending(t1, null);
|
||||
Threading.waitForUserCode();
|
||||
@ -943,7 +943,7 @@ public class WalletTest extends TestWithWallet {
|
||||
called[0] = called[1] = null;
|
||||
sendMoneyToWallet(t2, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
Threading.waitForUserCode();
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(t1, called[0]); // dead
|
||||
assertEquals(t2, called[1]); // replacement
|
||||
}
|
||||
@ -1021,8 +1021,8 @@ public class WalletTest extends TestWithWallet {
|
||||
// Test that a spend to the same wallet is dealt with correctly.
|
||||
// It should appear in the wallet and confirm.
|
||||
// This is a bit of a silly thing to do in the real world as all it does is burn a fee but it is perfectly valid.
|
||||
BigInteger coin1 = Utils.toNanoCoins(1, 0);
|
||||
BigInteger coinHalf = Utils.toNanoCoins(0, 50);
|
||||
Coin coin1 = Utils.toNanoCoins(1, 0);
|
||||
Coin coinHalf = Utils.toNanoCoins(0, 50);
|
||||
// Start by giving us 1 coin.
|
||||
sendMoneyToWallet(coin1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
// Send half to ourselves. We should then have a balance available to spend of zero.
|
||||
@ -1031,7 +1031,7 @@ public class WalletTest extends TestWithWallet {
|
||||
Transaction outbound1 = wallet.createSend(myAddress, coinHalf);
|
||||
wallet.commitTx(outbound1);
|
||||
// We should have a zero available balance before the next block.
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
sendMoneyToWallet(outbound1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
// We should have a balance of 1 BTC after the block is received.
|
||||
assertEquals(coin1, wallet.getBalance());
|
||||
@ -1039,9 +1039,9 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
@Test
|
||||
public void lastBlockSeen() throws Exception {
|
||||
BigInteger v1 = toNanoCoins(5, 0);
|
||||
BigInteger v2 = toNanoCoins(0, 50);
|
||||
BigInteger v3 = toNanoCoins(0, 25);
|
||||
Coin v1 = toNanoCoins(5, 0);
|
||||
Coin v2 = toNanoCoins(0, 50);
|
||||
Coin v3 = toNanoCoins(0, 25);
|
||||
Transaction t1 = createFakeTx(params, v1, myAddress);
|
||||
Transaction t2 = createFakeTx(params, v2, myAddress);
|
||||
Transaction t3 = createFakeTx(params, v3, myAddress);
|
||||
@ -1072,13 +1072,13 @@ public class WalletTest extends TestWithWallet {
|
||||
public void pubkeyOnlyScripts() throws Exception {
|
||||
// Verify that we support outputs like OP_PUBKEY and the corresponding inputs.
|
||||
ECKey key1 = wallet.freshReceiveKey();
|
||||
BigInteger value = toNanoCoins(5, 0);
|
||||
Coin value = toNanoCoins(5, 0);
|
||||
Transaction t1 = createFakeTx(params, value, key1);
|
||||
if (wallet.isPendingTransactionRelevant(t1))
|
||||
wallet.receivePending(t1, null);
|
||||
// TX should have been seen as relevant.
|
||||
assertEquals(value, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance(Wallet.BalanceType.AVAILABLE));
|
||||
assertEquals(Coin.ZERO, wallet.getBalance(Wallet.BalanceType.AVAILABLE));
|
||||
Block b1 = createFakeBlock(blockStore, t1).block;
|
||||
chain.add(b1);
|
||||
// TX should have been seen as relevant, extracted and processed.
|
||||
@ -1114,7 +1114,7 @@ public class WalletTest extends TestWithWallet {
|
||||
ECKey key = new ECKey();
|
||||
Address watchedAddress = key.toAddress(params);
|
||||
wallet.addWatchedAddress(watchedAddress);
|
||||
BigInteger value = toNanoCoins(5, 0);
|
||||
Coin value = toNanoCoins(5, 0);
|
||||
Transaction t1 = createFakeTx(params, value, watchedAddress);
|
||||
assertTrue(wallet.isPendingTransactionRelevant(t1));
|
||||
}
|
||||
@ -1127,7 +1127,7 @@ public class WalletTest extends TestWithWallet {
|
||||
Transaction t1 = createFakeTx(params, CENT, watchedAddress);
|
||||
StoredBlock b3 = createFakeBlock(blockStore, t1).storedBlock;
|
||||
wallet.receiveFromBlock(t1, b3, BlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(CENT, wallet.getWatchedBalance());
|
||||
|
||||
// We can't spend watched balances
|
||||
@ -1273,11 +1273,11 @@ public class WalletTest extends TestWithWallet {
|
||||
@Test
|
||||
public void spendOutputFromPendingTransaction() throws Exception {
|
||||
// We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
|
||||
BigInteger v1 = Utils.toNanoCoins(1, 0);
|
||||
Coin v1 = Utils.toNanoCoins(1, 0);
|
||||
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
// First create our current transaction
|
||||
ECKey k2 = wallet.freshReceiveKey();
|
||||
BigInteger v2 = toNanoCoins(0, 50);
|
||||
Coin v2 = toNanoCoins(0, 50);
|
||||
Transaction t2 = new Transaction(params);
|
||||
TransactionOutput o2 = new TransactionOutput(params, t2, v2, k2.toAddress(params));
|
||||
t2.addOutput(o2);
|
||||
@ -1293,7 +1293,7 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
// Now try to the spend the output.
|
||||
ECKey k3 = new ECKey();
|
||||
BigInteger v3 = toNanoCoins(0, 25);
|
||||
Coin v3 = toNanoCoins(0, 25);
|
||||
Transaction t3 = new Transaction(params);
|
||||
t3.addOutput(v3, k3.toAddress(params));
|
||||
t3.addInput(o2);
|
||||
@ -1314,7 +1314,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// Check that if a pending transaction spends outputs of chain-included transactions, we mark them as spent.
|
||||
// See bug 345. This can happen if there is a pending transaction floating around and then you replay the
|
||||
// chain without emptying the memory pool (or refilling it from a peer).
|
||||
BigInteger value = Utils.toNanoCoins(1, 0);
|
||||
Coin value = Utils.toNanoCoins(1, 0);
|
||||
Transaction tx1 = createFakeTx(params, value, myAddress);
|
||||
Transaction tx2 = new Transaction(params);
|
||||
tx2.addInput(tx1.getOutput(0));
|
||||
@ -1325,7 +1325,7 @@ public class WalletTest extends TestWithWallet {
|
||||
BlockPair bp = createFakeBlock(blockStore, tx1);
|
||||
wallet.receiveFromBlock(tx1, bp.storedBlock, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
wallet.notifyNewBestBlock(bp.storedBlock);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(1, wallet.getPoolSize(Pool.SPENT));
|
||||
assertEquals(1, wallet.getPoolSize(Pool.PENDING));
|
||||
assertEquals(0, wallet.getPoolSize(Pool.UNSPENT));
|
||||
@ -1461,7 +1461,7 @@ public class WalletTest extends TestWithWallet {
|
||||
Transaction tx = new Transaction(params);
|
||||
byte[] bits = new byte[20];
|
||||
new Random().nextBytes(bits);
|
||||
BigInteger v = Utils.toNanoCoins(0, 1);
|
||||
Coin v = Utils.toNanoCoins(0, 1);
|
||||
// 3100 outputs to a random address.
|
||||
for (int i = 0; i < 3100; i++) {
|
||||
tx.addOutput(v, new Address(params, bits));
|
||||
@ -1481,26 +1481,26 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
// Generate a few outputs to us that are far too small to spend reasonably
|
||||
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
|
||||
Transaction tx1 = createFakeTx(params, BigInteger.ONE, myAddress);
|
||||
Transaction tx1 = createFakeTx(params, Coin.ONE, myAddress);
|
||||
wallet.receiveFromBlock(tx1, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
Transaction tx2 = createFakeTx(params, BigInteger.ONE, myAddress);
|
||||
Transaction tx2 = createFakeTx(params, Coin.ONE, myAddress);
|
||||
assertTrue(!tx1.getHash().equals(tx2.getHash()));
|
||||
wallet.receiveFromBlock(tx2, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 1);
|
||||
Transaction tx3 = createFakeTx(params, BigInteger.TEN, myAddress);
|
||||
Transaction tx3 = createFakeTx(params, Coin.TEN, myAddress);
|
||||
wallet.receiveFromBlock(tx3, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 2);
|
||||
|
||||
// Not allowed to send dust.
|
||||
try {
|
||||
wallet.createSend(notMyAddr, BigInteger.ONE);
|
||||
wallet.createSend(notMyAddr, Coin.ONE);
|
||||
fail();
|
||||
} catch (Wallet.DustySendRequested e) {
|
||||
// Expected.
|
||||
}
|
||||
// Spend it all without fee enforcement
|
||||
SendRequest req = SendRequest.to(notMyAddr, BigInteger.TEN.add(BigInteger.ONE.add(BigInteger.ONE)));
|
||||
SendRequest req = SendRequest.to(notMyAddr, Coin.TEN.add(Coin.ONE.add(Coin.ONE)));
|
||||
req.ensureMinRequiredFee = false;
|
||||
assertNotNull(wallet.sendCoinsOffline(req));
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
|
||||
// Add some reasonable-sized outputs
|
||||
block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
|
||||
@ -1508,7 +1508,7 @@ public class WalletTest extends TestWithWallet {
|
||||
wallet.receiveFromBlock(tx4, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
|
||||
// Simple test to make sure if we have an ouput < 0.01 we get a fee
|
||||
Transaction spend1 = wallet.createSend(notMyAddr, CENT.subtract(BigInteger.ONE));
|
||||
Transaction spend1 = wallet.createSend(notMyAddr, CENT.subtract(Coin.ONE));
|
||||
assertEquals(2, spend1.getOutputs().size());
|
||||
// We optimize for priority, so the output selected should be the largest one.
|
||||
// We should have paid the default minfee.
|
||||
@ -1522,19 +1522,19 @@ public class WalletTest extends TestWithWallet {
|
||||
assertEquals(Utils.COIN, spend2.getOutput(0).getValue().add(spend2.getOutput(1).getValue()));
|
||||
|
||||
// ...but not more fee than what we request
|
||||
SendRequest request3 = SendRequest.to(notMyAddr, CENT.subtract(BigInteger.ONE));
|
||||
request3.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE);
|
||||
SendRequest request3 = SendRequest.to(notMyAddr, CENT.subtract(Coin.ONE));
|
||||
request3.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE);
|
||||
wallet.completeTx(request3);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE), request3.fee);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE), request3.fee);
|
||||
Transaction spend3 = request3.tx;
|
||||
assertEquals(2, spend3.getOutputs().size());
|
||||
// We optimize for priority, so the output selected should be the largest one.
|
||||
assertEquals(spend3.getOutput(0).getValue().add(spend3.getOutput(1).getValue()),
|
||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE)));
|
||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE)));
|
||||
|
||||
// ...unless we need it
|
||||
SendRequest request4 = SendRequest.to(notMyAddr, CENT.subtract(BigInteger.ONE));
|
||||
request4.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(BigInteger.ONE);
|
||||
SendRequest request4 = SendRequest.to(notMyAddr, CENT.subtract(Coin.ONE));
|
||||
request4.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(Coin.ONE);
|
||||
wallet.completeTx(request4);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request4.fee);
|
||||
Transaction spend4 = request4.tx;
|
||||
@ -1543,7 +1543,7 @@ public class WalletTest extends TestWithWallet {
|
||||
assertEquals(spend4.getOutput(0).getValue().add(spend4.getOutput(1).getValue()),
|
||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||
|
||||
SendRequest request5 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.subtract(BigInteger.ONE)));
|
||||
SendRequest request5 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.subtract(Coin.ONE)));
|
||||
wallet.completeTx(request5);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request5.fee);
|
||||
Transaction spend5 = request5.tx;
|
||||
@ -1555,15 +1555,15 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
SendRequest request6 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT));
|
||||
wallet.completeTx(request6);
|
||||
assertEquals(BigInteger.ZERO, request6.fee);
|
||||
assertEquals(Coin.ZERO, request6.fee);
|
||||
Transaction spend6 = request6.tx;
|
||||
// ...but not if change output == 0.01
|
||||
assertEquals(2, spend6.getOutputs().size());
|
||||
// We optimize for priority, so the output selected should be the largest one
|
||||
assertEquals(Utils.COIN, spend6.getOutput(0).getValue().add(spend6.getOutput(1).getValue()));
|
||||
|
||||
SendRequest request7 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.subtract(BigInteger.valueOf(2)).multiply(BigInteger.valueOf(2))));
|
||||
request7.tx.addOutput(CENT.subtract(BigInteger.ONE), notMyAddr);
|
||||
SendRequest request7 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.subtract(Coin.valueOf(2)).multiply(Coin.valueOf(2))));
|
||||
request7.tx.addOutput(CENT.subtract(Coin.ONE), notMyAddr);
|
||||
wallet.completeTx(request7);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request7.fee);
|
||||
Transaction spend7 = request7.tx;
|
||||
@ -1594,7 +1594,7 @@ public class WalletTest extends TestWithWallet {
|
||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)));
|
||||
|
||||
SendRequest request10 = SendRequest.to(notMyAddr, Utils.COIN.subtract(
|
||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(BigInteger.ONE)));
|
||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(Coin.ONE)));
|
||||
wallet.completeTx(request10);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request10.fee);
|
||||
Transaction spend10 = request10.tx;
|
||||
@ -1605,16 +1605,16 @@ public class WalletTest extends TestWithWallet {
|
||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||
|
||||
SendRequest request11 = SendRequest.to(notMyAddr, Utils.COIN.subtract(
|
||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(BigInteger.valueOf(2))));
|
||||
request11.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE);
|
||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(Coin.valueOf(2))));
|
||||
request11.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE);
|
||||
wallet.completeTx(request11);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE), request11.fee);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE), request11.fee);
|
||||
Transaction spend11 = request11.tx;
|
||||
// ...of course fee should be min(request.fee, MIN_TX_FEE) so we should get MIN_TX_FEE.add(ONE) here
|
||||
assertEquals(2, spend11.getOutputs().size());
|
||||
// We optimize for priority, so the output selected should be the largest one.
|
||||
assertEquals(spend11.getOutput(0).getValue().add(spend11.getOutput(1).getValue()),
|
||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE)));
|
||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE)));
|
||||
|
||||
// Remove the coin from our wallet
|
||||
wallet.commitTx(spend11);
|
||||
@ -1658,30 +1658,30 @@ public class WalletTest extends TestWithWallet {
|
||||
for (int i = 0; i < 29; i++)
|
||||
request15.tx.addOutput(CENT, notMyAddr);
|
||||
assertTrue(request15.tx.bitcoinSerialize().length > 1000);
|
||||
request15.feePerKb = BigInteger.ONE;
|
||||
request15.feePerKb = Coin.ONE;
|
||||
wallet.completeTx(request15);
|
||||
assertEquals(BigInteger.valueOf(2), request15.fee);
|
||||
assertEquals(Coin.valueOf(2), request15.fee);
|
||||
Transaction spend15 = request15.tx;
|
||||
// If a transaction is over 1kb, 2 satoshis should be added.
|
||||
assertEquals(31, spend15.getOutputs().size());
|
||||
// We optimize for priority, so the output selected should be the largest one
|
||||
BigInteger outValue15 = BigInteger.ZERO;
|
||||
Coin outValue15 = Coin.ZERO;
|
||||
for (TransactionOutput out : spend15.getOutputs())
|
||||
outValue15 = outValue15.add(out.getValue());
|
||||
assertEquals(Utils.COIN.subtract(BigInteger.valueOf(2)), outValue15);
|
||||
assertEquals(Utils.COIN.subtract(Coin.valueOf(2)), outValue15);
|
||||
|
||||
SendRequest request16 = SendRequest.to(notMyAddr, CENT);
|
||||
request16.feePerKb = BigInteger.ZERO;
|
||||
request16.feePerKb = Coin.ZERO;
|
||||
for (int i = 0; i < 29; i++)
|
||||
request16.tx.addOutput(CENT, notMyAddr);
|
||||
assertTrue(request16.tx.bitcoinSerialize().length > 1000);
|
||||
wallet.completeTx(request16);
|
||||
// Of course the fee shouldn't be added if feePerKb == 0
|
||||
assertEquals(BigInteger.ZERO, request16.fee);
|
||||
assertEquals(Coin.ZERO, request16.fee);
|
||||
Transaction spend16 = request16.tx;
|
||||
assertEquals(31, spend16.getOutputs().size());
|
||||
// We optimize for priority, so the output selected should be the largest one
|
||||
BigInteger outValue16 = BigInteger.ZERO;
|
||||
Coin outValue16 = Coin.ZERO;
|
||||
for (TransactionOutput out : spend16.getOutputs())
|
||||
outValue16 = outValue16.add(out.getValue());
|
||||
assertEquals(Utils.COIN, outValue16);
|
||||
@ -1691,9 +1691,9 @@ public class WalletTest extends TestWithWallet {
|
||||
for (int i = 0; i < 22; i++)
|
||||
request17.tx.addOutput(CENT, notMyAddr);
|
||||
request17.tx.addOutput(new TransactionOutput(params, request17.tx, CENT, new byte[15]));
|
||||
request17.feePerKb = BigInteger.ONE;
|
||||
request17.feePerKb = Coin.ONE;
|
||||
wallet.completeTx(request17);
|
||||
assertEquals(BigInteger.ONE, request17.fee);
|
||||
assertEquals(Coin.ONE, request17.fee);
|
||||
assertEquals(1, request17.tx.getInputs().size());
|
||||
// Calculate its max length to make sure it is indeed 999
|
||||
int theoreticalMaxLength17 = request17.tx.bitcoinSerialize().length + myKey.getPubKey().length + 75;
|
||||
@ -1709,19 +1709,19 @@ public class WalletTest extends TestWithWallet {
|
||||
// Now check that it got a fee of 1 since its max size is 999 (1kb).
|
||||
assertEquals(25, spend17.getOutputs().size());
|
||||
// We optimize for priority, so the output selected should be the largest one
|
||||
BigInteger outValue17 = BigInteger.ZERO;
|
||||
Coin outValue17 = Coin.ZERO;
|
||||
for (TransactionOutput out : spend17.getOutputs())
|
||||
outValue17 = outValue17.add(out.getValue());
|
||||
assertEquals(Utils.COIN.subtract(BigInteger.ONE), outValue17);
|
||||
assertEquals(Utils.COIN.subtract(Coin.ONE), outValue17);
|
||||
|
||||
// Create a transaction who's max size could be up to 1001 (if signatures were maximum size)
|
||||
SendRequest request18 = SendRequest.to(notMyAddr, CENT);
|
||||
for (int i = 0; i < 22; i++)
|
||||
request18.tx.addOutput(CENT, notMyAddr);
|
||||
request18.tx.addOutput(new TransactionOutput(params, request18.tx, CENT, new byte[17]));
|
||||
request18.feePerKb = BigInteger.ONE;
|
||||
request18.feePerKb = Coin.ONE;
|
||||
wallet.completeTx(request18);
|
||||
assertEquals(BigInteger.valueOf(2), request18.fee);
|
||||
assertEquals(Coin.valueOf(2), request18.fee);
|
||||
assertEquals(1, request18.tx.getInputs().size());
|
||||
// Calculate its max length to make sure it is indeed 1001
|
||||
Transaction spend18 = request18.tx;
|
||||
@ -1735,31 +1735,31 @@ public class WalletTest extends TestWithWallet {
|
||||
// Now check that it did get a fee since its max size is 1000
|
||||
assertEquals(25, spend18.getOutputs().size());
|
||||
// We optimize for priority, so the output selected should be the largest one
|
||||
BigInteger outValue18 = BigInteger.ZERO;
|
||||
Coin outValue18 = Coin.ZERO;
|
||||
for (TransactionOutput out : spend18.getOutputs())
|
||||
outValue18 = outValue18.add(out.getValue());
|
||||
assertEquals(outValue18, Utils.COIN.subtract(BigInteger.valueOf(2)));
|
||||
assertEquals(outValue18, Utils.COIN.subtract(Coin.valueOf(2)));
|
||||
|
||||
// Now create a transaction that will spend COIN + fee, which makes it require both inputs
|
||||
assertEquals(wallet.getBalance(), CENT.add(Utils.COIN));
|
||||
SendRequest request19 = SendRequest.to(notMyAddr, CENT);
|
||||
request19.feePerKb = BigInteger.ZERO;
|
||||
request19.feePerKb = Coin.ZERO;
|
||||
for (int i = 0; i < 99; i++)
|
||||
request19.tx.addOutput(CENT, notMyAddr);
|
||||
// If we send now, we shouldn't need a fee and should only have to spend our COIN
|
||||
wallet.completeTx(request19);
|
||||
assertEquals(BigInteger.ZERO, request19.fee);
|
||||
assertEquals(Coin.ZERO, request19.fee);
|
||||
assertEquals(1, request19.tx.getInputs().size());
|
||||
assertEquals(100, request19.tx.getOutputs().size());
|
||||
// Now reset request19 and give it a fee per kb
|
||||
request19.tx.clearInputs();
|
||||
request19 = SendRequest.forTx(request19.tx);
|
||||
request19.feePerKb = BigInteger.ONE;
|
||||
request19.feePerKb = Coin.ONE;
|
||||
request19.shuffleOutputs = false;
|
||||
wallet.completeTx(request19);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request19.fee);
|
||||
assertEquals(2, request19.tx.getInputs().size());
|
||||
BigInteger outValue19 = BigInteger.ZERO;
|
||||
Coin outValue19 = Coin.ZERO;
|
||||
for (TransactionOutput out : request19.tx.getOutputs())
|
||||
outValue19 = outValue19.add(out.getValue());
|
||||
// But now our change output is CENT-minfee, so we have to pay min fee
|
||||
@ -1768,12 +1768,12 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
// Create another transaction that will spend COIN + fee, which makes it require both inputs
|
||||
SendRequest request20 = SendRequest.to(notMyAddr, CENT);
|
||||
request20.feePerKb = BigInteger.ZERO;
|
||||
request20.feePerKb = Coin.ZERO;
|
||||
for (int i = 0; i < 99; i++)
|
||||
request20.tx.addOutput(CENT, notMyAddr);
|
||||
// If we send now, we shouldn't have a fee and should only have to spend our COIN
|
||||
wallet.completeTx(request20);
|
||||
assertEquals(BigInteger.ZERO, request20.fee);
|
||||
assertEquals(Coin.ZERO, request20.fee);
|
||||
assertEquals(1, request20.tx.getInputs().size());
|
||||
assertEquals(100, request20.tx.getOutputs().size());
|
||||
// Now reset request19 and give it a fee per kb
|
||||
@ -1782,18 +1782,18 @@ public class WalletTest extends TestWithWallet {
|
||||
request20.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
wallet.completeTx(request20);
|
||||
// 4kb tx.
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(4)), request20.fee);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(4)), request20.fee);
|
||||
assertEquals(2, request20.tx.getInputs().size());
|
||||
BigInteger outValue20 = BigInteger.ZERO;
|
||||
Coin outValue20 = Coin.ZERO;
|
||||
for (TransactionOutput out : request20.tx.getOutputs())
|
||||
outValue20 = outValue20.add(out.getValue());
|
||||
// This time the fee we wanted to pay was more, so that should be what we paid
|
||||
assertEquals(outValue20, Utils.COIN.add(CENT).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(4))));
|
||||
assertEquals(outValue20, Utils.COIN.add(CENT).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(4))));
|
||||
|
||||
// Same as request 19, but make the change 0 (so it doesnt force fee) and make us require min fee as a
|
||||
// result of an output < CENT.
|
||||
SendRequest request21 = SendRequest.to(notMyAddr, CENT);
|
||||
request21.feePerKb = BigInteger.ZERO;
|
||||
request21.feePerKb = Coin.ZERO;
|
||||
for (int i = 0; i < 99; i++)
|
||||
request21.tx.addOutput(CENT, notMyAddr);
|
||||
request21.tx.addOutput(CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), notMyAddr);
|
||||
@ -1801,7 +1801,7 @@ public class WalletTest extends TestWithWallet {
|
||||
wallet.completeTx(request21);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request21.fee);
|
||||
assertEquals(2, request21.tx.getInputs().size());
|
||||
BigInteger outValue21 = BigInteger.ZERO;
|
||||
Coin outValue21 = Coin.ZERO;
|
||||
for (TransactionOutput out : request21.tx.getOutputs())
|
||||
outValue21 = outValue21.add(out.getValue());
|
||||
assertEquals(outValue21, Utils.COIN.add(CENT).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||
@ -1809,30 +1809,30 @@ public class WalletTest extends TestWithWallet {
|
||||
// Test feePerKb when we aren't using ensureMinRequiredFee
|
||||
// Same as request 19
|
||||
SendRequest request25 = SendRequest.to(notMyAddr, CENT);
|
||||
request25.feePerKb = BigInteger.ZERO;
|
||||
request25.feePerKb = Coin.ZERO;
|
||||
for (int i = 0; i < 70; i++)
|
||||
request25.tx.addOutput(CENT, notMyAddr);
|
||||
// If we send now, we shouldn't need a fee and should only have to spend our COIN
|
||||
wallet.completeTx(request25);
|
||||
assertEquals(BigInteger.ZERO, request25.fee);
|
||||
assertEquals(Coin.ZERO, request25.fee);
|
||||
assertEquals(1, request25.tx.getInputs().size());
|
||||
assertEquals(72, request25.tx.getOutputs().size());
|
||||
// Now reset request19 and give it a fee per kb
|
||||
request25.tx.clearInputs();
|
||||
request25 = SendRequest.forTx(request25.tx);
|
||||
request25.feePerKb = CENT.divide(BigInteger.valueOf(3));
|
||||
request25.feePerKb = CENT.divide(Coin.valueOf(3));
|
||||
request25.ensureMinRequiredFee = false;
|
||||
request25.shuffleOutputs = false;
|
||||
wallet.completeTx(request25);
|
||||
assertEquals(CENT.subtract(BigInteger.ONE), request25.fee);
|
||||
assertEquals(CENT.subtract(Coin.ONE), request25.fee);
|
||||
assertEquals(2, request25.tx.getInputs().size());
|
||||
BigInteger outValue25 = BigInteger.ZERO;
|
||||
Coin outValue25 = Coin.ZERO;
|
||||
for (TransactionOutput out : request25.tx.getOutputs())
|
||||
outValue25 = outValue25.add(out.getValue());
|
||||
// Our change output should be one satoshi
|
||||
assertEquals(BigInteger.ONE, request25.tx.getOutput(request25.tx.getOutputs().size() - 1).getValue());
|
||||
assertEquals(Coin.ONE, request25.tx.getOutput(request25.tx.getOutputs().size() - 1).getValue());
|
||||
// and our fee should be CENT-1 satoshi
|
||||
assertEquals(outValue25, Utils.COIN.add(BigInteger.ONE));
|
||||
assertEquals(outValue25, Utils.COIN.add(Coin.ONE));
|
||||
|
||||
// Spend our CENT output.
|
||||
Transaction spendTx5 = new Transaction(params);
|
||||
@ -1849,14 +1849,14 @@ public class WalletTest extends TestWithWallet {
|
||||
request26.tx.addOutput(CENT.subtract(
|
||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)), notMyAddr);
|
||||
assertTrue(request26.tx.bitcoinSerialize().length > 1000);
|
||||
request26.feePerKb = BigInteger.ONE;
|
||||
request26.feePerKb = Coin.ONE;
|
||||
wallet.completeTx(request26);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT), request26.fee);
|
||||
Transaction spend26 = request26.tx;
|
||||
// If a transaction is over 1kb, the set fee should be added
|
||||
assertEquals(100, spend26.getOutputs().size());
|
||||
// We optimize for priority, so the output selected should be the largest one
|
||||
BigInteger outValue26 = BigInteger.ZERO;
|
||||
Coin outValue26 = Coin.ZERO;
|
||||
for (TransactionOutput out : spend26.getOutputs())
|
||||
outValue26 = outValue26.add(out.getValue());
|
||||
assertEquals(outValue26, Utils.COIN.subtract(
|
||||
@ -1866,7 +1866,7 @@ public class WalletTest extends TestWithWallet {
|
||||
@Test
|
||||
public void basicCategoryStepTest() throws Exception {
|
||||
// Creates spends that step through the possible fee solver categories
|
||||
SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
|
||||
SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||
// Make sure TestWithWallet isnt doing anything crazy.
|
||||
assertEquals(0, wallet.getTransactions(true).size());
|
||||
|
||||
@ -1882,9 +1882,9 @@ public class WalletTest extends TestWithWallet {
|
||||
}
|
||||
|
||||
// Create a spend that will throw away change (category 3 type 2 in which the change causes fee which is worth more than change)
|
||||
SendRequest request1 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
||||
SendRequest request1 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||
wallet.completeTx(request1);
|
||||
assertEquals(BigInteger.ONE, request1.fee);
|
||||
assertEquals(Coin.ONE, request1.fee);
|
||||
assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs
|
||||
|
||||
// Give us one more input...
|
||||
@ -1893,9 +1893,9 @@ public class WalletTest extends TestWithWallet {
|
||||
wallet.receiveFromBlock(tx1, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
||||
|
||||
// ... and create a spend that will throw away change (category 3 type 1 in which the change causes dust output)
|
||||
SendRequest request2 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
||||
SendRequest request2 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||
wallet.completeTx(request2);
|
||||
assertEquals(BigInteger.ONE, request2.fee);
|
||||
assertEquals(Coin.ONE, request2.fee);
|
||||
assertEquals(request2.tx.getInputs().size(), i - 1); // We should have spent all inputs - 1
|
||||
|
||||
// Give us one more input...
|
||||
@ -1905,16 +1905,16 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
// ... and create a spend that will throw away change (category 3 type 1 in which the change causes dust output)
|
||||
// but that also could have been category 2 if it wanted
|
||||
SendRequest request3 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
||||
SendRequest request3 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||
wallet.completeTx(request3);
|
||||
assertEquals(BigInteger.ONE, request3.fee);
|
||||
assertEquals(Coin.ONE, request3.fee);
|
||||
assertEquals(request3.tx.getInputs().size(), i - 2); // We should have spent all inputs - 2
|
||||
|
||||
//
|
||||
SendRequest request4 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
||||
request4.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.divide(BigInteger.valueOf(request3.tx.bitcoinSerialize().length));
|
||||
SendRequest request4 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||
request4.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.divide(Coin.valueOf(request3.tx.bitcoinSerialize().length));
|
||||
wallet.completeTx(request4);
|
||||
assertEquals(BigInteger.ONE, request4.fee);
|
||||
assertEquals(Coin.ONE, request4.fee);
|
||||
assertEquals(request4.tx.getInputs().size(), i - 2); // We should have spent all inputs - 2
|
||||
|
||||
// Give us a few more inputs...
|
||||
@ -1925,9 +1925,9 @@ public class WalletTest extends TestWithWallet {
|
||||
}
|
||||
|
||||
// ...that is just slightly less than is needed for category 1
|
||||
SendRequest request5 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
||||
SendRequest request5 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||
wallet.completeTx(request5);
|
||||
assertEquals(BigInteger.ONE, request5.fee);
|
||||
assertEquals(Coin.ONE, request5.fee);
|
||||
assertEquals(1, request5.tx.getOutputs().size()); // We should have no change output
|
||||
|
||||
// Give us one more input...
|
||||
@ -1936,9 +1936,9 @@ public class WalletTest extends TestWithWallet {
|
||||
wallet.receiveFromBlock(tx4, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
||||
|
||||
// ... that puts us in category 1 (no fee!)
|
||||
SendRequest request6 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
||||
SendRequest request6 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||
wallet.completeTx(request6);
|
||||
assertEquals(BigInteger.ZERO, request6.fee);
|
||||
assertEquals(Coin.ZERO, request6.fee);
|
||||
assertEquals(2, request6.tx.getOutputs().size()); // We should have a change output
|
||||
|
||||
SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
@ -1956,14 +1956,14 @@ public class WalletTest extends TestWithWallet {
|
||||
// Generate a ton of small outputs
|
||||
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
|
||||
int i = 0;
|
||||
while (i <= CENT.divide(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.TEN)).longValue()) {
|
||||
Transaction tx = createFakeTxWithChangeAddress(params, Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.TEN), myAddress, notMyAddr);
|
||||
while (i <= CENT.divide(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.TEN)).longValue()) {
|
||||
Transaction tx = createFakeTxWithChangeAddress(params, Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.TEN), myAddress, notMyAddr);
|
||||
tx.getInput(0).setSequenceNumber(i++); // Keep every transaction unique
|
||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
||||
}
|
||||
|
||||
// The selector will choose 2 with MIN_TX_FEE fee
|
||||
SendRequest request1 = SendRequest.to(notMyAddr, CENT.add(BigInteger.ONE));
|
||||
SendRequest request1 = SendRequest.to(notMyAddr, CENT.add(Coin.ONE));
|
||||
wallet.completeTx(request1);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request1.fee);
|
||||
assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs
|
||||
@ -2002,16 +2002,16 @@ public class WalletTest extends TestWithWallet {
|
||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
Transaction tx2 = createFakeTx(params, CENT, myAddress);
|
||||
wallet.receiveFromBlock(tx2, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 1);
|
||||
Transaction tx3 = createFakeTx(params, BigInteger.ONE, myAddress);
|
||||
Transaction tx3 = createFakeTx(params, Coin.ONE, myAddress);
|
||||
wallet.receiveFromBlock(tx3, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 2);
|
||||
|
||||
// Create a transaction who's max size could be up to 1000 (if signatures were maximum size)
|
||||
SendRequest request1 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.multiply(BigInteger.valueOf(17))));
|
||||
SendRequest request1 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.multiply(Coin.valueOf(17))));
|
||||
for (int i = 0; i < 16; i++)
|
||||
request1.tx.addOutput(CENT, notMyAddr);
|
||||
request1.tx.addOutput(new TransactionOutput(params, request1.tx, CENT, new byte[16]));
|
||||
request1.fee = BigInteger.ONE;
|
||||
request1.feePerKb = BigInteger.ONE;
|
||||
request1.fee = Coin.ONE;
|
||||
request1.feePerKb = Coin.ONE;
|
||||
// We get a category 2 using COIN+CENT
|
||||
// It spends COIN + 1(fee) and because its output is thus < CENT, we have to pay MIN_TX_FEE
|
||||
// When it tries category 1, its too large and requires COIN + 2 (fee)
|
||||
@ -2021,18 +2021,18 @@ public class WalletTest extends TestWithWallet {
|
||||
assertEquals(2, request1.tx.getInputs().size());
|
||||
|
||||
// We then add one more satoshi output to the wallet
|
||||
Transaction tx4 = createFakeTx(params, BigInteger.ONE, myAddress);
|
||||
Transaction tx4 = createFakeTx(params, Coin.ONE, myAddress);
|
||||
wallet.receiveFromBlock(tx4, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 3);
|
||||
|
||||
// Create a transaction who's max size could be up to 1000 (if signatures were maximum size)
|
||||
SendRequest request2 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.multiply(BigInteger.valueOf(17))));
|
||||
SendRequest request2 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.multiply(Coin.valueOf(17))));
|
||||
for (int i = 0; i < 16; i++)
|
||||
request2.tx.addOutput(CENT, notMyAddr);
|
||||
request2.tx.addOutput(new TransactionOutput(params, request2.tx, CENT, new byte[16]));
|
||||
request2.feePerKb = BigInteger.ONE;
|
||||
request2.feePerKb = Coin.ONE;
|
||||
// The process is the same as above, but now we can complete category 1 with one more input, and pay a fee of 2
|
||||
wallet.completeTx(request2);
|
||||
assertEquals(BigInteger.valueOf(2), request2.fee);
|
||||
assertEquals(Coin.valueOf(2), request2.fee);
|
||||
assertEquals(4, request2.tx.getInputs().size());
|
||||
}
|
||||
|
||||
@ -2107,7 +2107,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// Check that if a wallet listener throws an exception, the others still run.
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
log.info("onCoinsReceived 1");
|
||||
throw new RuntimeException("barf");
|
||||
}
|
||||
@ -2115,7 +2115,7 @@ public class WalletTest extends TestWithWallet {
|
||||
final AtomicInteger flag = new AtomicInteger();
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
log.info("onCoinsReceived 2");
|
||||
flag.incrementAndGet();
|
||||
}
|
||||
@ -2134,13 +2134,13 @@ public class WalletTest extends TestWithWallet {
|
||||
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, new ECKey().toAddress(params)), BigInteger.ONE, 1);
|
||||
Random rng = new Random();
|
||||
for (int i = 0; i < rng.nextInt(100) + 1; i++) {
|
||||
Transaction tx = createFakeTx(params, BigInteger.valueOf(rng.nextInt((int) Utils.COIN.longValue())), myAddress);
|
||||
Transaction tx = createFakeTx(params, Coin.valueOf(rng.nextInt((int) Utils.COIN.longValue())), myAddress);
|
||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
||||
}
|
||||
SendRequest request = SendRequest.emptyWallet(new ECKey().toAddress(params));
|
||||
wallet.completeTx(request);
|
||||
wallet.commitTx(request.tx);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -2153,7 +2153,7 @@ public class WalletTest extends TestWithWallet {
|
||||
SendRequest request = SendRequest.emptyWallet(outputKey);
|
||||
wallet.completeTx(request);
|
||||
wallet.commitTx(request.tx);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(CENT, request.tx.getOutput(0).getValue());
|
||||
|
||||
// Add 1 confirmed cent and 1 unconfirmed cent. Verify only one cent is emptied because of the coin selection
|
||||
@ -2166,22 +2166,22 @@ public class WalletTest extends TestWithWallet {
|
||||
request = SendRequest.emptyWallet(outputKey);
|
||||
wallet.completeTx(request);
|
||||
wallet.commitTx(request.tx);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(CENT, request.tx.getOutput(0).getValue());
|
||||
|
||||
// Add just under 0.01
|
||||
StoredBlock block2 = new StoredBlock(block.getHeader().createNextBlock(outputKey), BigInteger.ONE, 2);
|
||||
tx = createFakeTx(params, CENT.subtract(BigInteger.ONE), myAddress);
|
||||
tx = createFakeTx(params, CENT.subtract(Coin.ONE), myAddress);
|
||||
wallet.receiveFromBlock(tx, block2, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
request = SendRequest.emptyWallet(outputKey);
|
||||
wallet.completeTx(request);
|
||||
wallet.commitTx(request.tx);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(CENT.subtract(BigInteger.ONE).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), request.tx.getOutput(0).getValue());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(CENT.subtract(Coin.ONE).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), request.tx.getOutput(0).getValue());
|
||||
|
||||
// Add an unsendable value
|
||||
StoredBlock block3 = new StoredBlock(block2.getHeader().createNextBlock(outputKey), BigInteger.ONE, 3);
|
||||
BigInteger outputValue = Transaction.MIN_NONDUST_OUTPUT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE);
|
||||
Coin outputValue = Transaction.MIN_NONDUST_OUTPUT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE);
|
||||
tx = createFakeTx(params, outputValue, myAddress);
|
||||
wallet.receiveFromBlock(tx, block3, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
request = SendRequest.emptyWallet(outputKey);
|
||||
@ -2192,7 +2192,7 @@ public class WalletTest extends TestWithWallet {
|
||||
request.ensureMinRequiredFee = false;
|
||||
wallet.completeTx(request);
|
||||
wallet.commitTx(request.tx);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(outputValue, request.tx.getOutput(0).getValue());
|
||||
}
|
||||
|
||||
@ -2220,7 +2220,7 @@ public class WalletTest extends TestWithWallet {
|
||||
wallet.setKeyRotationTime(compromiseTime);
|
||||
assertTrue(wallet.isKeyRotating(key1));
|
||||
Transaction tx = broadcaster.waitForTransaction();
|
||||
final BigInteger THREE_CENTS = CENT.add(CENT).add(CENT);
|
||||
final Coin THREE_CENTS = CENT.add(CENT).add(CENT);
|
||||
assertEquals(THREE_CENTS, tx.getValueSentFromMe(wallet));
|
||||
assertEquals(THREE_CENTS.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), tx.getValueSentToMe(wallet));
|
||||
// TX is a raw pay to pubkey.
|
||||
@ -2281,11 +2281,11 @@ public class WalletTest extends TestWithWallet {
|
||||
wallet.setKeyRotationTime(compromise);
|
||||
|
||||
Transaction tx = broadcaster.waitForTransaction();
|
||||
final BigInteger valueSentToMe = tx.getValueSentToMe(wallet);
|
||||
BigInteger fee = tx.getValueSentFromMe(wallet).subtract(valueSentToMe);
|
||||
assertEquals(BigInteger.valueOf(900000), fee);
|
||||
final Coin valueSentToMe = tx.getValueSentToMe(wallet);
|
||||
Coin fee = tx.getValueSentFromMe(wallet).subtract(valueSentToMe);
|
||||
assertEquals(Coin.valueOf(900000), fee);
|
||||
assertEquals(KeyTimeCoinSelector.MAX_SIMULTANEOUS_INPUTS, tx.getInputs().size());
|
||||
assertEquals(BigInteger.valueOf(599100000), valueSentToMe);
|
||||
assertEquals(Coin.valueOf(599100000), valueSentToMe);
|
||||
|
||||
tx = broadcaster.waitForTransaction();
|
||||
assertNotNull(tx);
|
||||
@ -2347,11 +2347,11 @@ public class WalletTest extends TestWithWallet {
|
||||
}
|
||||
});
|
||||
assertTrue(wallet.isPendingTransactionRelevant(tx));
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||
wallet.receivePending(tx, null);
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||
assertTrue(bool.get());
|
||||
// Confirm it in the same manner as how Bloom filtered blocks do. Verify it shows up.
|
||||
StoredBlock block = createFakeBlock(blockStore, tx).storedBlock;
|
||||
|
@ -33,7 +33,6 @@ import javax.annotation.Nullable;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.Arrays;
|
||||
@ -116,7 +115,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
// Test with network code and without any issues. We'll broadcast two txns: multisig contract and settle transaction.
|
||||
final SettableFuture<ListenableFuture<PaymentChannelServerState>> serverCloseFuture = SettableFuture.create();
|
||||
final SettableFuture<Sha256Hash> channelOpenFuture = SettableFuture.create();
|
||||
final BlockingQueue<BigInteger> q = new LinkedBlockingQueue<BigInteger>();
|
||||
final BlockingQueue<Coin> q = new LinkedBlockingQueue<Coin>();
|
||||
final PaymentChannelServerListener server = new PaymentChannelServerListener(mockBroadcaster, serverWallet, 30, Utils.COIN,
|
||||
new PaymentChannelServerListener.HandlerFactory() {
|
||||
@Nullable
|
||||
@ -129,7 +128,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paymentIncrease(BigInteger by, BigInteger to) {
|
||||
public void paymentIncrease(Coin by, Coin to) {
|
||||
q.add(to);
|
||||
}
|
||||
|
||||
@ -169,7 +168,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
});
|
||||
|
||||
Thread.sleep(1250); // No timeouts once the channel is open
|
||||
BigInteger amount = client.state().getValueSpent();
|
||||
Coin amount = client.state().getValueSpent();
|
||||
assertEquals(amount, q.take());
|
||||
client.incrementPayment(Utils.CENT).get();
|
||||
amount = amount.add(Utils.CENT);
|
||||
@ -193,7 +192,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
broadcastTxPause.release();
|
||||
Transaction settleTx = broadcasts.take();
|
||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||
if (!serverState.getBestValueToMe().equals(amount) || !serverState.getFeePaid().equals(BigInteger.ZERO))
|
||||
if (!serverState.getBestValueToMe().equals(amount) || !serverState.getFeePaid().equals(Coin.ZERO))
|
||||
fail();
|
||||
assertTrue(channels.mapChannels.isEmpty());
|
||||
|
||||
@ -282,7 +281,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
||||
final Protos.TwoWayChannelMessage initiateMsg = pair.serverRecorder.checkNextMsg(MessageType.INITIATE);
|
||||
BigInteger minPayment = BigInteger.valueOf(initiateMsg.getInitiate().getMinPayment());
|
||||
Coin minPayment = Coin.valueOf(initiateMsg.getInitiate().getMinPayment());
|
||||
client.receiveMessage(initiateMsg);
|
||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_REFUND));
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.RETURN_REFUND));
|
||||
@ -297,7 +296,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
assertNull(pair.clientRecorder.q.poll());
|
||||
assertEquals(minPayment, client.state().getValueSpent());
|
||||
// Send a bitcent.
|
||||
BigInteger amount = minPayment.add(Utils.CENT);
|
||||
Coin amount = minPayment.add(Utils.CENT);
|
||||
client.incrementPayment(Utils.CENT);
|
||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||
assertEquals(amount, pair.serverRecorder.q.take());
|
||||
@ -463,7 +462,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
assertEquals(CloseReason.NO_ACCEPTABLE_VERSION, pair.clientRecorder.q.take());
|
||||
// Double-check that we cant do anything that requires an open channel
|
||||
try {
|
||||
client.incrementPayment(BigInteger.ONE);
|
||||
client.incrementPayment(Coin.ONE);
|
||||
fail();
|
||||
} catch (IllegalStateException e) { }
|
||||
}
|
||||
@ -489,7 +488,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
assertEquals(CloseReason.TIME_WINDOW_TOO_LARGE, pair.clientRecorder.q.take());
|
||||
// Double-check that we cant do anything that requires an open channel
|
||||
try {
|
||||
client.incrementPayment(BigInteger.ONE);
|
||||
client.incrementPayment(Coin.ONE);
|
||||
fail();
|
||||
} catch (IllegalStateException e) { }
|
||||
}
|
||||
@ -505,7 +504,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
||||
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
|
||||
.setInitiate(Protos.Initiate.newBuilder().setExpireTimeSecs(Utils.currentTimeSeconds())
|
||||
.setMinAcceptedChannelSize(Utils.COIN.add(BigInteger.ONE).longValue())
|
||||
.setMinAcceptedChannelSize(Utils.COIN.add(Coin.ONE).longValue())
|
||||
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey()))
|
||||
.setMinPayment(Transaction.MIN_NONDUST_OUTPUT.longValue()))
|
||||
.setType(MessageType.INITIATE).build());
|
||||
@ -513,17 +512,17 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
assertEquals(CloseReason.SERVER_REQUESTED_TOO_MUCH_VALUE, pair.clientRecorder.q.take());
|
||||
// Double-check that we cant do anything that requires an open channel
|
||||
try {
|
||||
client.incrementPayment(BigInteger.ONE);
|
||||
client.incrementPayment(Coin.ONE);
|
||||
fail();
|
||||
} catch (IllegalStateException e) { }
|
||||
|
||||
// Now check that if the server has a lower min size than what we are willing to spend, we do actually open
|
||||
// a channel of that size.
|
||||
sendMoneyToWallet(Utils.COIN.multiply(BigInteger.TEN), AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
sendMoneyToWallet(Utils.COIN.multiply(Coin.TEN), AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||
|
||||
pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
|
||||
server = pair.server;
|
||||
final BigInteger myValue = Utils.COIN.multiply(BigInteger.TEN);
|
||||
final Coin myValue = Utils.COIN.multiply(Coin.TEN);
|
||||
client = new PaymentChannelClient(wallet, myKey, myValue, Sha256Hash.ZERO_HASH, pair.clientRecorder);
|
||||
client.connectionOpen();
|
||||
server.connectionOpen();
|
||||
@ -531,7 +530,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
||||
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
|
||||
.setInitiate(Protos.Initiate.newBuilder().setExpireTimeSecs(Utils.currentTimeSeconds())
|
||||
.setMinAcceptedChannelSize(Utils.COIN.add(BigInteger.ONE).longValue())
|
||||
.setMinAcceptedChannelSize(Utils.COIN.add(Coin.ONE).longValue())
|
||||
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey()))
|
||||
.setMinPayment(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.longValue()))
|
||||
.setType(MessageType.INITIATE).build());
|
||||
@ -644,8 +643,8 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||
broadcasts.take();
|
||||
// The channel is now empty.
|
||||
assertEquals(BigInteger.ZERO, client.state().getValueRefunded());
|
||||
pair.serverRecorder.q.take(); // Take the BigInteger.
|
||||
assertEquals(Coin.ZERO, client.state().getValueRefunded());
|
||||
pair.serverRecorder.q.take(); // Take the Coin.
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CLOSE));
|
||||
assertEquals(CloseReason.SERVER_REQUESTED_CLOSE, pair.clientRecorder.q.take());
|
||||
@ -684,7 +683,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
pair.clientRecorder.checkInitiated();
|
||||
assertNull(pair.serverRecorder.q.poll());
|
||||
assertNull(pair.clientRecorder.q.poll());
|
||||
ListenableFuture<BigInteger> future = client.incrementPayment(Utils.CENT);
|
||||
ListenableFuture<Coin> future = client.incrementPayment(Utils.CENT);
|
||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||
pair.serverRecorder.q.take();
|
||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
|
||||
|
@ -1,12 +1,13 @@
|
||||
package com.google.bitcoin.protocols.channels;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.Sha256Hash;
|
||||
import com.google.bitcoin.core.TransactionBroadcaster;
|
||||
import com.google.bitcoin.core.Utils;
|
||||
import com.google.bitcoin.core.Wallet;
|
||||
|
||||
import org.bitcoin.paymentchannel.Protos;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.LinkedBlockingQueue;
|
||||
|
||||
@ -35,7 +36,7 @@ public class ChannelTestUtils {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paymentIncrease(BigInteger by, BigInteger to) {
|
||||
public void paymentIncrease(Coin by, Coin to) {
|
||||
q.add(to);
|
||||
}
|
||||
|
||||
@ -49,8 +50,8 @@ public class ChannelTestUtils {
|
||||
return msg;
|
||||
}
|
||||
|
||||
public void checkTotalPayment(BigInteger valueSoFar) throws InterruptedException {
|
||||
BigInteger lastSeen = (BigInteger) q.take();
|
||||
public void checkTotalPayment(Coin valueSoFar) throws InterruptedException {
|
||||
Coin lastSeen = (Coin) q.take();
|
||||
assertEquals(lastSeen, valueSoFar);
|
||||
}
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ import static org.junit.Assert.*;
|
||||
|
||||
public class PaymentChannelStateTest extends TestWithWallet {
|
||||
private ECKey serverKey;
|
||||
private BigInteger halfCoin;
|
||||
private Coin halfCoin;
|
||||
private Wallet serverWallet;
|
||||
private PaymentChannelServerState serverState;
|
||||
private PaymentChannelClientState clientState;
|
||||
@ -94,7 +94,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
@Test
|
||||
public void stateErrors() throws Exception {
|
||||
PaymentChannelClientState channelState = new PaymentChannelClientState(wallet, myKey, serverKey,
|
||||
Utils.COIN.multiply(BigInteger.TEN), 20);
|
||||
Utils.COIN.multiply(Coin.TEN), 20);
|
||||
assertEquals(PaymentChannelClientState.State.NEW, channelState.getState());
|
||||
try {
|
||||
channelState.getMultisigContract();
|
||||
@ -164,8 +164,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertFalse(clientWalletMultisigContract.getInput(0).getConnectedOutput().getSpentBy().getParentTransaction().getHash().equals(refund.getHash()));
|
||||
|
||||
// Both client and server are now in the ready state. Simulate a few micropayments of 0.005 bitcoins.
|
||||
BigInteger size = halfCoin.divide(BigInteger.TEN).divide(BigInteger.TEN);
|
||||
BigInteger totalPayment = BigInteger.ZERO;
|
||||
Coin size = halfCoin.divide(Coin.TEN).divide(Coin.TEN);
|
||||
Coin totalPayment = Coin.ZERO;
|
||||
for (int i = 0; i < 4; i++) {
|
||||
byte[] signature = clientState.incrementPaymentBy(size).signature.encodeToBitcoin();
|
||||
totalPayment = totalPayment.add(size);
|
||||
@ -194,10 +194,10 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
// Create a block with the payment transaction in it and give it to both wallets
|
||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), reserializedCloseTx));
|
||||
|
||||
assertEquals(size.multiply(BigInteger.valueOf(5)), serverWallet.getBalance());
|
||||
assertEquals(size.multiply(Coin.valueOf(5)), serverWallet.getBalance());
|
||||
assertEquals(0, serverWallet.getPendingTransactions().size());
|
||||
|
||||
assertEquals(Utils.COIN.subtract(size.multiply(BigInteger.valueOf(5))), wallet.getBalance());
|
||||
assertEquals(Utils.COIN.subtract(size.multiply(Coin.valueOf(5))), wallet.getBalance());
|
||||
assertEquals(0, wallet.getPendingTransactions().size());
|
||||
assertEquals(3, wallet.getTransactions(false).size());
|
||||
|
||||
@ -218,7 +218,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
|
||||
// Spend the client wallet's one coin
|
||||
Transaction spendCoinTx = wallet.sendCoinsOffline(Wallet.SendRequest.to(new ECKey().toAddress(params), Utils.COIN));
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), spendCoinTx, createFakeTx(params, Utils.CENT, myAddress)));
|
||||
assertEquals(Utils.CENT, wallet.getBalance());
|
||||
|
||||
@ -233,12 +233,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
||||
|
||||
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()),
|
||||
Utils.CENT.divide(BigInteger.valueOf(2)), EXPIRE_TIME);
|
||||
Utils.CENT.divide(Coin.valueOf(2)), EXPIRE_TIME);
|
||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||
assertEquals(Utils.CENT.divide(BigInteger.valueOf(2)), clientState.getTotalValue());
|
||||
assertEquals(Utils.CENT.divide(Coin.valueOf(2)), clientState.getTotalValue());
|
||||
clientState.initiate();
|
||||
// We will have to pay min_tx_fee twice - both the multisig contract and the refund tx
|
||||
assertEquals(clientState.getRefundTxFees(), Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(2)));
|
||||
assertEquals(clientState.getRefundTxFees(), Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(2)));
|
||||
assertEquals(PaymentChannelClientState.State.INITIATED, clientState.getState());
|
||||
|
||||
// Send the refund tx from client to server and get back the signature.
|
||||
@ -269,8 +269,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||
|
||||
// Pay a tiny bit
|
||||
serverState.incrementPayment(Utils.CENT.divide(BigInteger.valueOf(2)).subtract(Utils.CENT.divide(BigInteger.TEN)),
|
||||
clientState.incrementPaymentBy(Utils.CENT.divide(BigInteger.TEN)).signature.encodeToBitcoin());
|
||||
serverState.incrementPayment(Utils.CENT.divide(Coin.valueOf(2)).subtract(Utils.CENT.divide(Coin.TEN)),
|
||||
clientState.incrementPaymentBy(Utils.CENT.divide(Coin.TEN)).signature.encodeToBitcoin());
|
||||
|
||||
// Advance time until our we get close enough to lock time that server should rebroadcast
|
||||
Utils.rollMockClock(60*60*22);
|
||||
@ -313,7 +313,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), multisigContract,clientBroadcastedRefund));
|
||||
|
||||
// Make sure we actually had to pay what initialize() told us we would
|
||||
assertEquals(wallet.getBalance(), Utils.CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(2))));
|
||||
assertEquals(wallet.getBalance(), Utils.CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(2))));
|
||||
|
||||
try {
|
||||
// After its expired, we cant still increment payment
|
||||
@ -341,7 +341,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
// Test refund transaction with any number of issues
|
||||
byte[] refundTxBytes = clientState.getIncompleteRefundTransaction().bitcoinSerialize();
|
||||
Transaction refund = new Transaction(params, refundTxBytes);
|
||||
refund.addOutput(BigInteger.ZERO, new ECKey().toAddress(params));
|
||||
refund.addOutput(Coin.ZERO, new ECKey().toAddress(params));
|
||||
try {
|
||||
serverState.provideRefundTransaction(refund, myKey.getPubKey());
|
||||
fail();
|
||||
@ -408,7 +408,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
clientState.fakeSave();
|
||||
assertEquals(PaymentChannelClientState.State.PROVIDE_MULTISIG_CONTRACT_TO_SERVER, clientState.getState());
|
||||
|
||||
try { clientState.incrementPaymentBy(BigInteger.ONE); fail(); } catch (IllegalStateException e) {}
|
||||
try { clientState.incrementPaymentBy(Coin.ONE); fail(); } catch (IllegalStateException e) {}
|
||||
|
||||
byte[] multisigContractSerialized = clientState.getMultisigContract().bitcoinSerialize();
|
||||
|
||||
@ -424,7 +424,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
|
||||
multisigContract = new Transaction(params, multisigContractSerialized);
|
||||
multisigContract.clearOutputs();
|
||||
multisigContract.addOutput(BigInteger.ZERO, ScriptBuilder.createMultiSigOutputScript(2, Lists.newArrayList(myKey, serverKey)));
|
||||
multisigContract.addOutput(Coin.ZERO, ScriptBuilder.createMultiSigOutputScript(2, Lists.newArrayList(myKey, serverKey)));
|
||||
try {
|
||||
serverState.provideMultiSigContract(multisigContract);
|
||||
fail();
|
||||
@ -451,8 +451,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||
|
||||
// Both client and server are now in the ready state. Simulate a few micropayments of 0.005 bitcoins.
|
||||
BigInteger size = halfCoin.divide(BigInteger.TEN).divide(BigInteger.TEN);
|
||||
BigInteger totalPayment = BigInteger.ZERO;
|
||||
Coin size = halfCoin.divide(Coin.TEN).divide(Coin.TEN);
|
||||
Coin totalPayment = Coin.ZERO;
|
||||
try {
|
||||
clientState.incrementPaymentBy(Utils.COIN);
|
||||
fail();
|
||||
@ -510,12 +510,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(serverState.getBestValueToMe(), totalPayment);
|
||||
|
||||
try {
|
||||
clientState.incrementPaymentBy(BigInteger.ONE.negate());
|
||||
clientState.incrementPaymentBy(Coin.ONE.negate());
|
||||
fail();
|
||||
} catch (ValueOutOfRangeException e) {}
|
||||
|
||||
try {
|
||||
clientState.incrementPaymentBy(halfCoin.subtract(size).add(BigInteger.ONE));
|
||||
clientState.incrementPaymentBy(halfCoin.subtract(size).add(Coin.ONE));
|
||||
fail();
|
||||
} catch (ValueOutOfRangeException e) {}
|
||||
}
|
||||
@ -526,7 +526,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
|
||||
// Spend the client wallet's one coin
|
||||
wallet.sendCoinsOffline(Wallet.SendRequest.to(new ECKey().toAddress(params), Utils.COIN));
|
||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||
|
||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), createFakeTx(params, Utils.CENT, myAddress)));
|
||||
assertEquals(Utils.CENT, wallet.getBalance());
|
||||
@ -538,7 +538,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
||||
|
||||
// Clearly ONE is far too small to be useful
|
||||
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()), BigInteger.ONE, EXPIRE_TIME);
|
||||
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()), Coin.ONE, EXPIRE_TIME);
|
||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||
try {
|
||||
clientState.initiate();
|
||||
@ -546,7 +546,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
} catch (ValueOutOfRangeException e) {}
|
||||
|
||||
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()),
|
||||
Transaction.MIN_NONDUST_OUTPUT.subtract(BigInteger.ONE).add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE),
|
||||
Transaction.MIN_NONDUST_OUTPUT.subtract(Coin.ONE).add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE),
|
||||
EXPIRE_TIME);
|
||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||
try {
|
||||
@ -560,14 +560,14 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||
// We'll have to pay REFERENCE_DEFAULT_MIN_TX_FEE twice (multisig+refund), and we'll end up getting back nearly nothing...
|
||||
clientState.initiate();
|
||||
assertEquals(clientState.getRefundTxFees(), Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(2)));
|
||||
assertEquals(clientState.getRefundTxFees(), Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(2)));
|
||||
assertEquals(PaymentChannelClientState.State.INITIATED, clientState.getState());
|
||||
|
||||
// Now actually use a more useful CENT
|
||||
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()), Utils.CENT, EXPIRE_TIME);
|
||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||
clientState.initiate();
|
||||
assertEquals(clientState.getRefundTxFees(), BigInteger.ZERO);
|
||||
assertEquals(clientState.getRefundTxFees(), Coin.ZERO);
|
||||
assertEquals(PaymentChannelClientState.State.INITIATED, clientState.getState());
|
||||
|
||||
// Send the refund tx from client to server and get back the signature.
|
||||
@ -592,16 +592,16 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||
|
||||
// Both client and server are now in the ready state. Simulate a few micropayments
|
||||
BigInteger totalPayment = BigInteger.ZERO;
|
||||
Coin totalPayment = Coin.ZERO;
|
||||
|
||||
// We can send as little as we want - its up to the server to get the fees right
|
||||
byte[] signature = clientState.incrementPaymentBy(BigInteger.ONE).signature.encodeToBitcoin();
|
||||
totalPayment = totalPayment.add(BigInteger.ONE);
|
||||
byte[] signature = clientState.incrementPaymentBy(Coin.ONE).signature.encodeToBitcoin();
|
||||
totalPayment = totalPayment.add(Coin.ONE);
|
||||
serverState.incrementPayment(Utils.CENT.subtract(totalPayment), signature);
|
||||
|
||||
// We can't refund more than the contract is worth...
|
||||
try {
|
||||
serverState.incrementPayment(Utils.CENT.add(BigInteger.ONE), signature);
|
||||
serverState.incrementPayment(Utils.CENT.add(Coin.ONE), signature);
|
||||
fail();
|
||||
} catch (ValueOutOfRangeException e) {}
|
||||
|
||||
@ -609,12 +609,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
// will correct it for us to be larger than the requested amount, to make the change output zero.
|
||||
PaymentChannelClientState.IncrementedPayment payment =
|
||||
clientState.incrementPaymentBy(Utils.CENT.subtract(Transaction.MIN_NONDUST_OUTPUT));
|
||||
assertEquals(Utils.CENT.subtract(BigInteger.ONE), payment.amount);
|
||||
assertEquals(Utils.CENT.subtract(Coin.ONE), payment.amount);
|
||||
totalPayment = totalPayment.add(payment.amount);
|
||||
|
||||
// The server also won't accept it if we do that.
|
||||
try {
|
||||
serverState.incrementPayment(Transaction.MIN_NONDUST_OUTPUT.subtract(BigInteger.ONE), signature);
|
||||
serverState.incrementPayment(Transaction.MIN_NONDUST_OUTPUT.subtract(Coin.ONE), signature);
|
||||
fail();
|
||||
} catch (ValueOutOfRangeException e) {}
|
||||
|
||||
@ -678,9 +678,9 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||
|
||||
// Both client and server are now in the ready state, split the channel in half
|
||||
byte[] signature = clientState.incrementPaymentBy(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(BigInteger.ONE))
|
||||
byte[] signature = clientState.incrementPaymentBy(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(Coin.ONE))
|
||||
.signature.encodeToBitcoin();
|
||||
BigInteger totalRefund = Utils.CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(BigInteger.ONE));
|
||||
Coin totalRefund = Utils.CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(Coin.ONE));
|
||||
serverState.incrementPayment(totalRefund, signature);
|
||||
|
||||
// We need to pay MIN_TX_FEE, but we only have MIN_NONDUST_OUTPUT
|
||||
@ -703,8 +703,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertTrue(e.getMessage().contains("more in fees"));
|
||||
}
|
||||
|
||||
signature = clientState.incrementPaymentBy(BigInteger.ONE.shiftLeft(1)).signature.encodeToBitcoin();
|
||||
totalRefund = totalRefund.subtract(BigInteger.ONE.shiftLeft(1));
|
||||
signature = clientState.incrementPaymentBy(Coin.ONE.shiftLeft(1)).signature.encodeToBitcoin();
|
||||
totalRefund = totalRefund.subtract(Coin.ONE.shiftLeft(1));
|
||||
serverState.incrementPayment(totalRefund, signature);
|
||||
|
||||
// And settle the channel.
|
||||
@ -772,8 +772,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
assertFalse(clientWalletMultisigContract.getInput(0).getConnectedOutput().getSpentBy().getParentTransaction().getHash().equals(refund.getHash()));
|
||||
|
||||
// Both client and server are now in the ready state. Simulate a few micropayments of 0.005 bitcoins.
|
||||
BigInteger size = halfCoin.divide(BigInteger.TEN).divide(BigInteger.TEN);
|
||||
BigInteger totalPayment = BigInteger.ZERO;
|
||||
Coin size = halfCoin.divide(Coin.TEN).divide(Coin.TEN);
|
||||
Coin totalPayment = Coin.ZERO;
|
||||
for (int i = 0; i < 5; i++) {
|
||||
byte[] signature = clientState.incrementPaymentBy(size).signature.encodeToBitcoin();
|
||||
totalPayment = totalPayment.add(size);
|
||||
|
@ -20,7 +20,6 @@ import static org.junit.Assert.assertArrayEquals;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.security.KeyStore;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.X509Certificate;
|
||||
@ -35,6 +34,7 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import com.google.bitcoin.core.Address;
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.ECKey;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.Transaction;
|
||||
@ -50,7 +50,7 @@ public class PaymentProtocolTest {
|
||||
|
||||
// static test data
|
||||
private static final NetworkParameters NETWORK_PARAMS = UnitTestParams.get();
|
||||
private static final BigInteger AMOUNT = BigInteger.ONE;
|
||||
private static final Coin AMOUNT = Coin.ONE;
|
||||
private static final Address TO_ADDRESS = new ECKey().toAddress(NETWORK_PARAMS);
|
||||
private static final String MEMO = "memo";
|
||||
private static final String PAYMENT_URL = "https://example.com";
|
||||
@ -128,7 +128,7 @@ public class PaymentProtocolTest {
|
||||
// Create
|
||||
List<Transaction> transactions = new LinkedList<Transaction>();
|
||||
transactions.add(FakeTxBuilder.createFakeTx(NETWORK_PARAMS, AMOUNT, TO_ADDRESS));
|
||||
BigInteger refundAmount = BigInteger.ONE;
|
||||
Coin refundAmount = Coin.ONE;
|
||||
Address refundAddress = new ECKey().toAddress(NETWORK_PARAMS);
|
||||
Payment payment = PaymentProtocol.createPaymentMessage(transactions, refundAmount, refundAddress, MEMO,
|
||||
MERCHANT_DATA);
|
||||
|
@ -28,7 +28,6 @@ import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.math.BigInteger;
|
||||
import java.net.URL;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Date;
|
||||
@ -45,7 +44,7 @@ public class PaymentSessionTest {
|
||||
private ECKey serverKey;
|
||||
private Transaction tx;
|
||||
private TransactionOutput outputToMe;
|
||||
BigInteger nanoCoins = Utils.toNanoCoins(1, 0);
|
||||
Coin nanoCoins = Utils.toNanoCoins(1, 0);
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
@ -97,7 +96,7 @@ public class PaymentSessionTest {
|
||||
.setSerializedPaymentDetails(paymentDetails.toByteString())
|
||||
.build();
|
||||
MockPaymentSession paymentSession = new MockPaymentSession(paymentRequest);
|
||||
assertEquals(BigInteger.ZERO, paymentSession.getValue());
|
||||
assertEquals(Coin.ZERO, paymentSession.getValue());
|
||||
assertNull(paymentSession.getPaymentUrl());
|
||||
assertNull(paymentSession.getMemo());
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ public class WalletProtobufSerializerTest {
|
||||
// Check the base case of a wallet with one key and no transactions.
|
||||
Wallet wallet1 = roundTrip(myWallet);
|
||||
assertEquals(0, wallet1.getTransactions(true).size());
|
||||
assertEquals(BigInteger.ZERO, wallet1.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet1.getBalance());
|
||||
assertArrayEquals(myKey.getPubKey(),
|
||||
wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getPubKey());
|
||||
assertArrayEquals(myKey.getPrivKeyBytes(),
|
||||
@ -92,7 +92,7 @@ public class WalletProtobufSerializerTest {
|
||||
@Test
|
||||
public void oneTx() throws Exception {
|
||||
// Check basic tx serialization.
|
||||
BigInteger v1 = Utils.toNanoCoins(1, 0);
|
||||
Coin v1 = Utils.toNanoCoins(1, 0);
|
||||
Transaction t1 = createFakeTx(params, v1, myAddress);
|
||||
t1.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByName("1.2.3.4")));
|
||||
t1.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByName("5.6.7.8")));
|
||||
@ -136,7 +136,7 @@ public class WalletProtobufSerializerTest {
|
||||
assertEquals(1, wallet1.getTransactions(true).size());
|
||||
Transaction t1 = wallet1.getTransaction(doubleSpends.t1.getHash());
|
||||
assertEquals(ConfidenceType.DEAD, t1.getConfidence().getConfidenceType());
|
||||
assertEquals(BigInteger.ZERO, wallet1.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet1.getBalance());
|
||||
|
||||
// TODO: Wallet should store overriding transactions even if they are not wallet-relevant.
|
||||
// assertEquals(doubleSpends.t2, t1.getConfidence().getOverridingTransaction());
|
||||
@ -192,7 +192,7 @@ public class WalletProtobufSerializerTest {
|
||||
final ArrayList<Transaction> txns = new ArrayList<Transaction>(2);
|
||||
myWallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
txns.add(tx);
|
||||
}
|
||||
});
|
||||
@ -275,7 +275,7 @@ public class WalletProtobufSerializerTest {
|
||||
public void testRoundTripNormalWallet() throws Exception {
|
||||
Wallet wallet1 = roundTrip(myWallet);
|
||||
assertEquals(0, wallet1.getTransactions(true).size());
|
||||
assertEquals(BigInteger.ZERO, wallet1.getBalance());
|
||||
assertEquals(Coin.ZERO, wallet1.getBalance());
|
||||
assertArrayEquals(myKey.getPubKey(),
|
||||
wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getPubKey());
|
||||
assertArrayEquals(myKey.getPrivKeyBytes(),
|
||||
|
@ -25,7 +25,6 @@ import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ -97,7 +96,7 @@ public class DefaultCoinSelectorTest extends TestWithWallet {
|
||||
Transaction t1 = checkNotNull(sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN));
|
||||
// Padding block.
|
||||
wallet.notifyNewBestBlock(FakeTxBuilder.createFakeBlock(blockStore).storedBlock);
|
||||
final BigInteger TWO_COINS = Utils.COIN.multiply(BigInteger.valueOf(2));
|
||||
final Coin TWO_COINS = Utils.COIN.multiply(Coin.valueOf(2));
|
||||
Transaction t2 = checkNotNull(sendMoneyToWallet(TWO_COINS, AbstractBlockChain.NewBlockType.BEST_CHAIN));
|
||||
Transaction t3 = checkNotNull(sendMoneyToWallet(Utils.CENT, AbstractBlockChain.NewBlockType.BEST_CHAIN));
|
||||
|
||||
|
@ -17,8 +17,6 @@
|
||||
|
||||
package com.google.bitcoin.wallet;
|
||||
|
||||
import java.math.BigInteger;
|
||||
|
||||
import com.google.bitcoin.core.*;
|
||||
import com.google.bitcoin.params.MainNetParams;
|
||||
import com.google.bitcoin.script.ScriptBuilder;
|
||||
@ -136,7 +134,7 @@ public class DefaultRiskAnalysisTest {
|
||||
|
||||
Transaction dustTx = new Transaction(params);
|
||||
dustTx.addInput(params.getGenesisBlock().getTransactions().get(0).getOutput(0));
|
||||
dustTx.addOutput(BigInteger.ONE, key1); // 1 Satoshi
|
||||
dustTx.addOutput(Coin.ONE, key1); // 1 Satoshi
|
||||
assertEquals(RiskAnalysis.Result.NON_STANDARD, DefaultRiskAnalysis.FACTORY.create(wallet, dustTx, NO_DEPS).analyze());
|
||||
|
||||
Transaction edgeCaseTx = new Transaction(params);
|
||||
|
@ -7,7 +7,6 @@ import com.google.bitcoin.utils.BriefLogFormatter;
|
||||
import com.google.bitcoin.utils.Threading;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* This is a little test app that waits for a coin on a local regtest node, then generates two transactions that double
|
||||
@ -28,7 +27,7 @@ public class DoubleSpend {
|
||||
|
||||
kit.wallet().getBalanceFuture(Utils.COIN, Wallet.BalanceType.AVAILABLE).get();
|
||||
Transaction tx1 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), Utils.CENT);
|
||||
Transaction tx2 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), Utils.CENT.add(BigInteger.TEN));
|
||||
Transaction tx2 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), Utils.CENT.add(Coin.TEN));
|
||||
final Peer peer = kit.peerGroup().getConnectedPeers().get(0);
|
||||
peer.addEventListener(new AbstractPeerEventListener() {
|
||||
@Override
|
||||
|
@ -34,14 +34,13 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.ExecutionException;
|
||||
|
||||
import static com.google.bitcoin.core.Coin.TEN;
|
||||
import static com.google.bitcoin.core.Utils.CENT;
|
||||
import static java.math.BigInteger.TEN;
|
||||
|
||||
/**
|
||||
* Simple client that connects to the given host, opens a channel, and pays one cent.
|
||||
@ -49,7 +48,7 @@ import static java.math.BigInteger.TEN;
|
||||
public class ExamplePaymentChannelClient {
|
||||
private static final org.slf4j.Logger log = LoggerFactory.getLogger(ExamplePaymentChannelClient.class);
|
||||
private WalletAppKit appKit;
|
||||
private final BigInteger channelSize;
|
||||
private final Coin channelSize;
|
||||
private final ECKey myKey;
|
||||
private final NetworkParameters params;
|
||||
|
||||
@ -124,7 +123,7 @@ public class ExamplePaymentChannelClient {
|
||||
// we are not allowed to have payment channels that pay nothing at all.
|
||||
log.info("Success! Trying to make {} micropayments. Already paid {} satoshis on this channel",
|
||||
times, client.state().getValueSpent());
|
||||
final BigInteger MICROPAYMENT_SIZE = CENT.divide(TEN);
|
||||
final Coin MICROPAYMENT_SIZE = CENT.divide(TEN);
|
||||
for (int i = 0; i < times; i++) {
|
||||
try {
|
||||
// Wait because the act of making a micropayment is async, and we're not allowed to overlap.
|
||||
@ -164,11 +163,11 @@ public class ExamplePaymentChannelClient {
|
||||
latch.await();
|
||||
}
|
||||
|
||||
private void waitForSufficientBalance(BigInteger amount) {
|
||||
private void waitForSufficientBalance(Coin amount) {
|
||||
// Not enough money in the wallet.
|
||||
BigInteger amountPlusFee = amount.add(Wallet.SendRequest.DEFAULT_FEE_PER_KB);
|
||||
Coin amountPlusFee = amount.add(Wallet.SendRequest.DEFAULT_FEE_PER_KB);
|
||||
// ESTIMATED because we don't really need to wait for confirmation.
|
||||
ListenableFuture<BigInteger> balanceFuture = appKit.wallet().getBalanceFuture(amountPlusFee, Wallet.BalanceType.ESTIMATED);
|
||||
ListenableFuture<Coin> balanceFuture = appKit.wallet().getBalanceFuture(amountPlusFee, Wallet.BalanceType.ESTIMATED);
|
||||
if (!balanceFuture.isDone()) {
|
||||
System.out.println("Please send " + Utils.bitcoinValueToFriendlyString(amountPlusFee) +
|
||||
" BTC to " + myKey.toAddress(params));
|
||||
|
@ -17,6 +17,7 @@
|
||||
|
||||
package com.google.bitcoin.examples;
|
||||
|
||||
import com.google.bitcoin.core.Coin;
|
||||
import com.google.bitcoin.core.NetworkParameters;
|
||||
import com.google.bitcoin.core.Sha256Hash;
|
||||
import com.google.bitcoin.core.VerificationException;
|
||||
@ -26,10 +27,10 @@ import com.google.bitcoin.params.RegTestParams;
|
||||
import com.google.bitcoin.protocols.channels.*;
|
||||
import com.google.bitcoin.utils.BriefLogFormatter;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigInteger;
|
||||
import java.net.SocketAddress;
|
||||
import java.util.List;
|
||||
|
||||
@ -71,7 +72,7 @@ public class ExamplePaymentChannelServer implements PaymentChannelServerListener
|
||||
// We provide a peer group, a wallet, a timeout in seconds, the amount we require to start a channel and
|
||||
// an implementation of HandlerFactory, which we just implement ourselves.
|
||||
final int MILLI = 100000;
|
||||
new PaymentChannelServerListener(appKit.peerGroup(), appKit.wallet(), 15, BigInteger.valueOf(MILLI), this).bindAndStart(4242);
|
||||
new PaymentChannelServerListener(appKit.peerGroup(), appKit.wallet(), 15, Coin.valueOf(MILLI), this).bindAndStart(4242);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -101,7 +102,7 @@ public class ExamplePaymentChannelServer implements PaymentChannelServerListener
|
||||
}
|
||||
|
||||
@Override
|
||||
public void paymentIncrease(BigInteger by, BigInteger to) {
|
||||
public void paymentIncrease(Coin by, Coin to) {
|
||||
log.info("Client {} paid increased payment by {} for a total of " + to.toString(), clientAddress, by);
|
||||
}
|
||||
|
||||
|
@ -29,7 +29,6 @@ import com.google.common.util.concurrent.Futures;
|
||||
import com.google.common.util.concurrent.MoreExecutors;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigInteger;
|
||||
|
||||
import static com.google.common.base.Preconditions.checkNotNull;
|
||||
|
||||
@ -81,11 +80,11 @@ public class ForwardingService {
|
||||
// We want to know when we receive money.
|
||||
kit.wallet().addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet w, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet w, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
// Runs in the dedicated "user thread" (see bitcoinj docs for more info on this).
|
||||
//
|
||||
// The transaction "tx" can either be pending, or included into a block (we didn't see the broadcast).
|
||||
BigInteger value = tx.getValueSentToMe(w);
|
||||
Coin value = tx.getValueSentToMe(w);
|
||||
System.out.println("Received tx for " + Utils.bitcoinValueToFriendlyString(value) + ": " + tx);
|
||||
System.out.println("Transaction will be forwarded after it confirms.");
|
||||
// Wait until it's made it into the block chain (may run immediately if it's already there).
|
||||
@ -121,10 +120,10 @@ public class ForwardingService {
|
||||
|
||||
private static void forwardCoins(Transaction tx) {
|
||||
try {
|
||||
BigInteger value = tx.getValueSentToMe(kit.wallet());
|
||||
Coin value = tx.getValueSentToMe(kit.wallet());
|
||||
System.out.println("Forwarding " + Utils.bitcoinValueToFriendlyString(value) + " BTC");
|
||||
// Now send the coins back! Send with a small fee attached to ensure rapid confirmation.
|
||||
final BigInteger amountToSend = value.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
||||
final Coin amountToSend = value.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
||||
final Wallet.SendResult sendResult = kit.wallet().sendCoins(kit.peerGroup(), forwardingAddress, amountToSend);
|
||||
checkNotNull(sendResult); // We should never try to send more coins than we have!
|
||||
System.out.println("Sending ...");
|
||||
|
@ -23,7 +23,6 @@ import com.google.bitcoin.store.BlockStore;
|
||||
import com.google.bitcoin.store.MemoryBlockStore;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigInteger;
|
||||
import java.net.InetAddress;
|
||||
|
||||
/**
|
||||
@ -46,7 +45,7 @@ public class RefreshWallet {
|
||||
|
||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||
@Override
|
||||
public synchronized void onCoinsReceived(Wallet w, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public synchronized void onCoinsReceived(Wallet w, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
System.out.println("\nReceived tx " + tx.getHashAsString());
|
||||
System.out.println(tx.toString());
|
||||
}
|
||||
|
@ -8,7 +8,6 @@ import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.io.File;
|
||||
import java.math.BigInteger;
|
||||
|
||||
/**
|
||||
* A program that sends a transaction with the specified fee and measures how long it takes to confirm.
|
||||
@ -26,7 +25,7 @@ public class TestFeeLevel {
|
||||
return;
|
||||
}
|
||||
|
||||
BigInteger feeToTest = new BigInteger(args[0]);
|
||||
Coin feeToTest = Coin.valueOf(Long.parseLong(args[0]));
|
||||
|
||||
kit = new WalletAppKit(PARAMS, new File("."), "testfeelevel");
|
||||
kit.startAsync();
|
||||
@ -39,7 +38,7 @@ public class TestFeeLevel {
|
||||
}
|
||||
}
|
||||
|
||||
private static void go(BigInteger feeToTest) throws InterruptedException, java.util.concurrent.ExecutionException, InsufficientMoneyException {
|
||||
private static void go(Coin feeToTest) throws InterruptedException, java.util.concurrent.ExecutionException, InsufficientMoneyException {
|
||||
kit.peerGroup().setMaxConnections(50);
|
||||
|
||||
final Address address = kit.wallet().currentReceiveKey().toAddress(PARAMS);
|
||||
|
@ -124,9 +124,9 @@ public class WalletTool {
|
||||
value = s;
|
||||
}
|
||||
|
||||
public boolean matchBitcoins(BigInteger comparison) {
|
||||
public boolean matchBitcoins(Coin comparison) {
|
||||
try {
|
||||
BigInteger units = Utils.toNanoCoins(value);
|
||||
Coin units = Utils.toNanoCoins(value);
|
||||
switch (type) {
|
||||
case LT: return comparison.compareTo(units) < 0;
|
||||
case GT: return comparison.compareTo(units) > 0;
|
||||
@ -323,7 +323,7 @@ public class WalletTool {
|
||||
System.err.println("--payment-request and --output cannot be used together.");
|
||||
return;
|
||||
} else if (options.has(outputFlag)) {
|
||||
BigInteger fee = BigInteger.ZERO;
|
||||
Coin fee = Coin.ZERO;
|
||||
if (options.has("fee")) {
|
||||
fee = Utils.toNanoCoins((String)options.valueOf("fee"));
|
||||
}
|
||||
@ -413,7 +413,7 @@ public class WalletTool {
|
||||
}
|
||||
}
|
||||
|
||||
private static void send(List<String> outputs, BigInteger fee, String lockTimeStr, boolean allowUnconfirmed) throws VerificationException {
|
||||
private static void send(List<String> outputs, Coin fee, String lockTimeStr, boolean allowUnconfirmed) throws VerificationException {
|
||||
try {
|
||||
// Convert the input strings to outputs.
|
||||
Transaction t = new Transaction(params);
|
||||
@ -425,7 +425,7 @@ public class WalletTool {
|
||||
}
|
||||
String destination = parts[0];
|
||||
try {
|
||||
BigInteger value = Utils.toNanoCoins(parts[1]);
|
||||
Coin value = Utils.toNanoCoins(parts[1]);
|
||||
if (destination.startsWith("0")) {
|
||||
// Treat as a raw public key.
|
||||
byte[] pubKey = new BigInteger(destination, 16).toByteArray();
|
||||
@ -567,7 +567,7 @@ public class WalletTool {
|
||||
private static void send(PaymentSession session) {
|
||||
try {
|
||||
System.out.println("Payment Request");
|
||||
System.out.println("Amount: " + session.getValue().doubleValue() / 100000 + "mBTC");
|
||||
System.out.println("Coin: " + session.getValue().doubleValue() / 100000 + "mBTC");
|
||||
System.out.println("Date: " + session.getDate());
|
||||
System.out.println("Memo: " + session.getMemo());
|
||||
if (session.pkiVerificationData != null) {
|
||||
@ -636,15 +636,15 @@ public class WalletTool {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
||||
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||
// Runs in a peer thread.
|
||||
super.onCoinsReceived(wallet, tx, prevBalance, newBalance);
|
||||
handleTx(tx);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance,
|
||||
BigInteger newBalance) {
|
||||
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance,
|
||||
Coin newBalance) {
|
||||
// Runs in a peer thread.
|
||||
super.onCoinsSent(wallet, tx, prevBalance, newBalance);
|
||||
handleTx(tx);
|
||||
@ -677,7 +677,7 @@ public class WalletTool {
|
||||
public synchronized void onChange() {
|
||||
super.onChange();
|
||||
saveWallet(walletFile);
|
||||
BigInteger balance = wallet.getBalance(Wallet.BalanceType.ESTIMATED);
|
||||
Coin balance = wallet.getBalance(Wallet.BalanceType.ESTIMATED);
|
||||
if (condition.matchBitcoins(balance)) {
|
||||
System.out.println(Utils.bitcoinValueToFriendlyString(balance));
|
||||
latch.countDown();
|
||||
|
Loading…
Reference in New Issue
Block a user