Move coin related methods and constants from Utils into Coin.

This commit is contained in:
Andreas Schildbach 2014-04-25 23:19:42 +02:00 committed by Mike Hearn
parent e2140c5cf8
commit eb81b0c815
36 changed files with 613 additions and 588 deletions

View File

@ -35,6 +35,7 @@ import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static com.google.bitcoin.core.Utils.doubleDigest;
import static com.google.bitcoin.core.Utils.doubleDigestTwoBuffers;
@ -167,7 +168,7 @@ public class Block extends Message {
* </p>
*/
public Coin getBlockInflation(int height) {
return Utils.toNanoCoins(50, 0).shiftRight(height / params.getSubsidyDecreaseBlockCount());
return toNanoCoins(50, 0).shiftRight(height / params.getSubsidyDecreaseBlockCount());
}
private void readObject(ObjectInputStream ois) throws ClassNotFoundException, IOException {
@ -981,7 +982,7 @@ public class Block extends Message {
*/
@VisibleForTesting
public Block createNextBlock(Address to, long time) {
return createNextBlock(to, null, time, pubkeyForTesting, Utils.toNanoCoins(50, 0));
return createNextBlock(to, null, time, pubkeyForTesting, toNanoCoins(50, 0));
}
/**
@ -997,7 +998,7 @@ public class Block extends Message {
if (to != null) {
// Add a transaction paying 50 coins to the "to" address.
Transaction t = new Transaction(params);
t.addOutput(new TransactionOutput(params, t, Utils.toNanoCoins(50, 0), to));
t.addOutput(new TransactionOutput(params, t, toNanoCoins(50, 0), to));
// The input does not really need to be a valid signature, as long as it has the right general form.
TransactionInput input;
if (prevOut == null) {
@ -1032,7 +1033,7 @@ public class Block extends Message {
@VisibleForTesting
public Block createNextBlock(@Nullable Address to, TransactionOutPoint prevOut) {
return createNextBlock(to, prevOut, Utils.currentTimeSeconds(), pubkeyForTesting, Utils.toNanoCoins(50, 0));
return createNextBlock(to, prevOut, Utils.currentTimeSeconds(), pubkeyForTesting, toNanoCoins(50, 0));
}
@VisibleForTesting
@ -1042,7 +1043,7 @@ public class Block extends Message {
@VisibleForTesting
public Block createNextBlock(@Nullable Address to) {
return createNextBlock(to, Utils.toNanoCoins(50, 0));
return createNextBlock(to, toNanoCoins(50, 0));
}
@VisibleForTesting
@ -1056,7 +1057,7 @@ public class Block extends Message {
*/
@VisibleForTesting
Block createNextBlockWithCoinbase(byte[] pubKey) {
return createNextBlock(null, null, Utils.currentTimeSeconds(), pubKey, Utils.toNanoCoins(50, 0));
return createNextBlock(null, null, Utils.currentTimeSeconds(), pubKey, toNanoCoins(50, 0));
}
@VisibleForTesting

View File

@ -16,7 +16,10 @@
package com.google.bitcoin.core;
import static com.google.common.base.Preconditions.checkArgument;
import java.io.Serializable;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.google.common.math.LongMath;
@ -29,6 +32,25 @@ 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);
public static final Coin NEGATIVE_ONE = Coin.valueOf(-1);
/**
* How many "nanocoins" there are in a Bitcoin.
* <p/>
* A nanocoin is the smallest unit that can be transferred using Bitcoin.
* 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 Coin COIN = new Coin("100000000", 10);
/**
* How many "nanocoins" there are in 0.01 BitCoins.
* <p/>
* A nanocoin is the smallest unit that can be transferred using Bitcoin.
* 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 Coin CENT = new Coin("1000000", 10);
private final long value;
@ -110,6 +132,71 @@ public final class Coin implements Comparable<Coin>, Serializable {
return BigInteger.valueOf(value);
}
/**
* Convert an amount expressed in the way humans are used to into nanocoins.<p>
* <p/>
* This takes string in a format understood by {@link BigDecimal#BigDecimal(String)},
* for example "0", "1", "0.10", "1.23E3", "1234.5E-5".
*
* @throws ArithmeticException if you try to specify fractional nanocoins, or nanocoins out of range.
*/
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.");
return bigint;
}
/**
* Convert an amount expressed in the way humans are used to into nanocoins.
*/
public static Coin toNanoCoins(int coins, int cents) {
checkArgument(cents < 100);
checkArgument(cents >= 0);
checkArgument(coins >= 0);
checkArgument(coins < NetworkParameters.MAX_MONEY.divide(COIN).longValue());
Coin bi = Coin.valueOf(coins).multiply(COIN);
bi = bi.add(Coin.valueOf(cents).multiply(CENT));
return bi;
}
/**
* Returns the value as a 0.12 type string. More digits after the decimal place will be used
* if necessary, but two will always be present.
*/
public String toFriendlyString() {
Coin value = this;
boolean negative = value.signum() < 0;
if (negative)
value = value.negate();
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.
int toDelete = 0;
for (int i = formatted.length() - 1; i > decimalPoint + 2; i--) {
if (formatted.charAt(i) == '0')
toDelete++;
else
break;
}
return (negative ? "-" : "") + formatted.substring(0, formatted.length() - toDelete);
}
/**
* <p>
* Returns the value as a plain string denominated in BTC.
* The result is unformatted with no trailing zeroes.
* For instance, a value of 150000 satoshis gives an output string of "0.0015" BTC
* </p>
*/
public String toPlainString() {
BigDecimal valueInBTC = new BigDecimal(toBigInteger()).divide(new BigDecimal(COIN.toBigInteger()));
return valueInBTC.toPlainString();
}
@Override
public String toString() {
return Long.toString(value);

View File

@ -29,7 +29,7 @@ import java.math.BigInteger;
import java.util.HashMap;
import java.util.Map;
import static com.google.bitcoin.core.Utils.COIN;
import static com.google.bitcoin.core.Coin.*;
/**
* <p>NetworkParameters contains the data needed for working with an instantiation of a Bitcoin chain.</p>
@ -110,7 +110,7 @@ public abstract class NetworkParameters implements Serializable {
Script.writeBytes(scriptPubKeyBytes, Hex.decode
("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"));
scriptPubKeyBytes.write(ScriptOpCodes.OP_CHECKSIG);
t.addOutput(new TransactionOutput(n, t, Utils.toNanoCoins(50, 0), scriptPubKeyBytes.toByteArray()));
t.addOutput(new TransactionOutput(n, t, toNanoCoins(50, 0), scriptPubKeyBytes.toByteArray()));
} catch (Exception e) {
// Cannot happen.
throw new RuntimeException(e);

View File

@ -138,7 +138,7 @@ public class StoredTransactionOutput implements Serializable {
}
public String toString() {
return String.format("Stored TxOut of %s (%s:%d)", Utils.bitcoinValueToFriendlyString(value), hash.toString(), index);
return String.format("Stored TxOut of %s (%s:%d)", value.toFriendlyString(), hash.toString(), index);
}
@Override

View File

@ -656,7 +656,7 @@ public class Transaction extends ChildMessage implements Serializable {
Script scriptSig = in.getScriptSig();
s.append(scriptSig);
if (in.getValue() != null)
s.append(" ").append(bitcoinValueToFriendlyString(in.getValue())).append(" BTC");
s.append(" ").append(in.getValue().toFriendlyString()).append(" BTC");
s.append("\n ");
s.append("outpoint:");
final TransactionOutPoint outpoint = in.getOutpoint();
@ -678,7 +678,7 @@ public class Transaction extends ChildMessage implements Serializable {
Script scriptPubKey = out.getScriptPubKey();
s.append(scriptPubKey);
s.append(" ");
s.append(bitcoinValueToFriendlyString(out.getValue()));
s.append(out.getValue().toFriendlyString());
s.append(" BTC");
if (!out.isAvailableForSpending()) {
s.append(" Spent");
@ -1091,7 +1091,7 @@ public class Transaction extends ChildMessage implements Serializable {
// that position are "nulled out". Unintuitively, the value in a "null" transaction is set to -1.
this.outputs = new ArrayList<TransactionOutput>(this.outputs.subList(0, inputIndex + 1));
for (int i = 0; i < inputIndex; i++)
this.outputs.set(i, new TransactionOutput(params, this, NEGATIVE_ONE, new byte[] {}));
this.outputs.set(i, new TransactionOutput(params, this, Coin.NEGATIVE_ONE, new byte[] {}));
// The signature isn't broken by new versions of the transaction issued by other parties.
for (int i = 0; i < inputs.size(); i++)
if (i != inputIndex)

View File

@ -111,7 +111,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
super(params);
// Negative values obviously make no sense, except for -1 which is used as a sentinel value when calculating
// SIGHASH_SINGLE signatures, so unfortunately we have to allow that here.
checkArgument(value.signum() >= 0 || value.equals(Utils.NEGATIVE_ONE), "Negative values not allowed");
checkArgument(value.signum() >= 0 || value.equals(Coin.NEGATIVE_ONE), "Negative values not allowed");
checkArgument(value.compareTo(NetworkParameters.MAX_MONEY) < 0, "Values larger than MAX_MONEY not allowed");
this.value = value;
this.scriptBytes = scriptBytes;
@ -306,7 +306,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
try {
Script script = getScriptPubKey();
StringBuilder buf = new StringBuilder("TxOut of ");
buf.append(Utils.bitcoinValueToFriendlyString(value));
buf.append(value.toFriendlyString());
if (script.isSentToAddress() || script.isPayToScriptHash())
buf.append(" to ").append(script.getToAddress(params));
else if (script.isSentToRawPubKey())

View File

@ -28,7 +28,6 @@ import org.spongycastle.util.encoders.Hex;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
@ -45,7 +44,6 @@ 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 Coin NEGATIVE_ONE = Coin.valueOf(-1);
private static final MessageDigest digest;
static {
try {
@ -59,40 +57,8 @@ public class Utils {
public static final String BITCOIN_SIGNED_MESSAGE_HEADER = "Bitcoin Signed Message:\n";
public static final byte[] BITCOIN_SIGNED_MESSAGE_HEADER_BYTES = BITCOIN_SIGNED_MESSAGE_HEADER.getBytes(Charsets.UTF_8);
// TODO: Replace this nanocoins business with something better.
/**
* How many "nanocoins" there are in a Bitcoin.
* <p/>
* A nanocoin is the smallest unit that can be transferred using Bitcoin.
* 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 Coin COIN = new Coin("100000000", 10);
/**
* How many "nanocoins" there are in 0.01 BitCoins.
* <p/>
* A nanocoin is the smallest unit that can be transferred using Bitcoin.
* 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 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 Coin toNanoCoins(int coins, int cents) {
checkArgument(cents < 100);
checkArgument(cents >= 0);
checkArgument(coins >= 0);
checkArgument(coins < NetworkParameters.MAX_MONEY.divide(Utils.COIN).longValue());
Coin bi = Coin.valueOf(coins).multiply(COIN);
bi = bi.add(Coin.valueOf(cents).multiply(CENT));
return bi;
}
/**
* The regular {@link java.math.BigInteger#toByteArray()} method isn't quite what we often need: it appends a
* leading zero to indicate that the number is positive and may need padding.
@ -113,23 +79,6 @@ public class Utils {
return bytes;
}
/**
* Convert an amount expressed in the way humans are used to into nanocoins.<p>
* <p/>
* This takes string in a format understood by {@link BigDecimal#BigDecimal(String)},
* for example "0", "1", "0.10", "1.23E3", "1234.5E-5".
*
* @throws ArithmeticException if you try to specify fractional nanocoins, or nanocoins out of range.
*/
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("Coin larger than the total quantity of Bitcoins possible specified.");
return bigint;
}
public static void uint32ToByteArrayBE(long val, byte[] out, int offset) {
out[offset + 0] = (byte) (0xFF & (val >> 24));
out[offset + 1] = (byte) (0xFF & (val >> 16));
@ -328,49 +277,6 @@ 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(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.toBigInteger(), 8);
String formatted = bd.toPlainString(); // Don't use scientific notation.
int decimalPoint = formatted.indexOf(".");
// Drop unnecessary zeros from the end.
int toDelete = 0;
for (int i = formatted.length() - 1; i > decimalPoint + 2; i--) {
if (formatted.charAt(i) == '0')
toDelete++;
else
break;
}
return (negative ? "-" : "") + formatted.substring(0, formatted.length() - toDelete);
}
/**
* <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 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(Coin value) {
if (value == null) {
throw new IllegalArgumentException("Value cannot be null");
}
BigDecimal valueInBTC = new BigDecimal(value.toBigInteger()).divide(new BigDecimal(Utils.COIN.toBigInteger()));
return valueInBTC.toPlainString();
}
/**
* MPI encoded numbers are produced by the OpenSSL BN_bn2mpi function. They consist of
* a 4 byte big endian length field, followed by the stated number of bytes representing

View File

@ -56,8 +56,6 @@ import java.util.concurrent.Executor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReentrantLock;
import static com.google.bitcoin.core.Utils.bitcoinValueToFriendlyString;
import static com.google.bitcoin.core.Utils.bitcoinValueToPlainString;
import static com.google.common.base.Preconditions.*;
// To do list:
@ -1098,8 +1096,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
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),
Utils.bitcoinValueToFriendlyString(valueSentToMe)));
" and sends us %s BTC", tx.getHashAsString(), valueSentFromMe.toFriendlyString(),
valueSentToMe.toFriendlyString()));
}
if (tx.getConfidence().getSource().equals(TransactionConfidence.Source.UNKNOWN)) {
log.warn("Wallet received transaction with an unknown source. Consider tagging it!");
@ -1282,7 +1280,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
Coin valueDifference = valueSentToMe.subtract(valueSentFromMe);
log.info("Received tx{} for {} BTC: {} [{}] in block {}", sideChain ? " on a side chain" : "",
bitcoinValueToFriendlyString(valueDifference), tx.getHashAsString(), relativityOffset,
valueDifference.toFriendlyString(), tx.getHashAsString(), relativityOffset,
block != null ? block.getHeader().getHash() : "(unit test)");
// Inform the key chains that the issued keys were observed in a transaction, so they know to
@ -1365,7 +1363,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
// listeners.
if (!insideReorg && bestChain) {
Coin newBalance = getBalance(); // This is slow.
log.info("Balance is now: " + bitcoinValueToFriendlyString(newBalance));
log.info("Balance is now: " + newBalance.toFriendlyString());
if (!wasPending) {
int diff = valueDifference.signum();
// We pick one callback based on the value difference, though a tx can of course both send and receive
@ -2359,7 +2357,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
boolean needAtLeastReferenceFee = false;
if (req.ensureMinRequiredFee && !req.emptyWallet) { // min fee checking is handled later for emptyWallet
for (TransactionOutput output : req.tx.getOutputs())
if (output.getValue().compareTo(Utils.CENT) < 0) {
if (output.getValue().compareTo(Coin.CENT) < 0) {
if (output.getValue().compareTo(output.getMinNonDustValue()) < 0)
throw new DustySendRequested();
needAtLeastReferenceFee = true;
@ -2409,11 +2407,11 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
if (bestChangeOutput != null) {
req.tx.addOutput(bestChangeOutput);
totalOutput = totalOutput.add(bestChangeOutput.getValue());
log.info(" with {} coins change", bitcoinValueToFriendlyString(bestChangeOutput.getValue()));
log.info(" with {} coins change", bestChangeOutput.getValue().toFriendlyString());
}
final Coin calculatedFee = totalInput.subtract(totalOutput);
if (calculatedFee.signum() > 0) {
log.info(" with a fee of {}", bitcoinValueToFriendlyString(calculatedFee));
log.info(" with a fee of {}", calculatedFee.toFriendlyString());
}
// Now shuffle the outputs to obfuscate which is the change.
@ -2453,7 +2451,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
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)
if (output.getValue().compareTo(Coin.CENT) < 0 && fee.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0)
output.setValue(output.getValue().subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(fee)));
return output.getMinNonDustValue().compareTo(output.getValue()) <= 0;
}
@ -2622,7 +2620,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
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)));
estimatedBalance.toPlainString(), availableBalance.toPlainString()));
builder.append(String.format(" %d pending transactions%n", pending.size()));
builder.append(String.format(" %d unspent transactions%n", unspent.size()));
builder.append(String.format(" %d spent transactions%n", spent.size()));
@ -2694,11 +2692,11 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
for (Transaction tx : txns) {
try {
builder.append("Sends ");
builder.append(Utils.bitcoinValueToFriendlyString(tx.getValueSentFromMe(this)));
builder.append(tx.getValueSentFromMe(this).toFriendlyString());
builder.append(" and receives ");
builder.append(Utils.bitcoinValueToFriendlyString(tx.getValueSentToMe(this)));
builder.append(tx.getValueSentToMe(this).toFriendlyString());
builder.append(", total value ");
builder.append(Utils.bitcoinValueToFriendlyString(tx.getValue(this)));
builder.append(tx.getValue(this).toFriendlyString());
builder.append(".\n");
} catch (ScriptException e) {
// Ignore and don't print this line.
@ -2862,7 +2860,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
}
checkState(isConsistent());
final Coin balance = getBalance();
log.info("post-reorg balance is {}", Utils.bitcoinValueToFriendlyString(balance));
log.info("post-reorg balance is {}", balance.toFriendlyString());
// Inform event listeners that a re-org took place.
queueOnReorganize();
insideReorg = false;
@ -3604,10 +3602,10 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
// 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(Coin.ZERO) &&
change.compareTo(Utils.CENT) < 0 && fees.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0) {
change.compareTo(Coin.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;
additionalValueForNextCategory = Utils.CENT;
additionalValueForNextCategory = Coin.CENT;
// If the change is smaller than the fee we want to add, this will be negative
change = change.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(fees));
}
@ -3667,7 +3665,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
// If we are in selection2, we will require at least CENT additional. If we do that, there is no way
// we can end up back here because CENT additional will always get us to 1
checkState(selection2 == null);
checkState(additionalValueForNextCategory.equals(Utils.CENT));
checkState(additionalValueForNextCategory.equals(Coin.CENT));
selection2 = selection;
selection2Change = checkNotNull(changeOutput); // If we get no change in category 2, we are actually in category 3
} else {
@ -3690,7 +3688,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
if (selection3 == null && selection2 == null && selection1 == null) {
checkNotNull(valueMissing);
log.warn("Insufficient value in wallet for send: needed {} more", bitcoinValueToFriendlyString(valueMissing));
log.warn("Insufficient value in wallet for send: needed {} more", valueMissing.toFriendlyString());
throw new InsufficientMoneyException(valueMissing);
}

View File

@ -263,7 +263,7 @@ public class PaymentChannelClientState {
refundTx = new Transaction(params);
refundTx.addInput(multisigOutput).setSequenceNumber(0); // Allow replacement when it's eventually reactivated.
refundTx.setLockTime(expiryTime);
if (totalValue.compareTo(Utils.CENT) < 0) {
if (totalValue.compareTo(Coin.CENT) < 0) {
// Must pay min fee.
final Coin valueAfterFee = totalValue.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
if (Transaction.MIN_NONDUST_OUTPUT.compareTo(valueAfterFee) > 0)

View File

@ -24,9 +24,8 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
/**
* Utility methods for building fake/invalid transactions, often useful for unit testing.
*/
import static com.google.bitcoin.core.Coin.toNanoCoins;
public class FakeTxBuilder {
/**
* Create a fake TX of sufficient realism to exercise the unit tests. Two outputs, one to us, one to somewhere
@ -36,7 +35,7 @@ public class FakeTxBuilder {
Transaction t = new Transaction(params);
TransactionOutput outputToMe = new TransactionOutput(params, t, nanocoins, to);
t.addOutput(outputToMe);
TransactionOutput change = new TransactionOutput(params, t, Utils.toNanoCoins(1, 11), changeOutput);
TransactionOutput change = new TransactionOutput(params, t, toNanoCoins(1, 11), changeOutput);
t.addOutput(change);
// Make a previous tx simply to send us sufficient coins. This prev tx is not really valid but it doesn't
// matter for our purposes.
@ -65,7 +64,7 @@ public class FakeTxBuilder {
Transaction t = new Transaction(params);
TransactionOutput outputToMe = new TransactionOutput(params, t, nanocoins, to);
t.addOutput(outputToMe);
TransactionOutput change = new TransactionOutput(params, t, Utils.toNanoCoins(1, 11), new ECKey());
TransactionOutput change = new TransactionOutput(params, t, toNanoCoins(1, 11), new ECKey());
t.addOutput(change);
// Make a previous tx simply to send us sufficient coins. This prev tx is not really valid but it doesn't
// matter for our purposes.
@ -88,7 +87,7 @@ public class FakeTxBuilder {
Transaction t = new Transaction(params);
TransactionOutput outputToMe = new TransactionOutput(params, t, nanocoins, to);
t.addOutput(outputToMe);
TransactionOutput change = new TransactionOutput(params, t, Utils.toNanoCoins(1, 11), new ECKey().toAddress(params));
TransactionOutput change = new TransactionOutput(params, t, toNanoCoins(1, 11), new ECKey().toAddress(params));
t.addOutput(change);
// Make a feeder tx that sends to the from address specified. This feeder tx is not really valid but it doesn't
// matter for our purposes.
@ -133,7 +132,7 @@ public class FakeTxBuilder {
*/
public static DoubleSpends createFakeDoubleSpendTxns(NetworkParameters params, Address to) {
DoubleSpends doubleSpends = new DoubleSpends();
Coin value = Utils.toNanoCoins(1, 0);
Coin value = toNanoCoins(1, 0);
Address someBadGuy = new ECKey().toAddress(params);
doubleSpends.t1 = new Transaction(params);

View File

@ -22,7 +22,6 @@ 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;
@ -209,7 +208,7 @@ public class BitcoinURI {
if (FIELD_AMOUNT.equals(nameToken)) {
// Decode the amount (contains an optional decimal component to 8dp).
try {
Coin amount = Utils.toNanoCoins(valueToken);
Coin amount = Coin.toNanoCoins(valueToken);
putWithValidation(FIELD_AMOUNT, amount);
} catch (NumberFormatException e) {
throw new OptionalFieldValidationException(String.format("'%s' is not a valid amount", valueToken), e);
@ -342,7 +341,7 @@ public class BitcoinURI {
if (amount != null) {
builder.append(QUESTION_MARK_SEPARATOR).append(FIELD_AMOUNT).append("=");
builder.append(Utils.bitcoinValueToPlainString(amount));
builder.append(amount.toPlainString());
questionMarkHasBeenOutput = true;
}

View File

@ -33,6 +33,7 @@ import java.io.File;
import java.lang.ref.WeakReference;
import java.util.Arrays;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static org.junit.Assert.*;
/**
@ -131,7 +132,7 @@ public abstract class AbstractFullPrunedBlockChainTest
rollingBlock = rollingBlock.createNextBlock(null);
Transaction t = new Transaction(params);
t.addOutput(new TransactionOutput(params, t, Utils.toNanoCoins(50, 0), new byte[] {}));
t.addOutput(new TransactionOutput(params, t, toNanoCoins(50, 0), new byte[] {}));
TransactionInput input = t.addInput(spendableOutput);
// Invalid script.
input.setScriptBytes(new byte[]{});
@ -173,7 +174,7 @@ public abstract class AbstractFullPrunedBlockChainTest
Transaction t = new Transaction(params);
// Entirely invalid scriptPubKey
t.addOutput(new TransactionOutput(params, t, Utils.toNanoCoins(50, 0), new byte[] {}));
t.addOutput(new TransactionOutput(params, t, toNanoCoins(50, 0), new byte[] {}));
t.addSignedInput(spendableOutput, new Script(spendableOutputScriptPubKey), outKey);
rollingBlock.addTransaction(t);
rollingBlock.solve();

View File

@ -33,6 +33,7 @@ import java.math.BigInteger;
import java.text.SimpleDateFormat;
import java.util.Date;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeBlock;
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeTx;
import static org.junit.Assert.*;
@ -123,7 +124,7 @@ public class BlockChainTest {
public void receiveCoins() throws Exception {
// Quick check that we can actually receive coins.
Transaction tx1 = createFakeTx(unitTestParams,
Utils.toNanoCoins(1, 0),
toNanoCoins(1, 0),
wallet.currentReceiveKey().toAddress(unitTestParams));
Block b1 = createFakeBlock(blockStore, tx1).block;
chain.add(b1);
@ -135,7 +136,7 @@ public class BlockChainTest {
// Test that merkle root verification takes place when a relevant transaction is present and doesn't when
// there isn't any such tx present (as an optimization).
Transaction tx1 = createFakeTx(unitTestParams,
Utils.toNanoCoins(1, 0),
toNanoCoins(1, 0),
wallet.currentReceiveKey().toAddress(unitTestParams));
Block b1 = createFakeBlock(blockStore, tx1).block;
chain.add(b1);
@ -150,7 +151,7 @@ public class BlockChainTest {
b1.setMerkleRoot(hash);
}
// Now add a second block with no relevant transactions and then break it.
Transaction tx2 = createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0),
Transaction tx2 = createFakeTx(unitTestParams, toNanoCoins(1, 0),
new ECKey().toAddress(unitTestParams));
Block b2 = createFakeBlock(blockStore, tx2).block;
b2.getMerkleRoot();
@ -270,10 +271,10 @@ public class BlockChainTest {
ECKey key = wallet.freshReceiveKey();
Address addr = key.toAddress(unitTestParams);
// Create a tx that gives us some coins, and another that spends it to someone else in the same block.
Transaction t1 = FakeTxBuilder.createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0), addr);
Transaction t1 = FakeTxBuilder.createFakeTx(unitTestParams, toNanoCoins(1, 0), addr);
Transaction t2 = new Transaction(unitTestParams);
t2.addInput(t1.getOutputs().get(0));
t2.addOutput(Utils.toNanoCoins(2, 0), somebodyElse);
t2.addOutput(toNanoCoins(2, 0), somebodyElse);
b1.addTransaction(t1);
b1.addTransaction(t2);
b1.solve();
@ -301,12 +302,12 @@ public class BlockChainTest {
// The coinbase tx is not yet available to spend.
assertEquals(Coin.ZERO, wallet.getBalance());
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(50, 0));
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), toNanoCoins(50, 0));
assertTrue(!coinbaseTransaction.isMature());
// Attempt to spend the coinbase - this should fail as the coinbase is not mature yet.
try {
wallet.createSend(addressToSendTo, Utils.toNanoCoins(49, 0));
wallet.createSend(addressToSendTo, toNanoCoins(49, 0));
fail();
} catch (InsufficientMoneyException e) {
}
@ -314,7 +315,7 @@ public class BlockChainTest {
// Check that the coinbase is unavailable to spend for the next spendableCoinbaseDepth - 2 blocks.
for (int i = 0; i < unitTestParams.getSpendableCoinbaseDepth() - 2; i++) {
// Non relevant tx - just for fake block creation.
Transaction tx2 = createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0),
Transaction tx2 = createFakeTx(unitTestParams, toNanoCoins(1, 0),
new ECKey().toAddress(unitTestParams));
Block b2 = createFakeBlock(blockStore, tx2).block;
@ -322,47 +323,47 @@ public class BlockChainTest {
// Wallet still does not have the coinbase transaction available for spend.
assertEquals(Coin.ZERO, wallet.getBalance());
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(50, 0));
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), toNanoCoins(50, 0));
// The coinbase transaction is still not mature.
assertTrue(!coinbaseTransaction.isMature());
// Attempt to spend the coinbase - this should fail.
try {
wallet.createSend(addressToSendTo, Utils.toNanoCoins(49, 0));
wallet.createSend(addressToSendTo, toNanoCoins(49, 0));
fail();
} catch (InsufficientMoneyException e) {
}
}
// Give it one more block - should now be able to spend coinbase transaction. Non relevant tx.
Transaction tx3 = createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0), new ECKey().toAddress(unitTestParams));
Transaction tx3 = createFakeTx(unitTestParams, toNanoCoins(1, 0), new ECKey().toAddress(unitTestParams));
Block b3 = createFakeBlock(blockStore, tx3).block;
chain.add(b3);
// Wallet now has the coinbase transaction available for spend.
assertEquals(wallet.getBalance(), Utils.toNanoCoins(50, 0));
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(50, 0));
assertEquals(wallet.getBalance(), toNanoCoins(50, 0));
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), toNanoCoins(50, 0));
assertTrue(coinbaseTransaction.isMature());
// Create a spend with the coinbase BTC to the address in the second wallet - this should now succeed.
Transaction coinbaseSend2 = wallet.createSend(addressToSendTo, Utils.toNanoCoins(49, 0));
Transaction coinbaseSend2 = wallet.createSend(addressToSendTo, toNanoCoins(49, 0));
assertNotNull(coinbaseSend2);
// Commit the coinbaseSpend to the first wallet and check the balances decrement.
wallet.commitTx(coinbaseSend2);
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(1, 0));
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), toNanoCoins(1, 0));
// Available balance is zero as change has not been received from a block yet.
assertEquals(wallet.getBalance(BalanceType.AVAILABLE), Utils.toNanoCoins(0, 0));
assertEquals(wallet.getBalance(BalanceType.AVAILABLE), toNanoCoins(0, 0));
// Give it one more block - change from coinbaseSpend should now be available in the first wallet.
Block b4 = createFakeBlock(blockStore, coinbaseSend2).block;
chain.add(b4);
assertEquals(wallet.getBalance(BalanceType.AVAILABLE), Utils.toNanoCoins(1, 0));
assertEquals(wallet.getBalance(BalanceType.AVAILABLE), toNanoCoins(1, 0));
// Check the balances in the second wallet.
assertEquals(wallet2.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(49, 0));
assertEquals(wallet2.getBalance(BalanceType.AVAILABLE), Utils.toNanoCoins(49, 0));
assertEquals(wallet2.getBalance(BalanceType.ESTIMATED), toNanoCoins(49, 0));
assertEquals(wallet2.getBalance(BalanceType.AVAILABLE), toNanoCoins(49, 0));
}
// Some blocks from the test net.

View File

@ -36,6 +36,7 @@ import java.util.ArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import static com.google.bitcoin.core.Coin.*;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.junit.Assert.*;
@ -93,7 +94,7 @@ public class ChainSplitTest {
assertFalse(reorgHappened.get());
assertEquals(2, walletChanged.get());
// We got two blocks which sent 50 coins each to us.
assertEquals("100.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("100.00", wallet.getBalance().toFriendlyString());
// We now have the following chain:
// genesis -> b1 -> b2
//
@ -108,7 +109,7 @@ public class ChainSplitTest {
Threading.waitForUserCode();
assertFalse(reorgHappened.get()); // No re-org took place.
assertEquals(2, walletChanged.get());
assertEquals("100.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("100.00", wallet.getBalance().toFriendlyString());
// Check we can handle multi-way splits: this is almost certainly going to be extremely rare, but we have to
// handle it anyway. The same transaction appears in b7/b8 (side chain) but not b2 or b3.
// genesis -> b1--> b2
@ -127,7 +128,7 @@ public class ChainSplitTest {
assertEquals(2, wallet.getTransaction(tHash).getAppearsInHashes().size());
assertFalse(reorgHappened.get()); // No re-org took place.
assertEquals(5, walletChanged.get());
assertEquals("100.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("100.00", wallet.getBalance().toFriendlyString());
// Now we add another block to make the alternative chain longer.
assertTrue(chain.add(b3.createNextBlock(someOtherGuy)));
Threading.waitForUserCode();
@ -139,7 +140,7 @@ public class ChainSplitTest {
// \-> b3 -> b4
// We lost some coins! b2 is no longer a part of the best chain so our available balance should drop to 50.
// It's now pending reconfirmation.
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("50.00", wallet.getBalance().toFriendlyString());
// ... and back to the first chain.
Block b5 = b2.createNextBlock(coinsTo);
Block b6 = b5.createNextBlock(coinsTo);
@ -152,7 +153,7 @@ public class ChainSplitTest {
Threading.waitForUserCode();
assertTrue(reorgHappened.get());
assertEquals(9, walletChanged.get());
assertEquals("200.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("200.00", wallet.getBalance().toFriendlyString());
}
@Test
@ -171,7 +172,7 @@ public class ChainSplitTest {
assertTrue(chain.add(b3));
assertEquals(Coin.ZERO, wallet.getBalance());
assertTrue(chain.add(b4));
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("50.00", wallet.getBalance().toFriendlyString());
}
@Test
@ -179,16 +180,16 @@ public class ChainSplitTest {
// Check that we can handle our own spends being rolled back by a fork.
Block b1 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
chain.add(b1);
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("50.00", wallet.getBalance().toFriendlyString());
Address dest = new ECKey().toAddress(unitTestParams);
Transaction spend = wallet.createSend(dest, Utils.toNanoCoins(10, 0));
Transaction spend = wallet.createSend(dest, toNanoCoins(10, 0));
wallet.commitTx(spend);
// Waiting for confirmation ... make it eligible for selection.
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());
assertEquals(Utils.toNanoCoins(40, 0), wallet.getBalance());
assertEquals(toNanoCoins(40, 0), wallet.getBalance());
Block b2 = b1.createNextBlock(someOtherGuy);
b2.addTransaction(spend);
b2.solve();
@ -202,7 +203,7 @@ public class ChainSplitTest {
chain.add(b3);
chain.add(b4);
// b4 causes a re-org that should make our spend go pending again.
assertEquals(Utils.toNanoCoins(40, 0), wallet.getBalance());
assertEquals(toNanoCoins(40, 0), wallet.getBalance());
assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
}
@ -213,9 +214,9 @@ public class ChainSplitTest {
// keys are being shared between wallets.
Block b1 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
chain.add(b1);
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("50.00", wallet.getBalance().toFriendlyString());
Address dest = new ECKey().toAddress(unitTestParams);
Transaction spend = wallet.createSend(dest, Utils.toNanoCoins(50, 0));
Transaction spend = wallet.createSend(dest, toNanoCoins(50, 0));
// We do NOT confirm the spend here. That means it's not considered to be pending because createSend is
// stateless. For our purposes it is as if some other program with our keys created the tx.
//
@ -228,13 +229,13 @@ public class ChainSplitTest {
b3.solve();
chain.add(roundtrip(b3));
// The external spend is now pending.
assertEquals(Utils.toNanoCoins(0, 0), wallet.getBalance());
assertEquals(toNanoCoins(0, 0), wallet.getBalance());
Transaction tx = wallet.getTransaction(spend.getHash());
assertEquals(ConfidenceType.PENDING, tx.getConfidence().getConfidenceType());
Block b4 = b3.createNextBlock(someOtherGuy);
chain.add(b4);
// The external spend is now active.
assertEquals(Utils.toNanoCoins(0, 0), wallet.getBalance());
assertEquals(toNanoCoins(0, 0), wallet.getBalance());
assertEquals(ConfidenceType.BUILDING, tx.getConfidence().getConfidenceType());
}
@ -244,7 +245,7 @@ public class ChainSplitTest {
Block b1 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
chain.add(b1);
final Transaction t = b1.transactions.get(1);
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("50.00", wallet.getBalance().toFriendlyString());
// genesis -> b1
// -> b2
Block b2 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
@ -254,13 +255,13 @@ public class ChainSplitTest {
b2.addTransaction(t);
b2.solve();
chain.add(roundtrip(b2));
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("50.00", wallet.getBalance().toFriendlyString());
assertTrue(wallet.isConsistent());
assertEquals(2, wallet.getTransaction(t.getHash()).getAppearsInHashes().size());
// -> b2 -> b3
Block b3 = b2.createNextBlock(someOtherGuy);
chain.add(b3);
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("50.00", wallet.getBalance().toFriendlyString());
}
@ -284,7 +285,7 @@ public class ChainSplitTest {
b3.addTransaction(b2.transactions.get(1));
b3.solve();
chain.add(roundtrip(b3));
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("50.00", wallet.getBalance().toFriendlyString());
}
@Test
@ -305,9 +306,9 @@ public class ChainSplitTest {
Block b1 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
chain.add(b1);
Transaction t1 = wallet.createSend(someOtherGuy, Utils.toNanoCoins(10, 0));
Transaction t1 = wallet.createSend(someOtherGuy, toNanoCoins(10, 0));
Address yetAnotherGuy = new ECKey().toAddress(unitTestParams);
Transaction t2 = wallet.createSend(yetAnotherGuy, Utils.toNanoCoins(20, 0));
Transaction t2 = wallet.createSend(yetAnotherGuy, toNanoCoins(20, 0));
wallet.commitTx(t1);
// Receive t1 as confirmed by the network.
Block b2 = b1.createNextBlock(new ECKey().toAddress(unitTestParams));
@ -325,7 +326,7 @@ public class ChainSplitTest {
Threading.waitForUserCode();
// Should have seen a double spend.
assertTrue(eventCalled[0]);
assertEquals(Utils.toNanoCoins(30, 0), wallet.getBalance());
assertEquals(toNanoCoins(30, 0), wallet.getBalance());
}
@Test
@ -350,15 +351,15 @@ public class ChainSplitTest {
Block b1 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
chain.add(b1);
Transaction t1 = checkNotNull(wallet.createSend(someOtherGuy, Utils.toNanoCoins(10, 0)));
Transaction t1 = checkNotNull(wallet.createSend(someOtherGuy, toNanoCoins(10, 0)));
Address yetAnotherGuy = new ECKey().toAddress(unitTestParams);
Transaction t2 = checkNotNull(wallet.createSend(yetAnotherGuy, Utils.toNanoCoins(20, 0)));
Transaction t2 = checkNotNull(wallet.createSend(yetAnotherGuy, toNanoCoins(20, 0)));
wallet.commitTx(t1);
// t1 is still pending ...
Block b2 = b1.createNextBlock(new ECKey().toAddress(unitTestParams));
chain.add(b2);
assertEquals(Utils.toNanoCoins(0, 0), wallet.getBalance());
assertEquals(Utils.toNanoCoins(40, 0), wallet.getBalance(Wallet.BalanceType.ESTIMATED));
assertEquals(toNanoCoins(0, 0), wallet.getBalance());
assertEquals(toNanoCoins(40, 0), wallet.getBalance(Wallet.BalanceType.ESTIMATED));
// Now we make a double spend become active after a re-org.
// genesis -> b1 -> b2 [t1 pending]
@ -375,7 +376,7 @@ public class ChainSplitTest {
// \-> b3 (t2) -> b4
assertEquals(t1, eventDead[0]);
assertEquals(t2, eventReplacement[0]);
assertEquals(Utils.toNanoCoins(30, 0), wallet.getBalance());
assertEquals(toNanoCoins(30, 0), wallet.getBalance());
// ... and back to our own parallel universe.
Block b5 = b2.createNextBlock(new ECKey().toAddress(unitTestParams));
@ -384,7 +385,7 @@ public class ChainSplitTest {
chain.add(b6);
// genesis -> b1 -> b2 -> b5 -> b6 [t1 still dead]
// \-> b3 [t2 resurrected and now pending] -> b4
assertEquals(Utils.toNanoCoins(0, 0), wallet.getBalance());
assertEquals(toNanoCoins(0, 0), wallet.getBalance());
// t2 is pending - resurrected double spends take precedence over our dead transactions (which are in nobodies
// mempool by this point).
t1 = checkNotNull(wallet.getTransaction(t1.getHash()));
@ -519,7 +520,7 @@ public class ChainSplitTest {
BigInteger newWork3 = work3.add(work7).add(work8);
assertEquals(newWork3, txns.get(2).getConfidence().getWorkDone());
assertEquals("250.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
assertEquals("250.00", wallet.getBalance().toFriendlyString());
// Now add two more blocks that don't send coins to us. Despite being irrelevant the wallet should still update.
Block b9 = b8.createNextBlock(someOtherGuy);
@ -541,19 +542,19 @@ public class ChainSplitTest {
// This covers issue 468.
// Receive some money to the wallet.
Transaction t1 = FakeTxBuilder.createFakeTx(unitTestParams, Utils.COIN, coinsTo);
Transaction t1 = FakeTxBuilder.createFakeTx(unitTestParams, COIN, coinsTo);
final Block b1 = FakeTxBuilder.makeSolvedTestBlock(unitTestParams.genesisBlock, t1);
chain.add(b1);
// Send a couple of payments one after the other (so the second depends on the change output of the first).
wallet.allowSpendingUnconfirmedTransactions();
Transaction t2 = checkNotNull(wallet.createSend(new ECKey().toAddress(unitTestParams), Utils.CENT));
Transaction t2 = checkNotNull(wallet.createSend(new ECKey().toAddress(unitTestParams), CENT));
wallet.commitTx(t2);
Transaction t3 = checkNotNull(wallet.createSend(new ECKey().toAddress(unitTestParams), Utils.CENT));
Transaction t3 = checkNotNull(wallet.createSend(new ECKey().toAddress(unitTestParams), CENT));
wallet.commitTx(t3);
chain.add(FakeTxBuilder.makeSolvedTestBlock(b1, t2, t3));
final Coin coins0point98 = Utils.COIN.subtract(Utils.CENT).subtract(Utils.CENT);
final Coin coins0point98 = COIN.subtract(CENT).subtract(CENT);
assertEquals(coins0point98, wallet.getBalance());
// Now round trip the wallet and force a re-org.
@ -617,7 +618,7 @@ public class ChainSplitTest {
chain.add(firstTip);
}
// ... and spend.
Transaction fodder = wallet.createSend(new ECKey().toAddress(unitTestParams), Utils.toNanoCoins(50, 0));
Transaction fodder = wallet.createSend(new ECKey().toAddress(unitTestParams), toNanoCoins(50, 0));
wallet.commitTx(fodder);
final AtomicBoolean fodderIsDead = new AtomicBoolean(false);
fodder.getConfidence().addEventListener(new TransactionConfidence.Listener() {

View File

@ -0,0 +1,96 @@
/**
* 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 static com.google.bitcoin.core.Coin.*;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;
import org.junit.Assert;
import org.junit.Test;
public class CoinTest {
@Test
public void testToNanoCoins() {
// String version
assertEquals(CENT, toNanoCoins("0.01"));
assertEquals(CENT, toNanoCoins("1E-2"));
assertEquals(COIN.add(CENT), toNanoCoins("1.01"));
try {
toNanoCoins("2E-20");
org.junit.Assert.fail("should not have accepted fractional nanocoins");
} catch (ArithmeticException e) {
}
// int version
assertEquals(CENT, toNanoCoins(0, 1));
try {
toNanoCoins(1, -1);
fail();
} catch (IllegalArgumentException e) {}
try {
toNanoCoins(-1, 0);
fail();
} catch (IllegalArgumentException e) {}
try {
toNanoCoins("-1");
fail();
} catch (ArithmeticException e) {}
}
@Test
public void testToFriendlyString() {
assertEquals("1.00", toNanoCoins(1, 0).toFriendlyString());
assertEquals("1.23", toNanoCoins(1, 23).toFriendlyString());
assertEquals("0.001", Coin.valueOf(COIN.longValue() / 1000).toFriendlyString());
assertEquals("-1.23", toNanoCoins(1, 23).negate().toFriendlyString());
}
/**
* Test the bitcoinValueToPlainString amount formatter
*/
@Test
public void testToPlainString() {
assertEquals("0.0015", Coin.valueOf(150000).toPlainString());
assertEquals("1.23", toNanoCoins("1.23").toPlainString());
assertEquals("0.1", toNanoCoins("0.1").toPlainString());
assertEquals("1.1", toNanoCoins("1.1").toPlainString());
assertEquals("21.12", toNanoCoins("21.12").toPlainString());
assertEquals("321.123", toNanoCoins("321.123").toPlainString());
assertEquals("4321.1234", toNanoCoins("4321.1234").toPlainString());
assertEquals("54321.12345", toNanoCoins("54321.12345").toPlainString());
assertEquals("654321.123456", toNanoCoins("654321.123456").toPlainString());
assertEquals("7654321.1234567", toNanoCoins("7654321.1234567").toPlainString());
try {
assertEquals("87654321.12345678", toNanoCoins("87654321.12345678").toPlainString());
Assert.fail(); // More than MAX_MONEY
} catch (Exception e) {}
// check there are no trailing zeros
assertEquals("1", toNanoCoins("1.0").toPlainString());
assertEquals("2", toNanoCoins("2.00").toPlainString());
assertEquals("3", toNanoCoins("3.000").toPlainString());
assertEquals("4", toNanoCoins("4.0000").toPlainString());
assertEquals("5", toNanoCoins("5.00000").toPlainString());
assertEquals("6", toNanoCoins("6.000000").toPlainString());
assertEquals("7", toNanoCoins("7.0000000").toPlainString());
assertEquals("8", toNanoCoins("8.00000000").toPlainString());
}
}

View File

@ -12,6 +12,7 @@ import java.io.IOException;
import java.math.BigInteger;
import java.util.*;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static com.google.bitcoin.script.ScriptOpCodes.*;
/**
@ -133,14 +134,14 @@ public class FullBlockTestGenerator {
blocks.add(new BlockAndValidity(blockToHeightMap, chainHead, true, false, chainHead.getHash(), 1, "Initial Block"));
spendableOutputs.offer(new TransactionOutPointWithValue(
new TransactionOutPoint(params, 0, chainHead.getTransactions().get(0).getHash()),
Utils.toNanoCoins(50, 0), chainHead.getTransactions().get(0).getOutputs().get(0).getScriptPubKey()));
toNanoCoins(50, 0), chainHead.getTransactions().get(0).getOutputs().get(0).getScriptPubKey()));
for (int i = 1; i < params.getSpendableCoinbaseDepth(); i++) {
chainHead = chainHead.createNextBlockWithCoinbase(coinbaseOutKeyPubKey);
chainHeadHeight++;
blocks.add(new BlockAndValidity(blockToHeightMap, chainHead, true, false, chainHead.getHash(), i+1, "Initial Block chain output generation"));
spendableOutputs.offer(new TransactionOutPointWithValue(
new TransactionOutPoint(params, 0, chainHead.getTransactions().get(0).getHash()),
Utils.toNanoCoins(50, 0), chainHead.getTransactions().get(0).getOutputs().get(0).getScriptPubKey()));
toNanoCoins(50, 0), chainHead.getTransactions().get(0).getOutputs().get(0).getScriptPubKey()));
}
// Start by building a couple of blocks on top of the genesis block.
@ -1624,7 +1625,7 @@ public class FullBlockTestGenerator {
Integer height = blockToHeightMap.get(baseBlock.getHash());
if (height != null)
Preconditions.checkState(height == nextBlockHeight - 1);
Coin coinbaseValue = Utils.toNanoCoins(50, 0).shiftRight(nextBlockHeight / params.getSubsidyDecreaseBlockCount())
Coin coinbaseValue = 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);

View File

@ -28,6 +28,7 @@ import java.io.ByteArrayOutputStream;
import java.nio.ByteBuffer;
import java.util.Arrays;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeBlock;
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeTx;
import static org.junit.Assert.*;
@ -86,17 +87,17 @@ public class LazyParseByteCacheTest {
resetBlockStore();
Transaction tx1 = createFakeTx(unitTestParams,
Utils.toNanoCoins(2, 0),
toNanoCoins(2, 0),
wallet.currentReceiveKey().toAddress(unitTestParams));
//add a second input so can test granularity of byte cache.
Transaction prevTx = new Transaction(unitTestParams);
TransactionOutput prevOut = new TransactionOutput(unitTestParams, prevTx, Utils.toNanoCoins(1, 0), wallet.currentReceiveKey().toAddress(unitTestParams));
TransactionOutput prevOut = new TransactionOutput(unitTestParams, prevTx, toNanoCoins(1, 0), wallet.currentReceiveKey().toAddress(unitTestParams));
prevTx.addOutput(prevOut);
// Connect it.
tx1.addInput(prevOut);
Transaction tx2 = createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0),
Transaction tx2 = createFakeTx(unitTestParams, toNanoCoins(1, 0),
new ECKey().toAddress(unitTestParams));
Block b1 = createFakeBlock(blockStore, tx1, tx2).block;

View File

@ -24,6 +24,7 @@ import org.junit.Test;
import java.net.InetAddress;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
@ -35,7 +36,7 @@ public class MemoryPoolTest {
@Before
public void setup() throws Exception {
BriefLogFormatter.init();
tx1 = FakeTxBuilder.createFakeTx(params, Utils.toNanoCoins(1, 0), new ECKey().toAddress(params));
tx1 = FakeTxBuilder.createFakeTx(params, toNanoCoins(1, 0), new ECKey().toAddress(params));
tx2 = new Transaction(params, tx1.bitcoinSerialize());
address1 = new PeerAddress(InetAddress.getByAddress(new byte[] { 127, 0, 0, 1 }));

View File

@ -43,6 +43,7 @@ import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import static com.google.bitcoin.core.Coin.*;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.junit.Assert.*;
@ -178,7 +179,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
expectedPeers.add(peerOf(p2));
assertEquals(tmp, expectedPeers);
Coin value = Utils.toNanoCoins(1, 0);
Coin value = toNanoCoins(1, 0);
Transaction t1 = FakeTxBuilder.createFakeTx(unitTestParams, value, address);
InventoryMessage inv = new InventoryMessage(unitTestParams);
inv.addTransaction(t1);
@ -301,7 +302,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
InboundMessageQueuer p2 = connectPeer(2);
InboundMessageQueuer p3 = connectPeer(3);
Transaction tx = FakeTxBuilder.createFakeTx(params, Utils.toNanoCoins(20, 0), address);
Transaction tx = FakeTxBuilder.createFakeTx(params, toNanoCoins(20, 0), address);
InventoryMessage inv = new InventoryMessage(params);
inv.addTransaction(tx);
@ -539,7 +540,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
InboundMessageQueuer p1 = connectPeer(1);
InboundMessageQueuer p2 = connectPeer(2);
// Create a pay to pubkey tx.
Transaction tx = FakeTxBuilder.createFakeTx(params, Utils.COIN, key);
Transaction tx = FakeTxBuilder.createFakeTx(params, COIN, key);
Transaction tx2 = new Transaction(params);
tx2.addInput(tx.getOutput(0));
TransactionOutPoint outpoint = tx2.getInput(0).getOutpoint();

View File

@ -47,6 +47,7 @@ import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static com.google.bitcoin.testing.FakeTxBuilder.*;
import static org.junit.Assert.*;
@ -244,7 +245,7 @@ public class PeerTest extends TestWithNetworkConnections {
peer.setDownloadData(true);
// Make a transaction and tell the peer we have it.
Coin value = Utils.toNanoCoins(1, 0);
Coin value = toNanoCoins(1, 0);
Transaction tx = createFakeTx(unitTestParams, value, address);
InventoryMessage inv = new InventoryMessage(unitTestParams);
InventoryItem item = new InventoryItem(InventoryItem.Type.Transaction, tx.getHash());
@ -277,7 +278,7 @@ public class PeerTest extends TestWithNetworkConnections {
InboundMessageQueuer writeTarget2 = connect(peer2, peerVersion);
// Make a tx and advertise it to one of the peers.
Coin value = Utils.toNanoCoins(1, 0);
Coin value = toNanoCoins(1, 0);
Transaction tx = createFakeTx(unitTestParams, value, this.address);
InventoryMessage inv = new InventoryMessage(unitTestParams);
InventoryItem item = new InventoryItem(InventoryItem.Type.Transaction, tx.getHash());
@ -542,14 +543,14 @@ public class PeerTest extends TestWithNetworkConnections {
// -> [t7]
// -> [t8]
// The ones in brackets are assumed to be in the chain and are represented only by hashes.
Transaction t2 = FakeTxBuilder.createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0), to);
Transaction t2 = FakeTxBuilder.createFakeTx(unitTestParams, toNanoCoins(1, 0), to);
Sha256Hash t5 = t2.getInput(0).getOutpoint().getHash();
Transaction t4 = FakeTxBuilder.createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0), new ECKey());
Transaction t4 = FakeTxBuilder.createFakeTx(unitTestParams, toNanoCoins(1, 0), new ECKey());
Sha256Hash t6 = t4.getInput(0).getOutpoint().getHash();
t4.addOutput(Utils.toNanoCoins(1, 0), new ECKey());
t4.addOutput(toNanoCoins(1, 0), new ECKey());
Transaction t3 = new Transaction(unitTestParams);
t3.addInput(t4.getOutput(0));
t3.addOutput(Utils.toNanoCoins(1, 0), new ECKey());
t3.addOutput(toNanoCoins(1, 0), new ECKey());
Transaction t1 = new Transaction(unitTestParams);
t1.addInput(t2.getOutput(0));
t1.addInput(t3.getOutput(0));
@ -557,7 +558,7 @@ public class PeerTest extends TestWithNetworkConnections {
t1.addInput(new TransactionInput(unitTestParams, t1, new byte[]{}, new TransactionOutPoint(unitTestParams, 0, someHash)));
Sha256Hash anotherHash = new Sha256Hash("3b801dd82f01d17bbde881687bf72bc62e2faa8ab8133d36fcb8c3abe7459da6");
t1.addInput(new TransactionInput(unitTestParams, t1, new byte[]{}, new TransactionOutPoint(unitTestParams, 1, anotherHash)));
t1.addOutput(Utils.toNanoCoins(1, 0), to);
t1.addOutput(toNanoCoins(1, 0), to);
t1 = FakeTxBuilder.roundTripTransaction(unitTestParams, t1);
t2 = FakeTxBuilder.roundTripTransaction(unitTestParams, t2);
t3 = FakeTxBuilder.roundTripTransaction(unitTestParams, t3);
@ -663,7 +664,7 @@ public class PeerTest extends TestWithNetworkConnections {
}
});
// Send a normal relevant transaction, it's received correctly.
Transaction t1 = FakeTxBuilder.createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0), key);
Transaction t1 = FakeTxBuilder.createFakeTx(unitTestParams, toNanoCoins(1, 0), key);
inbound(writeTarget, t1);
GetDataMessage getdata = (GetDataMessage) outbound(writeTarget);
if (useNotFound) {
@ -676,7 +677,7 @@ public class PeerTest extends TestWithNetworkConnections {
assertNotNull(vtx[0]);
vtx[0] = null;
// Send a timelocked transaction, nothing happens.
Transaction t2 = FakeTxBuilder.createFakeTx(unitTestParams, Utils.toNanoCoins(2, 0), key);
Transaction t2 = FakeTxBuilder.createFakeTx(unitTestParams, toNanoCoins(2, 0), key);
t2.setLockTime(999999);
inbound(writeTarget, t2);
Threading.waitForUserCode();
@ -742,10 +743,10 @@ public class PeerTest extends TestWithNetworkConnections {
Sha256Hash t3 = Sha256Hash.create("abc".getBytes(Charset.forName("UTF-8")));
t2.addInput(new TransactionInput(unitTestParams, t2, new byte[]{}, new TransactionOutPoint(unitTestParams, 0, t3)));
t2.getInput(0).setSequenceNumber(0xDEADBEEF);
t2.addOutput(Utils.toNanoCoins(1, 0), new ECKey());
t2.addOutput(toNanoCoins(1, 0), new ECKey());
Transaction t1 = new Transaction(unitTestParams);
t1.addInput(t2.getOutput(0));
t1.addOutput(Utils.toNanoCoins(1, 0), key); // Make it relevant.
t1.addOutput(toNanoCoins(1, 0), key); // Make it relevant.
// Announce t1.
InventoryMessage inv = new InventoryMessage(unitTestParams);
inv.addTransaction(t1);
@ -839,10 +840,10 @@ public class PeerTest extends TestWithNetworkConnections {
connect();
Transaction t1 = new Transaction(unitTestParams);
t1.addInput(new TransactionInput(unitTestParams, t1, new byte[]{}));
t1.addOutput(Utils.toNanoCoins(1, 0), new ECKey().toAddress(unitTestParams));
t1.addOutput(toNanoCoins(1, 0), new ECKey().toAddress(unitTestParams));
Transaction t2 = new Transaction(unitTestParams);
t2.addInput(t1.getOutput(0));
t2.addOutput(Utils.toNanoCoins(1, 0), wallet.getChangeAddress());
t2.addOutput(toNanoCoins(1, 0), wallet.getChangeAddress());
inbound(writeTarget, t2);
final InventoryItem inventoryItem = new InventoryItem(InventoryItem.Type.Transaction, t2.getInput(0).getOutpoint().getHash());
final NotFoundMessage nfm = new NotFoundMessage(unitTestParams, Lists.newArrayList(inventoryItem));

View File

@ -33,6 +33,7 @@ import java.util.Arrays;
import java.util.Collection;
import java.util.Random;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.junit.Assert.*;
@ -107,11 +108,11 @@ public class TransactionBroadcastTest extends TestWithPeerGroup {
Block b1 = FakeTxBuilder.makeSolvedTestBlock(blockStore, address);
inbound(p1, b1);
assertNull(outbound(p1));
assertEquals(Utils.toNanoCoins(50, 0), wallet.getBalance());
assertEquals(toNanoCoins(50, 0), wallet.getBalance());
// Now create a spend, and expect the announcement on p1.
Address dest = new ECKey().toAddress(params);
Wallet.SendResult sendResult = wallet.sendCoins(peerGroup, dest, Utils.toNanoCoins(1, 0));
Wallet.SendResult sendResult = wallet.sendCoins(peerGroup, dest, toNanoCoins(1, 0));
assertFalse(sendResult.broadcastComplete.isDone());
Transaction t1;
{
@ -147,7 +148,7 @@ public class TransactionBroadcastTest extends TestWithPeerGroup {
inbound(p1, b1);
pingAndWait(p1);
assertNull(outbound(p1));
assertEquals(Utils.toNanoCoins(50, 0), wallet.getBalance());
assertEquals(toNanoCoins(50, 0), wallet.getBalance());
// Check that the wallet informs us of changes in confidence as the transaction ripples across the network.
final Transaction[] transactions = new Transaction[1];
@ -160,7 +161,7 @@ public class TransactionBroadcastTest extends TestWithPeerGroup {
// Now create a spend, and expect the announcement on p1.
Address dest = new ECKey().toAddress(params);
Wallet.SendResult sendResult = wallet.sendCoins(peerGroup, dest, Utils.toNanoCoins(1, 0));
Wallet.SendResult sendResult = wallet.sendCoins(peerGroup, dest, toNanoCoins(1, 0));
assertNotNull(sendResult.tx);
Threading.waitForUserCode();
assertFalse(sendResult.broadcastComplete.isDone());
@ -178,7 +179,7 @@ public class TransactionBroadcastTest extends TestWithPeerGroup {
}
assertNotNull(t1);
// 49 BTC in change.
assertEquals(Utils.toNanoCoins(49, 0), t1.getValueSentToMe(wallet));
assertEquals(toNanoCoins(49, 0), t1.getValueSentToMe(wallet));
// The future won't complete until it's heard back from the network on p2.
InventoryMessage inv = new InventoryMessage(params);
inv.addTransaction(t1);
@ -196,7 +197,7 @@ public class TransactionBroadcastTest extends TestWithPeerGroup {
// Do the same thing with an offline transaction.
peerGroup.removeWallet(wallet);
Wallet.SendRequest req = Wallet.SendRequest.to(dest, Utils.toNanoCoins(2, 0));
Wallet.SendRequest req = Wallet.SendRequest.to(dest, toNanoCoins(2, 0));
req.ensureMinRequiredFee = false;
Transaction t3 = checkNotNull(wallet.sendCoinsOffline(req));
assertNull(outbound(p1)); // Nothing sent.

View File

@ -20,88 +20,10 @@ import java.math.BigInteger;
import org.junit.Assert;
import org.junit.Test;
import static com.google.bitcoin.core.Utils.*;
import static org.junit.Assert.*;
public class UtilsTest {
@Test
public void testToNanoCoins() {
// String version
assertEquals(CENT, toNanoCoins("0.01"));
assertEquals(CENT, toNanoCoins("1E-2"));
assertEquals(COIN.add(Utils.CENT), toNanoCoins("1.01"));
try {
toNanoCoins("2E-20");
org.junit.Assert.fail("should not have accepted fractional nanocoins");
} catch (ArithmeticException e) {
}
// int version
assertEquals(CENT, toNanoCoins(0, 1));
try {
toNanoCoins(1, -1);
fail();
} catch (IllegalArgumentException e) {}
try {
toNanoCoins(-1, 0);
fail();
} catch (IllegalArgumentException e) {}
try {
toNanoCoins("-1");
fail();
} catch (ArithmeticException e) {}
}
@Test
public void testFormatting() {
assertEquals("1.00", bitcoinValueToFriendlyString(toNanoCoins(1, 0)));
assertEquals("1.23", bitcoinValueToFriendlyString(toNanoCoins(1, 23)));
assertEquals("0.001", bitcoinValueToFriendlyString(Coin.valueOf(COIN.longValue() / 1000)));
assertEquals("-1.23", bitcoinValueToFriendlyString(toNanoCoins(1, 23).negate()));
}
/**
* Test the bitcoinValueToPlainString amount formatter
*/
@Test
public void testBitcoinValueToPlainString() {
// null argument check
try {
bitcoinValueToPlainString(null);
org.junit.Assert.fail("Expecting IllegalArgumentException");
} catch (IllegalArgumentException e) {
assertTrue(e.getMessage().contains("Value cannot be null"));
}
assertEquals("0.0015", bitcoinValueToPlainString(Coin.valueOf(150000)));
assertEquals("1.23", bitcoinValueToPlainString(toNanoCoins("1.23")));
assertEquals("0.1", bitcoinValueToPlainString(toNanoCoins("0.1")));
assertEquals("1.1", bitcoinValueToPlainString(toNanoCoins("1.1")));
assertEquals("21.12", bitcoinValueToPlainString(toNanoCoins("21.12")));
assertEquals("321.123", bitcoinValueToPlainString(toNanoCoins("321.123")));
assertEquals("4321.1234", bitcoinValueToPlainString(toNanoCoins("4321.1234")));
assertEquals("54321.12345", bitcoinValueToPlainString(toNanoCoins("54321.12345")));
assertEquals("654321.123456", bitcoinValueToPlainString(toNanoCoins("654321.123456")));
assertEquals("7654321.1234567", bitcoinValueToPlainString(toNanoCoins("7654321.1234567")));
try {
assertEquals("87654321.12345678", bitcoinValueToPlainString(toNanoCoins("87654321.12345678")));
Assert.fail(); // More than MAX_MONEY
} catch (Exception e) {}
// check there are no trailing zeros
assertEquals("1", bitcoinValueToPlainString(toNanoCoins("1.0")));
assertEquals("2", bitcoinValueToPlainString(toNanoCoins("2.00")));
assertEquals("3", bitcoinValueToPlainString(toNanoCoins("3.000")));
assertEquals("4", bitcoinValueToPlainString(toNanoCoins("4.0000")));
assertEquals("5", bitcoinValueToPlainString(toNanoCoins("5.00000")));
assertEquals("6", bitcoinValueToPlainString(toNanoCoins("6.000000")));
assertEquals("7", bitcoinValueToPlainString(toNanoCoins("7.0000000")));
assertEquals("8", bitcoinValueToPlainString(toNanoCoins("8.00000000")));
}
@Test
public void testReverseBytes() {
assertArrayEquals(new byte[]{1, 2, 3, 4, 5}, Utils.reverseBytes(new byte[]{5, 4, 3, 2, 1}));

File diff suppressed because it is too large Load Diff

View File

@ -39,6 +39,7 @@ import java.util.Arrays;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicBoolean;
import static com.google.bitcoin.core.Coin.*;
import static com.google.bitcoin.protocols.channels.PaymentChannelCloseException.CloseReason;
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeBlock;
import static org.bitcoin.paymentchannel.Protos.TwoWayChannelMessage.MessageType;
@ -64,8 +65,8 @@ public class ChannelConnectionTest extends TestWithWallet {
public void setUp() throws Exception {
super.setUp();
Utils.setMockClock(); // Use mock clock
sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
wallet.addExtension(new StoredPaymentChannelClientStates(wallet, failBroadcaster));
serverWallet = new Wallet(params);
serverWallet.addExtension(new StoredPaymentChannelServerStates(serverWallet, failBroadcaster));
@ -116,7 +117,7 @@ public class ChannelConnectionTest extends TestWithWallet {
final SettableFuture<ListenableFuture<PaymentChannelServerState>> serverCloseFuture = SettableFuture.create();
final SettableFuture<Sha256Hash> channelOpenFuture = SettableFuture.create();
final BlockingQueue<Coin> q = new LinkedBlockingQueue<Coin>();
final PaymentChannelServerListener server = new PaymentChannelServerListener(mockBroadcaster, serverWallet, 30, Utils.COIN,
final PaymentChannelServerListener server = new PaymentChannelServerListener(mockBroadcaster, serverWallet, 30, COIN,
new PaymentChannelServerListener.HandlerFactory() {
@Nullable
@Override
@ -142,7 +143,7 @@ public class ChannelConnectionTest extends TestWithWallet {
server.bindAndStart(4243);
PaymentChannelClientConnection client = new PaymentChannelClientConnection(
new InetSocketAddress("localhost", 4243), 30, wallet, myKey, Utils.COIN, "");
new InetSocketAddress("localhost", 4243), 30, wallet, myKey, COIN, "");
// Wait for the multi-sig tx to be transmitted.
broadcastTxPause.release();
@ -170,14 +171,14 @@ public class ChannelConnectionTest extends TestWithWallet {
Thread.sleep(1250); // No timeouts once the channel is open
Coin amount = client.state().getValueSpent();
assertEquals(amount, q.take());
client.incrementPayment(Utils.CENT).get();
amount = amount.add(Utils.CENT);
client.incrementPayment(CENT).get();
amount = amount.add(CENT);
assertEquals(amount, q.take());
client.incrementPayment(Utils.CENT).get();
amount = amount.add(Utils.CENT);
client.incrementPayment(CENT).get();
amount = amount.add(CENT);
assertEquals(amount, q.take());
client.incrementPayment(Utils.CENT).get();
amount = amount.add(Utils.CENT);
client.incrementPayment(CENT).get();
amount = amount.add(CENT);
assertEquals(amount, q.take());
latch.await();
@ -215,7 +216,7 @@ public class ChannelConnectionTest extends TestWithWallet {
public void testServerErrorHandling() throws Exception {
// Gives the server crap and checks proper error responses are sent.
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
PaymentChannelServer server = pair.server;
server.connectionOpen();
client.connectionOpen();
@ -237,7 +238,7 @@ public class ChannelConnectionTest extends TestWithWallet {
// Make sure the server closes the socket on CLOSE
pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client = new PaymentChannelClient(wallet, myKey, COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
server = pair.server;
server.connectionOpen();
client.connectionOpen();
@ -251,7 +252,7 @@ public class ChannelConnectionTest extends TestWithWallet {
// Make sure the server closes the socket on ERROR
pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client = new PaymentChannelClient(wallet, myKey, COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
server = pair.server;
server.connectionOpen();
client.connectionOpen();
@ -275,7 +276,7 @@ public class ChannelConnectionTest extends TestWithWallet {
// Open up a normal channel.
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
pair.server.connectionOpen();
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, someServerId, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, someServerId, pair.clientRecorder);
PaymentChannelServer server = pair.server;
client.connectionOpen();
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
@ -296,8 +297,8 @@ public class ChannelConnectionTest extends TestWithWallet {
assertNull(pair.clientRecorder.q.poll());
assertEquals(minPayment, client.state().getValueSpent());
// Send a bitcent.
Coin amount = minPayment.add(Utils.CENT);
client.incrementPayment(Utils.CENT);
Coin amount = minPayment.add(CENT);
client.incrementPayment(CENT);
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
assertEquals(amount, pair.serverRecorder.q.take());
server.close();
@ -333,7 +334,7 @@ public class ChannelConnectionTest extends TestWithWallet {
(StoredPaymentChannelClientStates) wallet.getExtensions().get(StoredPaymentChannelClientStates.EXTENSION_ID);
pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
client = new PaymentChannelClient(wallet, myKey, Utils.COIN, someServerId, pair.clientRecorder);
client = new PaymentChannelClient(wallet, myKey, COIN, someServerId, pair.clientRecorder);
server = pair.server;
client.connectionOpen();
server.connectionOpen();
@ -349,8 +350,8 @@ public class ChannelConnectionTest extends TestWithWallet {
assertNull(pair.serverRecorder.q.poll());
assertNull(pair.clientRecorder.q.poll());
// Send another bitcent and check 2 were received in total.
client.incrementPayment(Utils.CENT);
amount = amount.add(Utils.CENT);
client.incrementPayment(CENT);
amount = amount.add(CENT);
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
pair.serverRecorder.checkTotalPayment(amount);
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
@ -360,7 +361,7 @@ public class ChannelConnectionTest extends TestWithWallet {
// Now open up a new client with the same id and make sure the server disconnects the previous client.
pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
client = new PaymentChannelClient(wallet, myKey, Utils.COIN, someServerId, pair.clientRecorder);
client = new PaymentChannelClient(wallet, myKey, COIN, someServerId, pair.clientRecorder);
server = pair.server;
client.connectionOpen();
server.connectionOpen();
@ -372,7 +373,7 @@ public class ChannelConnectionTest extends TestWithWallet {
}
// Make sure the server allows two simultaneous opens. It will close the first and allow resumption of the second.
pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
client = new PaymentChannelClient(wallet, myKey, Utils.COIN, someServerId, pair.clientRecorder);
client = new PaymentChannelClient(wallet, myKey, COIN, someServerId, pair.clientRecorder);
server = pair.server;
client.connectionOpen();
server.connectionOpen();
@ -452,7 +453,7 @@ public class ChannelConnectionTest extends TestWithWallet {
public void testClientUnknownVersion() throws Exception {
// Tests client rejects unknown version
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client.connectionOpen();
pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION);
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
@ -472,7 +473,7 @@ public class ChannelConnectionTest extends TestWithWallet {
// Tests that clients reject too large time windows
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
PaymentChannelServer server = pair.server;
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client.connectionOpen();
server.connectionOpen();
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
@ -497,14 +498,14 @@ public class ChannelConnectionTest extends TestWithWallet {
public void testValuesAreRespected() throws Exception {
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
PaymentChannelServer server = pair.server;
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client.connectionOpen();
server.connectionOpen();
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
.setInitiate(Protos.Initiate.newBuilder().setExpireTimeSecs(Utils.currentTimeSeconds())
.setMinAcceptedChannelSize(Utils.COIN.add(Coin.ONE).longValue())
.setMinAcceptedChannelSize(COIN.add(ONE).longValue())
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey()))
.setMinPayment(Transaction.MIN_NONDUST_OUTPUT.longValue()))
.setType(MessageType.INITIATE).build());
@ -518,11 +519,11 @@ public class ChannelConnectionTest extends TestWithWallet {
// 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(Coin.TEN), AbstractBlockChain.NewBlockType.BEST_CHAIN);
sendMoneyToWallet(COIN.multiply(TEN), AbstractBlockChain.NewBlockType.BEST_CHAIN);
pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
server = pair.server;
final Coin myValue = Utils.COIN.multiply(Coin.TEN);
final Coin myValue = COIN.multiply(TEN);
client = new PaymentChannelClient(wallet, myKey, myValue, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client.connectionOpen();
server.connectionOpen();
@ -530,7 +531,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(Coin.ONE).longValue())
.setMinAcceptedChannelSize(COIN.add(ONE).longValue())
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey()))
.setMinPayment(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.longValue()))
.setType(MessageType.INITIATE).build());
@ -545,7 +546,7 @@ public class ChannelConnectionTest extends TestWithWallet {
emptyWallet.freshReceiveKey();
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
PaymentChannelServer server = pair.server;
PaymentChannelClient client = new PaymentChannelClient(emptyWallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(emptyWallet, myKey, COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client.connectionOpen();
server.connectionOpen();
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
@ -553,7 +554,7 @@ public class ChannelConnectionTest extends TestWithWallet {
try {
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
.setInitiate(Protos.Initiate.newBuilder().setExpireTimeSecs(Utils.currentTimeSeconds())
.setMinAcceptedChannelSize(Utils.CENT.longValue())
.setMinAcceptedChannelSize(CENT.longValue())
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey()))
.setMinPayment(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.longValue()))
.setType(MessageType.INITIATE).build());
@ -567,7 +568,7 @@ public class ChannelConnectionTest extends TestWithWallet {
public void testClientRefusesNonCanonicalKey() throws Exception {
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
PaymentChannelServer server = pair.server;
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client.connectionOpen();
server.connectionOpen();
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
@ -585,7 +586,7 @@ public class ChannelConnectionTest extends TestWithWallet {
public void testClientResumeNothing() throws Exception {
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
PaymentChannelServer server = pair.server;
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client.connectionOpen();
server.connectionOpen();
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
@ -599,7 +600,7 @@ public class ChannelConnectionTest extends TestWithWallet {
@Test
public void testClientRandomMessage() throws Exception {
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, Sha256Hash.ZERO_HASH, pair.clientRecorder);
client.connectionOpen();
pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION);
@ -620,7 +621,7 @@ public class ChannelConnectionTest extends TestWithWallet {
Sha256Hash someServerId = Sha256Hash.ZERO_HASH;
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
pair.server.connectionOpen();
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, someServerId, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, someServerId, pair.clientRecorder);
PaymentChannelServer server = pair.server;
client.connectionOpen();
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
@ -651,7 +652,7 @@ public class ChannelConnectionTest extends TestWithWallet {
client.connectionClosed();
// Now try opening a new channel with the same server ID and verify the client asks for a new channel.
client = new PaymentChannelClient(wallet, myKey, Utils.COIN, someServerId, pair.clientRecorder);
client = new PaymentChannelClient(wallet, myKey, COIN, someServerId, pair.clientRecorder);
client.connectionOpen();
Protos.TwoWayChannelMessage msg = pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION);
assertFalse(msg.getClientVersion().hasPreviousChannelContractHash());
@ -666,7 +667,7 @@ public class ChannelConnectionTest extends TestWithWallet {
Sha256Hash someServerId = Sha256Hash.ZERO_HASH;
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
pair.server.connectionOpen();
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, someServerId, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, someServerId, pair.clientRecorder);
PaymentChannelServer server = pair.server;
client.connectionOpen();
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
@ -683,17 +684,17 @@ public class ChannelConnectionTest extends TestWithWallet {
pair.clientRecorder.checkInitiated();
assertNull(pair.serverRecorder.q.poll());
assertNull(pair.clientRecorder.q.poll());
ListenableFuture<Coin> future = client.incrementPayment(Utils.CENT);
ListenableFuture<Coin> future = client.incrementPayment(CENT);
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
pair.serverRecorder.q.take();
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
assertTrue(future.isDone());
client.incrementPayment(Utils.CENT);
client.incrementPayment(CENT);
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
pair.serverRecorder.q.take();
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
client.incrementPayment(Utils.CENT);
client.incrementPayment(CENT);
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
pair.serverRecorder.q.take();
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
@ -718,7 +719,7 @@ public class ChannelConnectionTest extends TestWithWallet {
Sha256Hash someServerId = Sha256Hash.ZERO_HASH;
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
pair.server.connectionOpen();
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, someServerId, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, someServerId, pair.clientRecorder);
PaymentChannelServer server = pair.server;
client.connectionOpen();
final Protos.TwoWayChannelMessage msg = pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION);
@ -737,7 +738,7 @@ public class ChannelConnectionTest extends TestWithWallet {
pair.clientRecorder.checkInitiated();
assertNull(pair.serverRecorder.q.poll());
assertNull(pair.clientRecorder.q.poll());
client.incrementPayment(Utils.CENT);
client.incrementPayment(CENT);
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
client.connectionClosed();
server.connectionClosed();
@ -747,7 +748,7 @@ public class ChannelConnectionTest extends TestWithWallet {
Sha256Hash someServerId = Sha256Hash.ZERO_HASH;
ChannelTestUtils.RecordingPair pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
pair.server.connectionOpen();
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, Utils.COIN, someServerId, pair.clientRecorder);
PaymentChannelClient client = new PaymentChannelClient(wallet, myKey, COIN, someServerId, pair.clientRecorder);
PaymentChannelServer server = pair.server;
client.connectionOpen();
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));

View File

@ -3,7 +3,6 @@ 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;
@ -109,7 +108,7 @@ public class ChannelTestUtils {
public static RecordingPair makeRecorders(final Wallet serverWallet, final TransactionBroadcaster mockBroadcaster) {
RecordingPair pair = new RecordingPair();
pair.serverRecorder = new RecordingServerConnection();
pair.server = new PaymentChannelServer(mockBroadcaster, serverWallet, Utils.COIN, pair.serverRecorder);
pair.server = new PaymentChannelServer(mockBroadcaster, serverWallet, Coin.COIN, pair.serverRecorder);
pair.clientRecorder = new RecordingClientConnection();
return pair;
}

View File

@ -34,6 +34,7 @@ import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.LinkedBlockingQueue;
import static com.google.bitcoin.core.Coin.*;
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeTx;
import static com.google.bitcoin.testing.FakeTxBuilder.makeSolvedTestBlock;
import static org.junit.Assert.*;
@ -67,12 +68,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
return null;
}
}));
sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
chain = new BlockChain(params, wallet, blockStore); // Recreate chain as sendMoneyToWallet will confuse it
serverWallet = new Wallet(params);
serverKey = serverWallet.freshReceiveKey();
chain.addWallet(serverWallet);
halfCoin = Utils.toNanoCoins(0, 50);
halfCoin = toNanoCoins(0, 50);
broadcasts = new LinkedBlockingQueue<TxFuturePair>();
mockBroadcaster = new TransactionBroadcaster() {
@ -94,7 +95,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
@Test
public void stateErrors() throws Exception {
PaymentChannelClientState channelState = new PaymentChannelClientState(wallet, myKey, serverKey,
Utils.COIN.multiply(Coin.TEN), 20);
COIN.multiply(TEN), 20);
assertEquals(PaymentChannelClientState.State.NEW, channelState.getState());
try {
channelState.getMultisigContract();
@ -197,7 +198,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
assertEquals(size.multiply(Coin.valueOf(5)), serverWallet.getBalance());
assertEquals(0, serverWallet.getPendingTransactions().size());
assertEquals(Utils.COIN.subtract(size.multiply(Coin.valueOf(5))), wallet.getBalance());
assertEquals(COIN.subtract(size.multiply(Coin.valueOf(5))), wallet.getBalance());
assertEquals(0, wallet.getPendingTransactions().size());
assertEquals(3, wallet.getTransactions(false).size());
@ -217,10 +218,10 @@ public class PaymentChannelStateTest extends TestWithWallet {
// we can broadcast the refund and get our balance back.
// Spend the client wallet's one coin
Transaction spendCoinTx = wallet.sendCoinsOffline(Wallet.SendRequest.to(new ECKey().toAddress(params), Utils.COIN));
Transaction spendCoinTx = wallet.sendCoinsOffline(Wallet.SendRequest.to(new ECKey().toAddress(params), COIN));
assertEquals(Coin.ZERO, wallet.getBalance());
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), spendCoinTx, createFakeTx(params, Utils.CENT, myAddress)));
assertEquals(Utils.CENT, wallet.getBalance());
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), spendCoinTx, createFakeTx(params, CENT, myAddress)));
assertEquals(CENT, wallet.getBalance());
// Set the wallet's stored states to use our real test PeerGroup
StoredPaymentChannelClientStates stateStorage = new StoredPaymentChannelClientStates(wallet, mockBroadcaster);
@ -233,9 +234,9 @@ 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(Coin.valueOf(2)), EXPIRE_TIME);
CENT.divide(Coin.valueOf(2)), EXPIRE_TIME);
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
assertEquals(Utils.CENT.divide(Coin.valueOf(2)), clientState.getTotalValue());
assertEquals(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(Coin.valueOf(2)));
@ -269,8 +270,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
// Pay a tiny bit
serverState.incrementPayment(Utils.CENT.divide(Coin.valueOf(2)).subtract(Utils.CENT.divide(Coin.TEN)),
clientState.incrementPaymentBy(Utils.CENT.divide(Coin.TEN)).signature.encodeToBitcoin());
serverState.incrementPayment(CENT.divide(Coin.valueOf(2)).subtract(CENT.divide(TEN)),
clientState.incrementPaymentBy(CENT.divide(TEN)).signature.encodeToBitcoin());
// Advance time until our we get close enough to lock time that server should rebroadcast
Utils.rollMockClock(60*60*22);
@ -313,11 +314,11 @@ 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(Coin.valueOf(2))));
assertEquals(wallet.getBalance(), CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(2))));
try {
// After its expired, we cant still increment payment
clientState.incrementPaymentBy(Utils.CENT);
clientState.incrementPaymentBy(CENT);
fail();
} catch (IllegalStateException e) { }
}
@ -454,7 +455,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
Coin size = halfCoin.divide(Coin.TEN).divide(Coin.TEN);
Coin totalPayment = Coin.ZERO;
try {
clientState.incrementPaymentBy(Utils.COIN);
clientState.incrementPaymentBy(COIN);
fail();
} catch (ValueOutOfRangeException e) {}
@ -525,11 +526,11 @@ public class PaymentChannelStateTest extends TestWithWallet {
// Test that transactions are getting the necessary fees
// Spend the client wallet's one coin
wallet.sendCoinsOffline(Wallet.SendRequest.to(new ECKey().toAddress(params), Utils.COIN));
wallet.sendCoinsOffline(Wallet.SendRequest.to(new ECKey().toAddress(params), COIN));
assertEquals(Coin.ZERO, wallet.getBalance());
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), createFakeTx(params, Utils.CENT, myAddress)));
assertEquals(Utils.CENT, wallet.getBalance());
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), createFakeTx(params, CENT, myAddress)));
assertEquals(CENT, wallet.getBalance());
Utils.setMockClock(); // Use mock clock
final long EXPIRE_TIME = Utils.currentTimeMillis()/1000 + 60*60*24;
@ -564,7 +565,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
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);
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()), CENT, EXPIRE_TIME);
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
clientState.initiate();
assertEquals(clientState.getRefundTxFees(), Coin.ZERO);
@ -597,19 +598,19 @@ public class PaymentChannelStateTest extends TestWithWallet {
// We can send as little as we want - its up to the server to get the fees right
byte[] signature = clientState.incrementPaymentBy(Coin.ONE).signature.encodeToBitcoin();
totalPayment = totalPayment.add(Coin.ONE);
serverState.incrementPayment(Utils.CENT.subtract(totalPayment), signature);
serverState.incrementPayment(CENT.subtract(totalPayment), signature);
// We can't refund more than the contract is worth...
try {
serverState.incrementPayment(Utils.CENT.add(Coin.ONE), signature);
serverState.incrementPayment(CENT.add(ONE), signature);
fail();
} catch (ValueOutOfRangeException e) {}
// We cannot send just under the total value - our refund would make it unspendable. So the client
// 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(Coin.ONE), payment.amount);
clientState.incrementPaymentBy(CENT.subtract(Transaction.MIN_NONDUST_OUTPUT));
assertEquals(CENT.subtract(ONE), payment.amount);
totalPayment = totalPayment.add(payment.amount);
// The server also won't accept it if we do that.
@ -618,7 +619,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
fail();
} catch (ValueOutOfRangeException e) {}
serverState.incrementPayment(Utils.CENT.subtract(totalPayment), payment.signature.encodeToBitcoin());
serverState.incrementPayment(CENT.subtract(totalPayment), payment.signature.encodeToBitcoin());
// And settle the channel.
serverState.close();
@ -640,7 +641,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
serverState = new PaymentChannelServerState(mockBroadcaster, serverWallet, serverKey, EXPIRE_TIME);
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()), Utils.CENT, EXPIRE_TIME) {
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()), CENT, EXPIRE_TIME) {
@Override
protected void editContractSendRequest(Wallet.SendRequest req) {
req.coinSelector = wallet.getCoinSelector();
@ -680,7 +681,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
// 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(Coin.ONE))
.signature.encodeToBitcoin();
Coin totalRefund = Utils.CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(Coin.ONE));
Coin totalRefund = CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(ONE));
serverState.incrementPayment(totalRefund, signature);
// We need to pay MIN_TX_FEE, but we only have MIN_NONDUST_OUTPUT
@ -692,7 +693,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
// Now give the server enough coins to pay the fee
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, new ECKey().toAddress(params)), BigInteger.ONE, 1);
Transaction tx1 = createFakeTx(params, Utils.COIN, serverKey.toAddress(params));
Transaction tx1 = createFakeTx(params, COIN, serverKey.toAddress(params));
serverWallet.receiveFromBlock(tx1, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
// The contract is still not worth redeeming - its worth less than we pay in fee

View File

@ -32,6 +32,7 @@ import java.net.URL;
import java.util.ArrayList;
import java.util.Date;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static org.junit.Assert.*;
public class PaymentSessionTest {
@ -44,7 +45,7 @@ public class PaymentSessionTest {
private ECKey serverKey;
private Transaction tx;
private TransactionOutput outputToMe;
Coin nanoCoins = Utils.toNanoCoins(1, 0);
private Coin nanoCoins = toNanoCoins(1, 0);
@Before
public void setUp() throws Exception {

View File

@ -40,6 +40,7 @@ import java.util.Date;
import java.util.Iterator;
import java.util.Set;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeTx;
import static org.junit.Assert.*;
@ -92,7 +93,7 @@ public class WalletProtobufSerializerTest {
@Test
public void oneTx() throws Exception {
// Check basic tx serialization.
Coin v1 = Utils.toNanoCoins(1, 0);
Coin v1 = 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")));
@ -287,7 +288,7 @@ public class WalletProtobufSerializerTest {
@Test
public void coinbaseTxns() throws Exception {
// Covers issue 420 where the outpoint index of a coinbase tx input was being mis-serialized.
Block b = params.getGenesisBlock().createNextBlockWithCoinbase(myKey.getPubKey(), Utils.toNanoCoins(50, 0));
Block b = params.getGenesisBlock().createNextBlockWithCoinbase(myKey.getPubKey(), toNanoCoins(50, 0));
Transaction coinbase = b.getTransactions().get(0);
assertTrue(coinbase.isCoinBase());
BlockChain chain = new BlockChain(params, myWallet, new MemoryBlockStore(params));

View File

@ -19,16 +19,15 @@
package com.google.bitcoin.uri;
import com.google.bitcoin.core.Address;
import com.google.bitcoin.core.Utils;
import com.google.bitcoin.params.MainNetParams;
import com.google.bitcoin.params.TestNet3Params;
import org.junit.Test;
import java.io.UnsupportedEncodingException;
import static com.google.bitcoin.core.Coin.toNanoCoins;
import static org.junit.Assert.*;
public class BitcoinURITest {
private BitcoinURI testObject = null;
@ -39,25 +38,25 @@ public class BitcoinURITest {
Address goodAddress = new Address(MainNetParams.get(), MAINNET_GOOD_ADDRESS);
// simple example
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=12.34&label=Hello&message=AMessage", BitcoinURI.convertToBitcoinURI(goodAddress, Utils.toNanoCoins("12.34"), "Hello", "AMessage"));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=12.34&label=Hello&message=AMessage", BitcoinURI.convertToBitcoinURI(goodAddress, toNanoCoins("12.34"), "Hello", "AMessage"));
// example with spaces, ampersand and plus
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=12.34&label=Hello%20World&message=Mess%20%26%20age%20%2B%20hope", BitcoinURI.convertToBitcoinURI(goodAddress, Utils.toNanoCoins("12.34"), "Hello World", "Mess & age + hope"));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=12.34&label=Hello%20World&message=Mess%20%26%20age%20%2B%20hope", BitcoinURI.convertToBitcoinURI(goodAddress, toNanoCoins("12.34"), "Hello World", "Mess & age + hope"));
// no amount, label present, message present
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?label=Hello&message=glory", BitcoinURI.convertToBitcoinURI(goodAddress, null, "Hello", "glory"));
// amount present, no label, message present
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=0.1&message=glory", BitcoinURI.convertToBitcoinURI(goodAddress, Utils.toNanoCoins("0.1"), null, "glory"));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=0.1&message=glory", BitcoinURI.convertToBitcoinURI(goodAddress, Utils.toNanoCoins("0.1"), "", "glory"));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=0.1&message=glory", BitcoinURI.convertToBitcoinURI(goodAddress, toNanoCoins("0.1"), null, "glory"));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=0.1&message=glory", BitcoinURI.convertToBitcoinURI(goodAddress, toNanoCoins("0.1"), "", "glory"));
// amount present, label present, no message
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=12.34&label=Hello", BitcoinURI.convertToBitcoinURI(goodAddress, Utils.toNanoCoins("12.34"), "Hello", null));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=12.34&label=Hello", BitcoinURI.convertToBitcoinURI(goodAddress, Utils.toNanoCoins("12.34"), "Hello", ""));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=12.34&label=Hello", BitcoinURI.convertToBitcoinURI(goodAddress, toNanoCoins("12.34"), "Hello", null));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=12.34&label=Hello", BitcoinURI.convertToBitcoinURI(goodAddress, toNanoCoins("12.34"), "Hello", ""));
// amount present, no label, no message
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=1000", BitcoinURI.convertToBitcoinURI(goodAddress, Utils.toNanoCoins("1000"), null, null));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=1000", BitcoinURI.convertToBitcoinURI(goodAddress, Utils.toNanoCoins("1000"), "", ""));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=1000", BitcoinURI.convertToBitcoinURI(goodAddress, toNanoCoins("1000"), null, null));
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?amount=1000", BitcoinURI.convertToBitcoinURI(goodAddress, toNanoCoins("1000"), "", ""));
// no amount, label present, no message
assertEquals("bitcoin:" + MAINNET_GOOD_ADDRESS + "?label=Hello", BitcoinURI.convertToBitcoinURI(goodAddress, null, "Hello", null));
@ -363,7 +362,7 @@ public class BitcoinURITest {
String str = "bitcoin://1KzTSfqjF2iKCduwz59nv2uqh1W2JsTxZH?amount=0.01000000";
BitcoinURI uri = new BitcoinURI(str);
assertEquals("1KzTSfqjF2iKCduwz59nv2uqh1W2JsTxZH", uri.getAddress().toString());
assertEquals(Utils.toNanoCoins(0, 1), uri.getAmount());
assertEquals(toNanoCoins(0, 1), uri.getAmount());
}
@Test(expected = BitcoinURIParseException.class)

View File

@ -28,6 +28,7 @@ import org.junit.Test;
import java.net.InetAddress;
import java.util.ArrayList;
import static com.google.bitcoin.core.Coin.*;
import static com.google.common.base.Preconditions.checkNotNull;
import static org.junit.Assert.*;
@ -71,14 +72,14 @@ public class DefaultCoinSelectorTest extends TestWithWallet {
@Test
public void depthOrdering() throws Exception {
// Send two transactions in two blocks on top of each other.
Transaction t1 = checkNotNull(sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN));
Transaction t2 = checkNotNull(sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN));
Transaction t1 = checkNotNull(sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN));
Transaction t2 = checkNotNull(sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN));
// Check we selected just the oldest one.
DefaultCoinSelector selector = new DefaultCoinSelector();
CoinSelection selection = selector.select(Utils.COIN, wallet.calculateAllSpendCandidates(true));
CoinSelection selection = selector.select(COIN, wallet.calculateAllSpendCandidates(true));
assertTrue(selection.gathered.contains(t1.getOutputs().get(0)));
assertEquals(Utils.COIN, selection.valueGathered);
assertEquals(COIN, selection.valueGathered);
// Check we ordered them correctly (by depth).
ArrayList<TransactionOutput> candidates = new ArrayList<TransactionOutput>();
@ -93,12 +94,12 @@ public class DefaultCoinSelectorTest extends TestWithWallet {
public void coinAgeOrdering() throws Exception {
// Send three transactions in four blocks on top of each other. Coin age of t1 is 1*4=4, coin age of t2 = 2*2=4
// and t3=0.01.
Transaction t1 = checkNotNull(sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN));
Transaction t1 = checkNotNull(sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN));
// Padding block.
wallet.notifyNewBestBlock(FakeTxBuilder.createFakeBlock(blockStore).storedBlock);
final Coin TWO_COINS = Utils.COIN.multiply(Coin.valueOf(2));
final Coin TWO_COINS = 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));
Transaction t3 = checkNotNull(sendMoneyToWallet(CENT, AbstractBlockChain.NewBlockType.BEST_CHAIN));
// Should be ordered t2, t1, t3.
ArrayList<TransactionOutput> candidates = new ArrayList<TransactionOutput>();

View File

@ -25,6 +25,7 @@ import com.google.common.collect.ImmutableList;
import org.junit.Before;
import org.junit.Test;
import static com.google.bitcoin.core.Coin.COIN;
import static com.google.bitcoin.script.ScriptOpCodes.OP_PUSHDATA1;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
@ -59,7 +60,7 @@ public class DefaultRiskAnalysisTest {
// Verify that just having a lock time in the future is not enough to be considered risky (it's still final).
Transaction tx = new Transaction(params);
TransactionInput input = tx.addInput(params.getGenesisBlock().getTransactions().get(0).getOutput(0));
tx.addOutput(Utils.COIN, key1);
tx.addOutput(COIN, key1);
tx.setLockTime(TIMESTAMP + 86400);
{
@ -93,7 +94,7 @@ public class DefaultRiskAnalysisTest {
public void selfCreatedAreNotRisky() {
Transaction tx = new Transaction(params);
tx.addInput(params.getGenesisBlock().getTransactions().get(0).getOutput(0)).setSequenceNumber(1);
tx.addOutput(Utils.COIN, key1);
tx.addOutput(COIN, key1);
tx.setLockTime(TIMESTAMP + 86400);
{
@ -114,11 +115,11 @@ public class DefaultRiskAnalysisTest {
// Final tx has a dependency that is non-final.
Transaction tx1 = new Transaction(params);
tx1.addInput(params.getGenesisBlock().getTransactions().get(0).getOutput(0)).setSequenceNumber(1);
TransactionOutput output = tx1.addOutput(Utils.COIN, key1);
TransactionOutput output = tx1.addOutput(COIN, key1);
tx1.setLockTime(TIMESTAMP + 86400);
Transaction tx2 = new Transaction(params);
tx2.addInput(output);
tx2.addOutput(Utils.COIN, new ECKey());
tx2.addOutput(COIN, new ECKey());
DefaultRiskAnalysis analysis = DefaultRiskAnalysis.FACTORY.create(wallet, tx2, ImmutableList.of(tx1));
assertEquals(RiskAnalysis.Result.NON_FINAL, analysis.analyze());
@ -129,7 +130,7 @@ public class DefaultRiskAnalysisTest {
public void nonStandardDust() {
Transaction standardTx = new Transaction(params);
standardTx.addInput(params.getGenesisBlock().getTransactions().get(0).getOutput(0));
standardTx.addOutput(Utils.COIN, key1);
standardTx.addOutput(COIN, key1);
assertEquals(RiskAnalysis.Result.OK, DefaultRiskAnalysis.FACTORY.create(wallet, standardTx, NO_DEPS).analyze());
Transaction dustTx = new Transaction(params);
@ -155,7 +156,7 @@ public class DefaultRiskAnalysisTest {
// Test non-standard script as an output.
tx.clearInputs();
assertEquals(DefaultRiskAnalysis.RuleViolation.NONE, DefaultRiskAnalysis.isStandard(tx));
tx.addOutput(new TransactionOutput(params, null, Utils.COIN, nonStandardScript));
tx.addOutput(new TransactionOutput(params, null, COIN, nonStandardScript));
assertEquals(DefaultRiskAnalysis.RuleViolation.SHORTEST_POSSIBLE_PUSHDATA, DefaultRiskAnalysis.isStandard(tx));
}
}

View File

@ -8,6 +8,8 @@ import com.google.bitcoin.utils.Threading;
import java.io.File;
import static com.google.bitcoin.core.Coin.*;
/**
* This is a little test app that waits for a coin on a local regtest node, then generates two transactions that double
* spend the same output and sends them. It's useful for testing double spend codepaths but is otherwise not something
@ -25,9 +27,9 @@ public class DoubleSpend {
System.out.println(kit.wallet());
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(Coin.TEN));
kit.wallet().getBalanceFuture(COIN, Wallet.BalanceType.AVAILABLE).get();
Transaction tx1 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), CENT);
Transaction tx2 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), CENT.add(TEN));
final Peer peer = kit.peerGroup().getConnectedPeers().get(0);
peer.addEventListener(new AbstractPeerEventListener() {
@Override

View File

@ -39,8 +39,8 @@ import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import static com.google.bitcoin.core.Coin.CENT;
import static com.google.bitcoin.core.Coin.TEN;
import static com.google.bitcoin.core.Utils.CENT;
/**
* Simple client that connects to the given host, opens a channel, and pays one cent.
@ -169,7 +169,7 @@ public class ExamplePaymentChannelClient {
// ESTIMATED because we don't really need to wait for confirmation.
ListenableFuture<Coin> balanceFuture = appKit.wallet().getBalanceFuture(amountPlusFee, Wallet.BalanceType.ESTIMATED);
if (!balanceFuture.isDone()) {
System.out.println("Please send " + Utils.bitcoinValueToFriendlyString(amountPlusFee) +
System.out.println("Please send " + amountPlusFee.toFriendlyString() +
" BTC to " + myKey.toAddress(params));
Futures.getUnchecked(balanceFuture);
}

View File

@ -85,7 +85,7 @@ public class ForwardingService {
//
// The transaction "tx" can either be pending, or included into a block (we didn't see the broadcast).
Coin value = tx.getValueSentToMe(w);
System.out.println("Received tx for " + Utils.bitcoinValueToFriendlyString(value) + ": " + tx);
System.out.println("Received tx for " + value.toFriendlyString() + ": " + 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,7 +121,7 @@ public class ForwardingService {
private static void forwardCoins(Transaction tx) {
try {
Coin value = tx.getValueSentToMe(kit.wallet());
System.out.println("Forwarding " + Utils.bitcoinValueToFriendlyString(value) + " BTC");
System.out.println("Forwarding " + value.toFriendlyString() + " BTC");
// Now send the coins back! Send with a small fee attached to ensure rapid confirmation.
final Coin amountToSend = value.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
final Wallet.SendResult sendResult = kit.wallet().sendCoins(kit.peerGroup(), forwardingAddress, amountToSend);

View File

@ -67,7 +67,7 @@ public class PrivateKeys {
peerGroup.stopAsync();
// And take them!
System.out.println("Claiming " + Utils.bitcoinValueToFriendlyString(wallet.getBalance()) + " coins");
System.out.println("Claiming " + wallet.getBalance().toFriendlyString() + " coins");
wallet.sendCoins(peerGroup, destination, wallet.getBalance());
// Wait a few seconds to let the packets flush out to the network (ugly).
Thread.sleep(5000);

View File

@ -66,6 +66,8 @@ import java.util.concurrent.TimeoutException;
import java.util.logging.Level;
import java.util.logging.LogManager;
import static com.google.bitcoin.core.Coin.toNanoCoins;
/**
* A command line tool for manipulating wallets and working with Bitcoin.
*/
@ -126,7 +128,7 @@ public class WalletTool {
public boolean matchBitcoins(Coin comparison) {
try {
Coin units = Utils.toNanoCoins(value);
Coin units = toNanoCoins(value);
switch (type) {
case LT: return comparison.compareTo(units) < 0;
case GT: return comparison.compareTo(units) > 0;
@ -325,7 +327,7 @@ public class WalletTool {
} else if (options.has(outputFlag)) {
Coin fee = Coin.ZERO;
if (options.has("fee")) {
fee = Utils.toNanoCoins((String)options.valueOf("fee"));
fee = toNanoCoins((String)options.valueOf("fee"));
}
String lockTime = null;
if (options.has("locktime")) {
@ -425,7 +427,7 @@ public class WalletTool {
}
String destination = parts[0];
try {
Coin value = Utils.toNanoCoins(parts[1]);
Coin value = toNanoCoins(parts[1]);
if (destination.startsWith("0")) {
// Treat as a raw public key.
byte[] pubKey = new BigInteger(destination, 16).toByteArray();
@ -505,7 +507,7 @@ public class WalletTool {
} catch (ExecutionException e) {
throw new RuntimeException(e);
} catch (InsufficientMoneyException e) {
System.err.println("Insufficient funds: have " + Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
System.err.println("Insufficient funds: have " + wallet.getBalance().toFriendlyString());
}
}
@ -615,7 +617,7 @@ public class WalletTool {
} catch (InterruptedException e1) {
// Ignore.
} catch (InsufficientMoneyException e) {
System.err.println("Insufficient funds: have " + Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
System.err.println("Insufficient funds: have " + wallet.getBalance().toFriendlyString());
} catch (BlockStoreException e) {
throw new RuntimeException(e);
}
@ -679,7 +681,7 @@ public class WalletTool {
saveWallet(walletFile);
Coin balance = wallet.getBalance(Wallet.BalanceType.ESTIMATED);
if (condition.matchBitcoins(balance)) {
System.out.println(Utils.bitcoinValueToFriendlyString(balance));
System.out.println(balance.toFriendlyString());
latch.countDown();
}
}