mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-02-07 06:44:16 +00:00
Wrap coin-ish BigIntegers into Coin class.
This commit is contained in:
parent
d2e1b14d4c
commit
022e7c27fe
@ -19,7 +19,6 @@ package com.google.bitcoin.core;
|
|||||||
import com.google.bitcoin.script.Script;
|
import com.google.bitcoin.script.Script;
|
||||||
import com.google.bitcoin.wallet.AbstractKeyChainEventListener;
|
import com.google.bitcoin.wallet.AbstractKeyChainEventListener;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -27,12 +26,12 @@ import java.util.List;
|
|||||||
*/
|
*/
|
||||||
public abstract class AbstractWalletEventListener extends AbstractKeyChainEventListener implements WalletEventListener {
|
public abstract class AbstractWalletEventListener extends AbstractKeyChainEventListener implements WalletEventListener {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
onChange();
|
onChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
onChange();
|
onChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,7 +166,7 @@ public class Block extends Message {
|
|||||||
* <p>The half-life is controlled by {@link com.google.bitcoin.core.NetworkParameters#getSubsidyDecreaseBlockCount()}.
|
* <p>The half-life is controlled by {@link com.google.bitcoin.core.NetworkParameters#getSubsidyDecreaseBlockCount()}.
|
||||||
* </p>
|
* </p>
|
||||||
*/
|
*/
|
||||||
public BigInteger getBlockInflation(int height) {
|
public Coin getBlockInflation(int height) {
|
||||||
return Utils.toNanoCoins(50, 0).shiftRight(height / params.getSubsidyDecreaseBlockCount());
|
return Utils.toNanoCoins(50, 0).shiftRight(height / params.getSubsidyDecreaseBlockCount());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -953,7 +953,7 @@ public class Block extends Message {
|
|||||||
static private int txCounter;
|
static private int txCounter;
|
||||||
|
|
||||||
/** Adds a coinbase transaction to the block. This exists for unit tests. */
|
/** Adds a coinbase transaction to the block. This exists for unit tests. */
|
||||||
void addCoinbaseTransaction(byte[] pubKeyTo, BigInteger value) {
|
void addCoinbaseTransaction(byte[] pubKeyTo, Coin value) {
|
||||||
unCacheTransactions();
|
unCacheTransactions();
|
||||||
transactions = new ArrayList<Transaction>();
|
transactions = new ArrayList<Transaction>();
|
||||||
Transaction coinbase = new Transaction(params);
|
Transaction coinbase = new Transaction(params);
|
||||||
@ -989,7 +989,7 @@ public class Block extends Message {
|
|||||||
* In this variant you can specify a public key (pubkey) for use in generating coinbase blocks.
|
* In this variant you can specify a public key (pubkey) for use in generating coinbase blocks.
|
||||||
*/
|
*/
|
||||||
Block createNextBlock(@Nullable Address to, @Nullable TransactionOutPoint prevOut, long time,
|
Block createNextBlock(@Nullable Address to, @Nullable TransactionOutPoint prevOut, long time,
|
||||||
byte[] pubKey, BigInteger coinbaseValue) {
|
byte[] pubKey, Coin coinbaseValue) {
|
||||||
Block b = new Block(params);
|
Block b = new Block(params);
|
||||||
b.setDifficultyTarget(difficultyTarget);
|
b.setDifficultyTarget(difficultyTarget);
|
||||||
b.addCoinbaseTransaction(pubKey, coinbaseValue);
|
b.addCoinbaseTransaction(pubKey, coinbaseValue);
|
||||||
@ -1036,7 +1036,7 @@ public class Block extends Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public Block createNextBlock(@Nullable Address to, BigInteger value) {
|
public Block createNextBlock(@Nullable Address to, Coin value) {
|
||||||
return createNextBlock(to, null, Utils.currentTimeSeconds(), pubkeyForTesting, value);
|
return createNextBlock(to, null, Utils.currentTimeSeconds(), pubkeyForTesting, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1046,7 +1046,7 @@ public class Block extends Message {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
public Block createNextBlockWithCoinbase(byte[] pubKey, BigInteger coinbaseValue) {
|
public Block createNextBlockWithCoinbase(byte[] pubKey, Coin coinbaseValue) {
|
||||||
return createNextBlock(null, null, Utils.currentTimeSeconds(), pubKey, coinbaseValue);
|
return createNextBlock(null, null, Utils.currentTimeSeconds(), pubKey, coinbaseValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
132
core/src/main/java/com/google/bitcoin/core/Coin.java
Normal file
132
core/src/main/java/com/google/bitcoin/core/Coin.java
Normal file
@ -0,0 +1,132 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014 Andreas Schildbach
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.google.bitcoin.core;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.math.BigInteger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Represents a monetary Bitcoin value. This class is immutable.
|
||||||
|
*/
|
||||||
|
public final class Coin implements Comparable<Coin>, Serializable {
|
||||||
|
|
||||||
|
public static final Coin ZERO = new Coin(BigInteger.ZERO);
|
||||||
|
public static final Coin ONE = new Coin(BigInteger.ONE);
|
||||||
|
public static final Coin TEN = new Coin(BigInteger.TEN);
|
||||||
|
|
||||||
|
private final BigInteger value;
|
||||||
|
|
||||||
|
public Coin(final BigInteger value) {
|
||||||
|
this.value = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin(final String value, final int radix) {
|
||||||
|
this(new BigInteger(value, radix));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin(final byte[] value) {
|
||||||
|
this(new BigInteger(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Coin valueOf(final long value) {
|
||||||
|
return new Coin(BigInteger.valueOf(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin add(final Coin value) {
|
||||||
|
return new Coin(this.value.add(value.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin subtract(final Coin value) {
|
||||||
|
return new Coin(this.value.subtract(value.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin multiply(final Coin value) {
|
||||||
|
return new Coin(this.value.multiply(value.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin multiply(final long value) {
|
||||||
|
return multiply(Coin.valueOf(value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin divide(final Coin value) {
|
||||||
|
return new Coin(this.value.divide(value.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin[] divideAndRemainder(final Coin value) {
|
||||||
|
final BigInteger[] result = this.value.divideAndRemainder(value.value);
|
||||||
|
return new Coin[] { new Coin(result[0]), new Coin(result[1]) };
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin shiftLeft(final int n) {
|
||||||
|
return new Coin(this.value.shiftLeft(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin shiftRight(final int n) {
|
||||||
|
return new Coin(this.value.shiftRight(n));
|
||||||
|
}
|
||||||
|
|
||||||
|
public int signum() {
|
||||||
|
return this.value.signum();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Coin negate() {
|
||||||
|
return new Coin(this.value.negate());
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte[] toByteArray() {
|
||||||
|
return this.value.toByteArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long longValue() {
|
||||||
|
return this.value.longValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double doubleValue() {
|
||||||
|
return this.value.doubleValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
public BigInteger toBigInteger() {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String toString() {
|
||||||
|
return value.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (o == this)
|
||||||
|
return true;
|
||||||
|
if (o == null || o.getClass() != getClass())
|
||||||
|
return false;
|
||||||
|
final Coin other = (Coin) o;
|
||||||
|
if (!this.value.equals(other.value))
|
||||||
|
return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return this.value.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int compareTo(final Coin other) {
|
||||||
|
return this.value.compareTo(other.value);
|
||||||
|
}
|
||||||
|
}
|
@ -23,7 +23,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@ -175,12 +174,12 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
sigOps += tx.getSigOpCount();
|
sigOps += tx.getSigOpCount();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BigInteger totalFees = BigInteger.ZERO;
|
Coin totalFees = Coin.ZERO;
|
||||||
BigInteger coinbaseValue = null;
|
Coin coinbaseValue = null;
|
||||||
for (final Transaction tx : block.transactions) {
|
for (final Transaction tx : block.transactions) {
|
||||||
boolean isCoinBase = tx.isCoinBase();
|
boolean isCoinBase = tx.isCoinBase();
|
||||||
BigInteger valueIn = BigInteger.ZERO;
|
Coin valueIn = Coin.ZERO;
|
||||||
BigInteger valueOut = BigInteger.ZERO;
|
Coin valueOut = Coin.ZERO;
|
||||||
final List<Script> prevOutScripts = new LinkedList<Script>();
|
final List<Script> prevOutScripts = new LinkedList<Script>();
|
||||||
if (!isCoinBase) {
|
if (!isCoinBase) {
|
||||||
// For each input of the transaction remove the corresponding output from the set of unspent
|
// For each input of the transaction remove the corresponding output from the set of unspent
|
||||||
@ -300,16 +299,16 @@ public class FullPrunedBlockChain extends AbstractBlockChain {
|
|||||||
throw new VerificationException("Block failed BIP30 test!");
|
throw new VerificationException("Block failed BIP30 test!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
BigInteger totalFees = BigInteger.ZERO;
|
Coin totalFees = Coin.ZERO;
|
||||||
BigInteger coinbaseValue = null;
|
Coin coinbaseValue = null;
|
||||||
|
|
||||||
if (scriptVerificationExecutor.isShutdown())
|
if (scriptVerificationExecutor.isShutdown())
|
||||||
scriptVerificationExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
scriptVerificationExecutor = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors());
|
||||||
List<Future<VerificationException>> listScriptVerificationResults = new ArrayList<Future<VerificationException>>(transactions.size());
|
List<Future<VerificationException>> listScriptVerificationResults = new ArrayList<Future<VerificationException>>(transactions.size());
|
||||||
for(final Transaction tx : transactions) {
|
for(final Transaction tx : transactions) {
|
||||||
boolean isCoinBase = tx.isCoinBase();
|
boolean isCoinBase = tx.isCoinBase();
|
||||||
BigInteger valueIn = BigInteger.ZERO;
|
Coin valueIn = Coin.ZERO;
|
||||||
BigInteger valueOut = BigInteger.ZERO;
|
Coin valueOut = Coin.ZERO;
|
||||||
final List<Script> prevOutScripts = new LinkedList<Script>();
|
final List<Script> prevOutScripts = new LinkedList<Script>();
|
||||||
if (!isCoinBase) {
|
if (!isCoinBase) {
|
||||||
for (int index = 0; index < tx.getInputs().size(); index++) {
|
for (int index = 0; index < tx.getInputs().size(); index++) {
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
package com.google.bitcoin.core;
|
package com.google.bitcoin.core;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@ -27,17 +26,17 @@ import static com.google.common.base.Preconditions.checkNotNull;
|
|||||||
public class InsufficientMoneyException extends Exception {
|
public class InsufficientMoneyException extends Exception {
|
||||||
/** Contains the number of satoshis that would have been required to complete the operation. */
|
/** Contains the number of satoshis that would have been required to complete the operation. */
|
||||||
@Nullable
|
@Nullable
|
||||||
public final BigInteger missing;
|
public final Coin missing;
|
||||||
|
|
||||||
protected InsufficientMoneyException() {
|
protected InsufficientMoneyException() {
|
||||||
this.missing = null;
|
this.missing = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsufficientMoneyException(BigInteger missing) {
|
public InsufficientMoneyException(Coin missing) {
|
||||||
this(missing, "Insufficient money, missing " + missing + " satoshis");
|
this(missing, "Insufficient money, missing " + missing + " satoshis");
|
||||||
}
|
}
|
||||||
|
|
||||||
public InsufficientMoneyException(BigInteger missing, String message) {
|
public InsufficientMoneyException(Coin missing, String message) {
|
||||||
super(message);
|
super(message);
|
||||||
this.missing = checkNotNull(missing);
|
this.missing = checkNotNull(missing);
|
||||||
}
|
}
|
||||||
|
@ -133,7 +133,7 @@ public abstract class NetworkParameters implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* The maximum money to be generated
|
* The maximum money to be generated
|
||||||
*/
|
*/
|
||||||
public static final BigInteger MAX_MONEY = new BigInteger("21000000", 10).multiply(COIN);
|
public static final Coin MAX_MONEY = new Coin("21000000", 10).multiply(COIN);
|
||||||
|
|
||||||
/** Alias for TestNet3Params.get(), use that instead. */
|
/** Alias for TestNet3Params.get(), use that instead. */
|
||||||
@Deprecated
|
@Deprecated
|
||||||
|
@ -45,7 +45,6 @@ import javax.annotation.Nullable;
|
|||||||
import java.lang.reflect.Constructor;
|
import java.lang.reflect.Constructor;
|
||||||
import java.lang.reflect.Field;
|
import java.lang.reflect.Field;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -179,7 +178,7 @@ public class PeerGroup extends AbstractExecutionThreadService implements Transac
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
// We received a relevant transaction. We MAY need to recalculate and resend the Bloom filter, but only
|
// We received a relevant transaction. We MAY need to recalculate and resend the Bloom filter, but only
|
||||||
// if we have received a transaction that includes a relevant pay-to-pubkey output.
|
// if we have received a transaction that includes a relevant pay-to-pubkey output.
|
||||||
//
|
//
|
||||||
|
@ -17,7 +17,6 @@
|
|||||||
package com.google.bitcoin.core;
|
package com.google.bitcoin.core;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A StoredTransactionOutput message contains the information necessary to check a spending transaction.
|
* A StoredTransactionOutput message contains the information necessary to check a spending transaction.
|
||||||
@ -31,7 +30,7 @@ public class StoredTransactionOutput implements Serializable {
|
|||||||
* A transaction output has some value and a script used for authenticating that the redeemer is allowed to spend
|
* A transaction output has some value and a script used for authenticating that the redeemer is allowed to spend
|
||||||
* this output.
|
* this output.
|
||||||
*/
|
*/
|
||||||
private BigInteger value;
|
private Coin value;
|
||||||
private byte[] scriptBytes;
|
private byte[] scriptBytes;
|
||||||
|
|
||||||
/** Hash of the transaction to which we refer. */
|
/** Hash of the transaction to which we refer. */
|
||||||
@ -53,7 +52,7 @@ public class StoredTransactionOutput implements Serializable {
|
|||||||
* @param height the height this output was created in
|
* @param height the height this output was created in
|
||||||
* @param scriptBytes
|
* @param scriptBytes
|
||||||
*/
|
*/
|
||||||
public StoredTransactionOutput(Sha256Hash hash, long index, BigInteger value, int height, boolean isCoinbase, byte[] scriptBytes) {
|
public StoredTransactionOutput(Sha256Hash hash, long index, Coin value, int height, boolean isCoinbase, byte[] scriptBytes) {
|
||||||
this.hash = hash;
|
this.hash = hash;
|
||||||
this.index = index;
|
this.index = index;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
@ -73,7 +72,7 @@ public class StoredTransactionOutput implements Serializable {
|
|||||||
byte[] valueBytes = new byte[8];
|
byte[] valueBytes = new byte[8];
|
||||||
if (in.read(valueBytes, 0, 8) != 8)
|
if (in.read(valueBytes, 0, 8) != 8)
|
||||||
throw new EOFException();
|
throw new EOFException();
|
||||||
value = BigInteger.valueOf(Utils.readInt64(valueBytes, 0));
|
value = Coin.valueOf(Utils.readInt64(valueBytes, 0));
|
||||||
|
|
||||||
int scriptBytesLength = ((in.read() & 0xFF) << 0) |
|
int scriptBytesLength = ((in.read() & 0xFF) << 0) |
|
||||||
((in.read() & 0xFF) << 8) |
|
((in.read() & 0xFF) << 8) |
|
||||||
@ -103,7 +102,7 @@ public class StoredTransactionOutput implements Serializable {
|
|||||||
* The value which this Transaction output holds
|
* The value which this Transaction output holds
|
||||||
* @return the value
|
* @return the value
|
||||||
*/
|
*/
|
||||||
public BigInteger getValue() {
|
public Coin getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -157,7 +156,7 @@ public class StoredTransactionOutput implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void serializeToStream(OutputStream bos) throws IOException {
|
public void serializeToStream(OutputStream bos) throws IOException {
|
||||||
Utils.uint64ToByteStreamLE(value, bos);
|
Utils.uint64ToByteStreamLE(value.toBigInteger(), bos);
|
||||||
|
|
||||||
bos.write(0xFF & scriptBytes.length >> 0);
|
bos.write(0xFF & scriptBytes.length >> 0);
|
||||||
bos.write(0xFF & scriptBytes.length >> 8);
|
bos.write(0xFF & scriptBytes.length >> 8);
|
||||||
|
@ -33,7 +33,6 @@ import org.spongycastle.crypto.params.KeyParameter;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.text.ParseException;
|
import java.text.ParseException;
|
||||||
import java.text.SimpleDateFormat;
|
import java.text.SimpleDateFormat;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -87,14 +86,14 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
* If fee is lower than this value (in satoshis), a default reference client will treat it as if there were no fee.
|
* If fee is lower than this value (in satoshis), a default reference client will treat it as if there were no fee.
|
||||||
* Currently this is 10000 satoshis.
|
* Currently this is 10000 satoshis.
|
||||||
*/
|
*/
|
||||||
public static final BigInteger REFERENCE_DEFAULT_MIN_TX_FEE = BigInteger.valueOf(10000);
|
public static final Coin REFERENCE_DEFAULT_MIN_TX_FEE = Coin.valueOf(10000);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Any standard (ie pay-to-address) output smaller than this value (in satoshis) will most likely be rejected by the network.
|
* Any standard (ie pay-to-address) output smaller than this value (in satoshis) will most likely be rejected by the network.
|
||||||
* This is calculated by assuming a standard output will be 34 bytes, and then using the formula used in
|
* This is calculated by assuming a standard output will be 34 bytes, and then using the formula used in
|
||||||
* {@link TransactionOutput#getMinNonDustValue(BigInteger)}. Currently it's 5460 satoshis.
|
* {@link TransactionOutput#getMinNonDustValue(Coin)}. Currently it's 5460 satoshis.
|
||||||
*/
|
*/
|
||||||
public static final BigInteger MIN_NONDUST_OUTPUT = BigInteger.valueOf(5460);
|
public static final Coin MIN_NONDUST_OUTPUT = Coin.valueOf(5460);
|
||||||
|
|
||||||
// These are serialized in both bitcoin and java serialization.
|
// These are serialized in both bitcoin and java serialization.
|
||||||
private long version;
|
private long version;
|
||||||
@ -237,10 +236,10 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
* Calculates the sum of the outputs that are sending coins to a key in the wallet. The flag controls whether to
|
* Calculates the sum of the outputs that are sending coins to a key in the wallet. The flag controls whether to
|
||||||
* include spent outputs or not.
|
* include spent outputs or not.
|
||||||
*/
|
*/
|
||||||
BigInteger getValueSentToMe(Wallet wallet, boolean includeSpent) {
|
Coin getValueSentToMe(Wallet wallet, boolean includeSpent) {
|
||||||
maybeParse();
|
maybeParse();
|
||||||
// This is tested in WalletTest.
|
// This is tested in WalletTest.
|
||||||
BigInteger v = BigInteger.ZERO;
|
Coin v = Coin.ZERO;
|
||||||
for (TransactionOutput o : outputs) {
|
for (TransactionOutput o : outputs) {
|
||||||
if (!o.isMineOrWatched(wallet)) continue;
|
if (!o.isMineOrWatched(wallet)) continue;
|
||||||
if (!includeSpent && !o.isAvailableForSpending()) continue;
|
if (!includeSpent && !o.isAvailableForSpending()) continue;
|
||||||
@ -275,7 +274,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Calculates the sum of the outputs that are sending coins to a key in the wallet.
|
* Calculates the sum of the outputs that are sending coins to a key in the wallet.
|
||||||
*/
|
*/
|
||||||
public BigInteger getValueSentToMe(Wallet wallet) {
|
public Coin getValueSentToMe(Wallet wallet) {
|
||||||
return getValueSentToMe(wallet, true);
|
return getValueSentToMe(wallet, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -347,10 +346,10 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
*
|
*
|
||||||
* @return sum in nanocoins.
|
* @return sum in nanocoins.
|
||||||
*/
|
*/
|
||||||
public BigInteger getValueSentFromMe(Wallet wallet) throws ScriptException {
|
public Coin getValueSentFromMe(Wallet wallet) throws ScriptException {
|
||||||
maybeParse();
|
maybeParse();
|
||||||
// This is tested in WalletTest.
|
// This is tested in WalletTest.
|
||||||
BigInteger v = BigInteger.ZERO;
|
Coin v = Coin.ZERO;
|
||||||
for (TransactionInput input : inputs) {
|
for (TransactionInput input : inputs) {
|
||||||
// This input is taking value from a transaction in our wallet. To discover the value,
|
// This input is taking value from a transaction in our wallet. To discover the value,
|
||||||
// we must find the connected transaction.
|
// we must find the connected transaction.
|
||||||
@ -373,7 +372,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Returns the difference of {@link Transaction#getValueSentFromMe(Wallet)} and {@link Transaction#getValueSentToMe(Wallet)}.
|
* Returns the difference of {@link Transaction#getValueSentFromMe(Wallet)} and {@link Transaction#getValueSentToMe(Wallet)}.
|
||||||
*/
|
*/
|
||||||
public BigInteger getValue(Wallet wallet) throws ScriptException {
|
public Coin getValue(Wallet wallet) throws ScriptException {
|
||||||
return getValueSentToMe(wallet).subtract(getValueSentFromMe(wallet));
|
return getValueSentToMe(wallet).subtract(getValueSentFromMe(wallet));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -383,8 +382,8 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
*
|
*
|
||||||
* @return fee, or null if it cannot be determined
|
* @return fee, or null if it cannot be determined
|
||||||
*/
|
*/
|
||||||
public BigInteger getFee() {
|
public Coin getFee() {
|
||||||
BigInteger fee = BigInteger.ZERO;
|
Coin fee = Coin.ZERO;
|
||||||
for (TransactionInput input : inputs) {
|
for (TransactionInput input : inputs) {
|
||||||
if (input.getValue() == null)
|
if (input.getValue() == null)
|
||||||
return null;
|
return null;
|
||||||
@ -807,7 +806,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Creates an output based on the given address and value, adds it to this transaction, and returns the new output.
|
* Creates an output based on the given address and value, adds it to this transaction, and returns the new output.
|
||||||
*/
|
*/
|
||||||
public TransactionOutput addOutput(BigInteger value, Address address) {
|
public TransactionOutput addOutput(Coin value, Address address) {
|
||||||
return addOutput(new TransactionOutput(params, this, value, address));
|
return addOutput(new TransactionOutput(params, this, value, address));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -815,7 +814,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
* Creates an output that pays to the given pubkey directly (no address) with the given value, adds it to this
|
* Creates an output that pays to the given pubkey directly (no address) with the given value, adds it to this
|
||||||
* transaction, and returns the new output.
|
* transaction, and returns the new output.
|
||||||
*/
|
*/
|
||||||
public TransactionOutput addOutput(BigInteger value, ECKey pubkey) {
|
public TransactionOutput addOutput(Coin value, ECKey pubkey) {
|
||||||
return addOutput(new TransactionOutput(params, this, value, pubkey));
|
return addOutput(new TransactionOutput(params, this, value, pubkey));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -823,7 +822,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
* Creates an output that pays to the given script. The address and key forms are specialisations of this method,
|
* Creates an output that pays to the given script. The address and key forms are specialisations of this method,
|
||||||
* you won't normally need to use it unless you're doing unusual things.
|
* you won't normally need to use it unless you're doing unusual things.
|
||||||
*/
|
*/
|
||||||
public TransactionOutput addOutput(BigInteger value, Script script) {
|
public TransactionOutput addOutput(Coin value, Script script) {
|
||||||
return addOutput(new TransactionOutput(params, this, value, script.getProgram()));
|
return addOutput(new TransactionOutput(params, this, value, script.getProgram()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1263,7 +1262,7 @@ public class Transaction extends ChildMessage implements Serializable {
|
|||||||
if (this.getMessageSize() > Block.MAX_BLOCK_SIZE)
|
if (this.getMessageSize() > Block.MAX_BLOCK_SIZE)
|
||||||
throw new VerificationException("Transaction larger than MAX_BLOCK_SIZE");
|
throw new VerificationException("Transaction larger than MAX_BLOCK_SIZE");
|
||||||
|
|
||||||
BigInteger valueOut = BigInteger.ZERO;
|
Coin valueOut = Coin.ZERO;
|
||||||
for (TransactionOutput output : outputs) {
|
for (TransactionOutput output : outputs) {
|
||||||
if (output.getValue().signum() < 0)
|
if (output.getValue().signum() < 0)
|
||||||
throw new VerificationException("Transaction output negative");
|
throw new VerificationException("Transaction output negative");
|
||||||
|
@ -25,7 +25,6 @@ import java.io.ObjectOutputStream;
|
|||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
@ -58,7 +57,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
|||||||
transient private WeakReference<Script> scriptSig;
|
transient private WeakReference<Script> scriptSig;
|
||||||
/** Value of the output connected to the input, if known. This field does not participate in equals()/hashCode(). */
|
/** Value of the output connected to the input, if known. This field does not participate in equals()/hashCode(). */
|
||||||
@Nullable
|
@Nullable
|
||||||
private final BigInteger value;
|
private final Coin value;
|
||||||
// A pointer to the transaction that owns this input.
|
// A pointer to the transaction that owns this input.
|
||||||
private final Transaction parentTransaction;
|
private final Transaction parentTransaction;
|
||||||
|
|
||||||
@ -75,7 +74,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public TransactionInput(NetworkParameters params, @Nullable Transaction parentTransaction, byte[] scriptBytes,
|
public TransactionInput(NetworkParameters params, @Nullable Transaction parentTransaction, byte[] scriptBytes,
|
||||||
TransactionOutPoint outpoint, @Nullable BigInteger value) {
|
TransactionOutPoint outpoint, @Nullable Coin value) {
|
||||||
super(params);
|
super(params);
|
||||||
this.scriptBytes = scriptBytes;
|
this.scriptBytes = scriptBytes;
|
||||||
this.outpoint = outpoint;
|
this.outpoint = outpoint;
|
||||||
@ -267,7 +266,7 @@ public class TransactionInput extends ChildMessage implements Serializable {
|
|||||||
* @return Value of the output connected to this input, if known. Null if unknown.
|
* @return Value of the output connected to this input, if known. Null if unknown.
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
public BigInteger getValue() {
|
public Coin getValue() {
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,16 +18,17 @@ package com.google.bitcoin.core;
|
|||||||
|
|
||||||
import com.google.bitcoin.script.Script;
|
import com.google.bitcoin.script.Script;
|
||||||
import com.google.bitcoin.script.ScriptBuilder;
|
import com.google.bitcoin.script.ScriptBuilder;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.ObjectOutputStream;
|
import java.io.ObjectOutputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.*;
|
||||||
@ -42,7 +43,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
|
|
||||||
// A transaction output has some value and a script used for authenticating that the redeemer is allowed to spend
|
// A transaction output has some value and a script used for authenticating that the redeemer is allowed to spend
|
||||||
// this output.
|
// this output.
|
||||||
private BigInteger value;
|
private Coin value;
|
||||||
private byte[] scriptBytes;
|
private byte[] scriptBytes;
|
||||||
|
|
||||||
// The script bytes are parsed and turned into a Script on demand.
|
// The script bytes are parsed and turned into a Script on demand.
|
||||||
@ -91,22 +92,22 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Creates an output that sends 'value' to the given address (public key hash). The amount should be created with
|
* Creates an output that sends 'value' to the given address (public key hash). The amount should be created with
|
||||||
* something like {@link Utils#toNanoCoins(int, int)}. Typically you would use
|
* something like {@link Utils#toNanoCoins(int, int)}. Typically you would use
|
||||||
* {@link Transaction#addOutput(java.math.BigInteger, Address)} instead of creating a TransactionOutput directly.
|
* {@link Transaction#addOutput(java.math.Coin, Address)} instead of creating a TransactionOutput directly.
|
||||||
*/
|
*/
|
||||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, BigInteger value, Address to) {
|
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, Coin value, Address to) {
|
||||||
this(params, parent, value, ScriptBuilder.createOutputScript(to).getProgram());
|
this(params, parent, value, ScriptBuilder.createOutputScript(to).getProgram());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an output that sends 'value' to the given public key using a simple CHECKSIG script (no addresses). The
|
* Creates an output that sends 'value' to the given public key using a simple CHECKSIG script (no addresses). The
|
||||||
* amount should be created with something like {@link Utils#toNanoCoins(int, int)}. Typically you would use
|
* amount should be created with something like {@link Utils#toNanoCoins(int, int)}. Typically you would use
|
||||||
* {@link Transaction#addOutput(java.math.BigInteger, ECKey)} instead of creating an output directly.
|
* {@link Transaction#addOutput(java.math.Coin, ECKey)} instead of creating an output directly.
|
||||||
*/
|
*/
|
||||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, BigInteger value, ECKey to) {
|
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, Coin value, ECKey to) {
|
||||||
this(params, parent, value, ScriptBuilder.createOutputScript(to).getProgram());
|
this(params, parent, value, ScriptBuilder.createOutputScript(to).getProgram());
|
||||||
}
|
}
|
||||||
|
|
||||||
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, BigInteger value, byte[] scriptBytes) {
|
public TransactionOutput(NetworkParameters params, @Nullable Transaction parent, Coin value, byte[] scriptBytes) {
|
||||||
super(params);
|
super(params);
|
||||||
// Negative values obviously make no sense, except for -1 which is used as a sentinel value when calculating
|
// 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.
|
// SIGHASH_SINGLE signatures, so unfortunately we have to allow that here.
|
||||||
@ -134,11 +135,11 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void parseLite() throws ProtocolException {
|
protected void parseLite() throws ProtocolException {
|
||||||
// TODO: There is no reason to use BigInteger for values, they are always smaller than 21 million * COIN
|
// TODO: There is no reason to use Coin for values, they are always smaller than 21 million * COIN
|
||||||
// The only reason to use BigInteger would be to properly read values from the reference implementation, however
|
// The only reason to use Coin would be to properly read values from the reference implementation, however
|
||||||
// the reference implementation uses signed 64-bit integers for its values as well (though it probably shouldn't)
|
// the reference implementation uses signed 64-bit integers for its values as well (though it probably shouldn't)
|
||||||
long outputValue = readInt64();
|
long outputValue = readInt64();
|
||||||
value = BigInteger.valueOf(outputValue);
|
value = Coin.valueOf(outputValue);
|
||||||
scriptLen = (int) readVarInt();
|
scriptLen = (int) readVarInt();
|
||||||
length = cursor - offset + scriptLen;
|
length = cursor - offset + scriptLen;
|
||||||
}
|
}
|
||||||
@ -160,7 +161,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
* Returns the value of this output in nanocoins. This is the amount of currency that the destination address
|
* Returns the value of this output in nanocoins. This is the amount of currency that the destination address
|
||||||
* receives.
|
* receives.
|
||||||
*/
|
*/
|
||||||
public BigInteger getValue() {
|
public Coin getValue() {
|
||||||
maybeParse();
|
maybeParse();
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
@ -168,7 +169,7 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
/**
|
/**
|
||||||
* Sets the value of this output in nanocoins.
|
* Sets the value of this output in nanocoins.
|
||||||
*/
|
*/
|
||||||
public void setValue(BigInteger value) {
|
public void setValue(Coin value) {
|
||||||
checkNotNull(value);
|
checkNotNull(value);
|
||||||
unCache();
|
unCache();
|
||||||
this.value = value;
|
this.value = value;
|
||||||
@ -197,15 +198,15 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
* @param feePerKbRequired The fee required per kilobyte. Note that this is the same as the reference client's -minrelaytxfee * 3
|
* @param feePerKbRequired The fee required per kilobyte. Note that this is the same as the reference client's -minrelaytxfee * 3
|
||||||
* If you want a safe default, use {@link Transaction#REFERENCE_DEFAULT_MIN_TX_FEE}*3
|
* If you want a safe default, use {@link Transaction#REFERENCE_DEFAULT_MIN_TX_FEE}*3
|
||||||
*/
|
*/
|
||||||
public BigInteger getMinNonDustValue(BigInteger feePerKbRequired) {
|
public Coin getMinNonDustValue(Coin feePerKbRequired) {
|
||||||
// A typical output is 33 bytes (pubkey hash + opcodes) and requires an input of 148 bytes to spend so we add
|
// A typical output is 33 bytes (pubkey hash + opcodes) and requires an input of 148 bytes to spend so we add
|
||||||
// that together to find out the total amount of data used to transfer this amount of value. Note that this
|
// that together to find out the total amount of data used to transfer this amount of value. Note that this
|
||||||
// formula is wrong for anything that's not a pay-to-address output, unfortunately, we must follow the reference
|
// formula is wrong for anything that's not a pay-to-address output, unfortunately, we must follow the reference
|
||||||
// clients wrongness in order to ensure we're considered standard. A better formula would either estimate the
|
// clients wrongness in order to ensure we're considered standard. A better formula would either estimate the
|
||||||
// size of data needed to satisfy all different script types, or just hard code 33 below.
|
// size of data needed to satisfy all different script types, or just hard code 33 below.
|
||||||
final BigInteger size = BigInteger.valueOf(this.bitcoinSerialize().length + 148);
|
final long size = this.bitcoinSerialize().length + 148;
|
||||||
BigInteger[] nonDustAndRemainder = feePerKbRequired.multiply(size).divideAndRemainder(BigInteger.valueOf(1000));
|
Coin[] nonDustAndRemainder = feePerKbRequired.multiply(size).divideAndRemainder(Coin.valueOf(1000));
|
||||||
return nonDustAndRemainder[1].equals(BigInteger.ZERO) ? nonDustAndRemainder[0] : nonDustAndRemainder[0].add(BigInteger.ONE);
|
return nonDustAndRemainder[1].equals(Coin.ZERO) ? nonDustAndRemainder[0] : nonDustAndRemainder[0].add(Coin.ONE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -213,8 +214,8 @@ public class TransactionOutput extends ChildMessage implements Serializable {
|
|||||||
* and mined by default miners. For normal pay to address outputs, this is 5460 satoshis, the same as
|
* and mined by default miners. For normal pay to address outputs, this is 5460 satoshis, the same as
|
||||||
* {@link Transaction#MIN_NONDUST_OUTPUT}.
|
* {@link Transaction#MIN_NONDUST_OUTPUT}.
|
||||||
*/
|
*/
|
||||||
public BigInteger getMinNonDustValue() {
|
public Coin getMinNonDustValue() {
|
||||||
return getMinNonDustValue(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(3)));
|
return getMinNonDustValue(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(3)));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +45,7 @@ import static com.google.common.util.concurrent.Uninterruptibles.sleepUninterrup
|
|||||||
* To enable debug logging from the library, run with -Dbitcoinj.logging=true on your command line.
|
* To enable debug logging from the library, run with -Dbitcoinj.logging=true on your command line.
|
||||||
*/
|
*/
|
||||||
public class Utils {
|
public class Utils {
|
||||||
public static final BigInteger NEGATIVE_ONE = BigInteger.valueOf(-1);
|
public static final Coin NEGATIVE_ONE = Coin.valueOf(-1);
|
||||||
private static final MessageDigest digest;
|
private static final MessageDigest digest;
|
||||||
static {
|
static {
|
||||||
try {
|
try {
|
||||||
@ -68,7 +68,7 @@ public class Utils {
|
|||||||
* The term nanocoin is very misleading, though, because there are only 100 million
|
* The term nanocoin is very misleading, though, because there are only 100 million
|
||||||
* of them in a coin (whereas one would expect 1 billion.
|
* of them in a coin (whereas one would expect 1 billion.
|
||||||
*/
|
*/
|
||||||
public static final BigInteger COIN = new BigInteger("100000000", 10);
|
public static final Coin COIN = new Coin("100000000", 10);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* How many "nanocoins" there are in 0.01 BitCoins.
|
* How many "nanocoins" there are in 0.01 BitCoins.
|
||||||
@ -77,19 +77,19 @@ public class Utils {
|
|||||||
* The term nanocoin is very misleading, though, because there are only 100 million
|
* The term nanocoin is very misleading, though, because there are only 100 million
|
||||||
* of them in a coin (whereas one would expect 1 billion).
|
* of them in a coin (whereas one would expect 1 billion).
|
||||||
*/
|
*/
|
||||||
public static final BigInteger CENT = new BigInteger("1000000", 10);
|
public static final Coin CENT = new Coin("1000000", 10);
|
||||||
private static BlockingQueue<Boolean> mockSleepQueue;
|
private static BlockingQueue<Boolean> mockSleepQueue;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convert an amount expressed in the way humans are used to into nanocoins.
|
* Convert an amount expressed in the way humans are used to into nanocoins.
|
||||||
*/
|
*/
|
||||||
public static BigInteger toNanoCoins(int coins, int cents) {
|
public static Coin toNanoCoins(int coins, int cents) {
|
||||||
checkArgument(cents < 100);
|
checkArgument(cents < 100);
|
||||||
checkArgument(cents >= 0);
|
checkArgument(cents >= 0);
|
||||||
checkArgument(coins >= 0);
|
checkArgument(coins >= 0);
|
||||||
checkArgument(coins < NetworkParameters.MAX_MONEY.divide(Utils.COIN).longValue());
|
checkArgument(coins < NetworkParameters.MAX_MONEY.divide(Utils.COIN).longValue());
|
||||||
BigInteger bi = BigInteger.valueOf(coins).multiply(COIN);
|
Coin bi = Coin.valueOf(coins).multiply(COIN);
|
||||||
bi = bi.add(BigInteger.valueOf(cents).multiply(CENT));
|
bi = bi.add(Coin.valueOf(cents).multiply(CENT));
|
||||||
return bi;
|
return bi;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,12 +121,12 @@ public class Utils {
|
|||||||
*
|
*
|
||||||
* @throws ArithmeticException if you try to specify fractional nanocoins, or nanocoins out of range.
|
* @throws ArithmeticException if you try to specify fractional nanocoins, or nanocoins out of range.
|
||||||
*/
|
*/
|
||||||
public static BigInteger toNanoCoins(String coins) {
|
public static Coin toNanoCoins(String coins) {
|
||||||
BigInteger bigint = new BigDecimal(coins).movePointRight(8).toBigIntegerExact();
|
Coin bigint = new Coin(new BigDecimal(coins).movePointRight(8).toBigIntegerExact());
|
||||||
if (bigint.signum() < 0)
|
if (bigint.signum() < 0)
|
||||||
throw new ArithmeticException("Negative coins specified");
|
throw new ArithmeticException("Negative coins specified");
|
||||||
if (bigint.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
if (bigint.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
||||||
throw new ArithmeticException("Amount larger than the total quantity of Bitcoins possible specified.");
|
throw new ArithmeticException("Coin larger than the total quantity of Bitcoins possible specified.");
|
||||||
return bigint;
|
return bigint;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -332,12 +332,12 @@ public class Utils {
|
|||||||
* Returns the given value in nanocoins as a 0.12 type string. More digits after the decimal place will be used
|
* 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.
|
* if necessary, but two will always be present.
|
||||||
*/
|
*/
|
||||||
public static String bitcoinValueToFriendlyString(BigInteger value) {
|
public static String bitcoinValueToFriendlyString(Coin value) {
|
||||||
// TODO: This API is crap. This method should go away when we encapsulate money values.
|
// TODO: This API is crap. This method should go away when we encapsulate money values.
|
||||||
boolean negative = value.signum() < 0;
|
boolean negative = value.signum() < 0;
|
||||||
if (negative)
|
if (negative)
|
||||||
value = value.negate();
|
value = value.negate();
|
||||||
BigDecimal bd = new BigDecimal(value, 8);
|
BigDecimal bd = new BigDecimal(value.toBigInteger(), 8);
|
||||||
String formatted = bd.toPlainString(); // Don't use scientific notation.
|
String formatted = bd.toPlainString(); // Don't use scientific notation.
|
||||||
int decimalPoint = formatted.indexOf(".");
|
int decimalPoint = formatted.indexOf(".");
|
||||||
// Drop unnecessary zeros from the end.
|
// Drop unnecessary zeros from the end.
|
||||||
@ -355,19 +355,19 @@ public class Utils {
|
|||||||
* <p>
|
* <p>
|
||||||
* Returns the given value as a plain string denominated in BTC.
|
* Returns the given value as a plain string denominated in BTC.
|
||||||
* The result is unformatted with no trailing zeroes.
|
* The result is unformatted with no trailing zeroes.
|
||||||
* For instance, an input value of BigInteger.valueOf(150000) nanocoin gives an output string of "0.0015" BTC
|
* For instance, an input value of Coin.valueOf(150000) nanocoin gives an output string of "0.0015" BTC
|
||||||
* </p>
|
* </p>
|
||||||
*
|
*
|
||||||
* @param value The value in nanocoins to convert to a string (denominated in BTC)
|
* @param value The value in nanocoins to convert to a string (denominated in BTC)
|
||||||
* @throws IllegalArgumentException
|
* @throws IllegalArgumentException
|
||||||
* If the input value is null
|
* If the input value is null
|
||||||
*/
|
*/
|
||||||
public static String bitcoinValueToPlainString(BigInteger value) {
|
public static String bitcoinValueToPlainString(Coin value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
throw new IllegalArgumentException("Value cannot be null");
|
throw new IllegalArgumentException("Value cannot be null");
|
||||||
}
|
}
|
||||||
|
|
||||||
BigDecimal valueInBTC = new BigDecimal(value).divide(new BigDecimal(Utils.COIN));
|
BigDecimal valueInBTC = new BigDecimal(value.toBigInteger()).divide(new BigDecimal(Utils.COIN.toBigInteger()));
|
||||||
return valueInBTC.toPlainString();
|
return valueInBTC.toPlainString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1094,8 +1094,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
log.warn("There are now {} risk dropped transactions being kept in memory", riskDropped.size());
|
log.warn("There are now {} risk dropped transactions being kept in memory", riskDropped.size());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BigInteger valueSentToMe = tx.getValueSentToMe(this);
|
Coin valueSentToMe = tx.getValueSentToMe(this);
|
||||||
BigInteger valueSentFromMe = tx.getValueSentFromMe(this);
|
Coin valueSentFromMe = tx.getValueSentFromMe(this);
|
||||||
if (log.isInfoEnabled()) {
|
if (log.isInfoEnabled()) {
|
||||||
log.info(String.format("Received a pending transaction %s that spends %s BTC from our own wallet," +
|
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),
|
" and sends us %s BTC", tx.getHashAsString(), Utils.bitcoinValueToFriendlyString(valueSentFromMe),
|
||||||
@ -1272,14 +1272,14 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
int relativityOffset) throws VerificationException {
|
int relativityOffset) throws VerificationException {
|
||||||
// Runs in a peer thread.
|
// Runs in a peer thread.
|
||||||
checkState(lock.isHeldByCurrentThread());
|
checkState(lock.isHeldByCurrentThread());
|
||||||
BigInteger prevBalance = getBalance();
|
Coin prevBalance = getBalance();
|
||||||
Sha256Hash txHash = tx.getHash();
|
Sha256Hash txHash = tx.getHash();
|
||||||
boolean bestChain = blockType == BlockChain.NewBlockType.BEST_CHAIN;
|
boolean bestChain = blockType == BlockChain.NewBlockType.BEST_CHAIN;
|
||||||
boolean sideChain = blockType == BlockChain.NewBlockType.SIDE_CHAIN;
|
boolean sideChain = blockType == BlockChain.NewBlockType.SIDE_CHAIN;
|
||||||
|
|
||||||
BigInteger valueSentFromMe = tx.getValueSentFromMe(this);
|
Coin valueSentFromMe = tx.getValueSentFromMe(this);
|
||||||
BigInteger valueSentToMe = tx.getValueSentToMe(this);
|
Coin valueSentToMe = tx.getValueSentToMe(this);
|
||||||
BigInteger valueDifference = valueSentToMe.subtract(valueSentFromMe);
|
Coin valueDifference = valueSentToMe.subtract(valueSentFromMe);
|
||||||
|
|
||||||
log.info("Received tx{} for {} BTC: {} [{}] in block {}", sideChain ? " on a side chain" : "",
|
log.info("Received tx{} for {} BTC: {} [{}] in block {}", sideChain ? " on a side chain" : "",
|
||||||
bitcoinValueToFriendlyString(valueDifference), tx.getHashAsString(), relativityOffset,
|
bitcoinValueToFriendlyString(valueDifference), tx.getHashAsString(), relativityOffset,
|
||||||
@ -1364,7 +1364,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
// own spends. If users want to know when a broadcast tx becomes confirmed, they need to use tx confidence
|
// own spends. If users want to know when a broadcast tx becomes confirmed, they need to use tx confidence
|
||||||
// listeners.
|
// listeners.
|
||||||
if (!insideReorg && bestChain) {
|
if (!insideReorg && bestChain) {
|
||||||
BigInteger newBalance = getBalance(); // This is slow.
|
Coin newBalance = getBalance(); // This is slow.
|
||||||
log.info("Balance is now: " + bitcoinValueToFriendlyString(newBalance));
|
log.info("Balance is now: " + bitcoinValueToFriendlyString(newBalance));
|
||||||
if (!wasPending) {
|
if (!wasPending) {
|
||||||
int diff = valueDifference.signum();
|
int diff = valueDifference.signum();
|
||||||
@ -1694,7 +1694,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
if (pending.containsKey(tx.getHash()))
|
if (pending.containsKey(tx.getHash()))
|
||||||
return false;
|
return false;
|
||||||
log.info("commitTx of {}", tx.getHashAsString());
|
log.info("commitTx of {}", tx.getHashAsString());
|
||||||
BigInteger balance = getBalance();
|
Coin balance = getBalance();
|
||||||
tx.setUpdateTime(Utils.now());
|
tx.setUpdateTime(Utils.now());
|
||||||
// Mark the outputs we're spending as spent so we won't try and use them in future creations. This will also
|
// Mark the outputs we're spending as spent so we won't try and use them in future creations. This will also
|
||||||
// move any transactions that are now fully spent to the spent map so we can skip them when creating future
|
// move any transactions that are now fully spent to the spent map so we can skip them when creating future
|
||||||
@ -1708,9 +1708,9 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
addWalletTransaction(Pool.PENDING, tx);
|
addWalletTransaction(Pool.PENDING, tx);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
BigInteger valueSentFromMe = tx.getValueSentFromMe(this);
|
Coin valueSentFromMe = tx.getValueSentFromMe(this);
|
||||||
BigInteger valueSentToMe = tx.getValueSentToMe(this);
|
Coin valueSentToMe = tx.getValueSentToMe(this);
|
||||||
BigInteger newBalance = balance.add(valueSentToMe).subtract(valueSentFromMe);
|
Coin newBalance = balance.add(valueSentToMe).subtract(valueSentFromMe);
|
||||||
if (valueSentToMe.signum() > 0) {
|
if (valueSentToMe.signum() > 0) {
|
||||||
checkBalanceFuturesLocked(null);
|
checkBalanceFuturesLocked(null);
|
||||||
queueOnCoinsReceived(tx, balance, newBalance);
|
queueOnCoinsReceived(tx, balance, newBalance);
|
||||||
@ -2015,7 +2015,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* fees) - the wallet will calculate all that for you and update tx later.</p>
|
* fees) - the wallet will calculate all that for you and update tx later.</p>
|
||||||
*
|
*
|
||||||
* <p>Be careful when adding outputs that you check the min output value
|
* <p>Be careful when adding outputs that you check the min output value
|
||||||
* ({@link TransactionOutput#getMinNonDustValue(BigInteger)}) to avoid the whole transaction being rejected
|
* ({@link TransactionOutput#getMinNonDustValue(Coin)}) to avoid the whole transaction being rejected
|
||||||
* because one output is dust.</p>
|
* because one output is dust.</p>
|
||||||
*
|
*
|
||||||
* <p>If there are already inputs to the transaction, make sure their out point has a connected output,
|
* <p>If there are already inputs to the transaction, make sure their out point has a connected output,
|
||||||
@ -2056,7 +2056,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* <p>You might also consider adding a {@link SendRequest#feePerKb} to set the fee per kb of transaction size
|
* <p>You might also consider adding a {@link SendRequest#feePerKb} to set the fee per kb of transaction size
|
||||||
* (rounded down to the nearest kb) as that is how transactions are sorted when added to a block by miners.</p>
|
* (rounded down to the nearest kb) as that is how transactions are sorted when added to a block by miners.</p>
|
||||||
*/
|
*/
|
||||||
public BigInteger fee = null;
|
public Coin fee = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>A transaction can have a fee attached, which is defined as the difference between the input values
|
* <p>A transaction can have a fee attached, which is defined as the difference between the input values
|
||||||
@ -2072,13 +2072,13 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
*
|
*
|
||||||
* <p>You might also consider using a {@link SendRequest#fee} to set the fee added for the first kb of size.</p>
|
* <p>You might also consider using a {@link SendRequest#fee} to set the fee added for the first kb of size.</p>
|
||||||
*/
|
*/
|
||||||
public BigInteger feePerKb = DEFAULT_FEE_PER_KB;
|
public Coin feePerKb = DEFAULT_FEE_PER_KB;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If you want to modify the default fee for your entire app without having to change each SendRequest you make,
|
* If you want to modify the default fee for your entire app without having to change each SendRequest you make,
|
||||||
* you can do it here. This is primarily useful for unit tests.
|
* you can do it here. This is primarily useful for unit tests.
|
||||||
*/
|
*/
|
||||||
public static BigInteger DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
public static Coin DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Requires that there be enough fee for a default reference client to at least relay the transaction.
|
* <p>Requires that there be enough fee for a default reference client to at least relay the transaction.
|
||||||
@ -2123,7 +2123,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* <p>Be very careful when value is smaller than {@link Transaction#MIN_NONDUST_OUTPUT} as the transaction will
|
* <p>Be very careful when value is smaller than {@link Transaction#MIN_NONDUST_OUTPUT} as the transaction will
|
||||||
* likely be rejected by the network in this case.</p>
|
* likely be rejected by the network in this case.</p>
|
||||||
*/
|
*/
|
||||||
public static SendRequest to(Address destination, BigInteger value) {
|
public static SendRequest to(Address destination, Coin value) {
|
||||||
SendRequest req = new SendRequest();
|
SendRequest req = new SendRequest();
|
||||||
final NetworkParameters parameters = destination.getParameters();
|
final NetworkParameters parameters = destination.getParameters();
|
||||||
checkNotNull(parameters, "Address is for an unknown network");
|
checkNotNull(parameters, "Address is for an unknown network");
|
||||||
@ -2136,11 +2136,11 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* <p>Creates a new SendRequest to the given pubkey for the given value.</p>
|
* <p>Creates a new SendRequest to the given pubkey for the given value.</p>
|
||||||
*
|
*
|
||||||
* <p>Be careful to check the output's value is reasonable using
|
* <p>Be careful to check the output's value is reasonable using
|
||||||
* {@link TransactionOutput#getMinNonDustValue(BigInteger)} afterwards or you risk having the transaction
|
* {@link TransactionOutput#getMinNonDustValue(Coin)} afterwards or you risk having the transaction
|
||||||
* rejected by the network. Note that using {@link SendRequest#to(Address, java.math.BigInteger)} will result
|
* rejected by the network. Note that using {@link SendRequest#to(Address, java.math.Coin)} will result
|
||||||
* in a smaller output, and thus the ability to use a smaller output value without rejection.</p>
|
* in a smaller output, and thus the ability to use a smaller output value without rejection.</p>
|
||||||
*/
|
*/
|
||||||
public static SendRequest to(NetworkParameters params, ECKey destination, BigInteger value) {
|
public static SendRequest to(NetworkParameters params, ECKey destination, Coin value) {
|
||||||
SendRequest req = new SendRequest();
|
SendRequest req = new SendRequest();
|
||||||
req.tx = new Transaction(params);
|
req.tx = new Transaction(params);
|
||||||
req.tx.addOutput(value, destination);
|
req.tx.addOutput(value, destination);
|
||||||
@ -2159,7 +2159,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
final NetworkParameters parameters = destination.getParameters();
|
final NetworkParameters parameters = destination.getParameters();
|
||||||
checkNotNull(parameters, "Address is for an unknown network");
|
checkNotNull(parameters, "Address is for an unknown network");
|
||||||
req.tx = new Transaction(parameters);
|
req.tx = new Transaction(parameters);
|
||||||
req.tx.addOutput(BigInteger.ZERO, destination);
|
req.tx.addOutput(Coin.ZERO, destination);
|
||||||
req.emptyWallet = true;
|
req.emptyWallet = true;
|
||||||
return req;
|
return req;
|
||||||
}
|
}
|
||||||
@ -2170,11 +2170,11 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* {@link Wallet#getChangeAddress()}, so you must have added at least one key.</p>
|
* {@link Wallet#getChangeAddress()}, so you must have added at least one key.</p>
|
||||||
*
|
*
|
||||||
* <p>If you just want to send money quickly, you probably want
|
* <p>If you just want to send money quickly, you probably want
|
||||||
* {@link Wallet#sendCoins(TransactionBroadcaster, Address, java.math.BigInteger)} instead. That will create the sending
|
* {@link Wallet#sendCoins(TransactionBroadcaster, Address, java.math.Coin)} instead. That will create the sending
|
||||||
* transaction, commit to the wallet and broadcast it to the network all in one go. This method is lower level
|
* transaction, commit to the wallet and broadcast it to the network all in one go. This method is lower level
|
||||||
* and lets you see the proposed transaction before anything is done with it.</p>
|
* and lets you see the proposed transaction before anything is done with it.</p>
|
||||||
*
|
*
|
||||||
* <p>This is a helper method that is equivalent to using {@link Wallet.SendRequest#to(Address, java.math.BigInteger)}
|
* <p>This is a helper method that is equivalent to using {@link Wallet.SendRequest#to(Address, java.math.Coin)}
|
||||||
* followed by {@link Wallet#completeTx(Wallet.SendRequest)} and returning the requests transaction object.
|
* followed by {@link Wallet#completeTx(Wallet.SendRequest)} and returning the requests transaction object.
|
||||||
* Note that this means a fee may be automatically added if required, if you want more control over the process,
|
* Note that this means a fee may be automatically added if required, if you want more control over the process,
|
||||||
* just do those two steps yourself.</p>
|
* just do those two steps yourself.</p>
|
||||||
@ -2193,7 +2193,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* coins as spent until commitTx is called on the result.
|
* coins as spent until commitTx is called on the result.
|
||||||
* @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
|
* @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
|
||||||
*/
|
*/
|
||||||
public Transaction createSend(Address address, BigInteger nanocoins) throws InsufficientMoneyException {
|
public Transaction createSend(Address address, Coin nanocoins) throws InsufficientMoneyException {
|
||||||
SendRequest req = SendRequest.to(address, nanocoins);
|
SendRequest req = SendRequest.to(address, nanocoins);
|
||||||
if (params == UnitTestParams.get())
|
if (params == UnitTestParams.get())
|
||||||
req.shuffleOutputs = false;
|
req.shuffleOutputs = false;
|
||||||
@ -2243,7 +2243,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* @return An object containing the transaction that was created, and a future for the broadcast of it.
|
* @return An object containing the transaction that was created, and a future for the broadcast of it.
|
||||||
* @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
|
* @throws InsufficientMoneyException if the request could not be completed due to not enough balance.
|
||||||
*/
|
*/
|
||||||
public SendResult sendCoins(TransactionBroadcaster broadcaster, Address to, BigInteger value) throws InsufficientMoneyException {
|
public SendResult sendCoins(TransactionBroadcaster broadcaster, Address to, Coin value) throws InsufficientMoneyException {
|
||||||
SendRequest request = SendRequest.to(to, value);
|
SendRequest request = SendRequest.to(to, value);
|
||||||
return sendCoins(broadcaster, request);
|
return sendCoins(broadcaster, request);
|
||||||
}
|
}
|
||||||
@ -2335,17 +2335,17 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
try {
|
try {
|
||||||
checkArgument(!req.completed, "Given SendRequest has already been completed.");
|
checkArgument(!req.completed, "Given SendRequest has already been completed.");
|
||||||
// Calculate the amount of value we need to import.
|
// Calculate the amount of value we need to import.
|
||||||
BigInteger value = BigInteger.ZERO;
|
Coin value = Coin.ZERO;
|
||||||
for (TransactionOutput output : req.tx.getOutputs()) {
|
for (TransactionOutput output : req.tx.getOutputs()) {
|
||||||
value = value.add(output.getValue());
|
value = value.add(output.getValue());
|
||||||
}
|
}
|
||||||
BigInteger totalOutput = value;
|
Coin totalOutput = value;
|
||||||
|
|
||||||
log.info("Completing send tx with {} outputs totalling {} satoshis (not including fees)",
|
log.info("Completing send tx with {} outputs totalling {} satoshis (not including fees)",
|
||||||
req.tx.getOutputs().size(), value);
|
req.tx.getOutputs().size(), value);
|
||||||
|
|
||||||
// If any inputs have already been added, we don't need to get their value from wallet
|
// If any inputs have already been added, we don't need to get their value from wallet
|
||||||
BigInteger totalInput = BigInteger.ZERO;
|
Coin totalInput = Coin.ZERO;
|
||||||
for (TransactionInput input : req.tx.getInputs())
|
for (TransactionInput input : req.tx.getInputs())
|
||||||
if (input.getConnectedOutput() != null)
|
if (input.getConnectedOutput() != null)
|
||||||
totalInput = totalInput.add(input.getConnectedOutput().getValue());
|
totalInput = totalInput.add(input.getConnectedOutput().getValue());
|
||||||
@ -2397,8 +2397,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
req.tx.addInput(output);
|
req.tx.addInput(output);
|
||||||
|
|
||||||
if (req.ensureMinRequiredFee && req.emptyWallet) {
|
if (req.ensureMinRequiredFee && req.emptyWallet) {
|
||||||
final BigInteger baseFee = req.fee == null ? BigInteger.ZERO : req.fee;
|
final Coin baseFee = req.fee == null ? Coin.ZERO : req.fee;
|
||||||
final BigInteger feePerKb = req.feePerKb == null ? BigInteger.ZERO : req.feePerKb;
|
final Coin feePerKb = req.feePerKb == null ? Coin.ZERO : req.feePerKb;
|
||||||
Transaction tx = req.tx;
|
Transaction tx = req.tx;
|
||||||
if (!adjustOutputDownwardsForFee(tx, bestCoinSelection, baseFee, feePerKb))
|
if (!adjustOutputDownwardsForFee(tx, bestCoinSelection, baseFee, feePerKb))
|
||||||
throw new CouldNotAdjustDownwards();
|
throw new CouldNotAdjustDownwards();
|
||||||
@ -2411,7 +2411,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
totalOutput = totalOutput.add(bestChangeOutput.getValue());
|
totalOutput = totalOutput.add(bestChangeOutput.getValue());
|
||||||
log.info(" with {} coins change", bitcoinValueToFriendlyString(bestChangeOutput.getValue()));
|
log.info(" with {} coins change", bitcoinValueToFriendlyString(bestChangeOutput.getValue()));
|
||||||
}
|
}
|
||||||
final BigInteger calculatedFee = totalInput.subtract(totalOutput);
|
final Coin calculatedFee = totalInput.subtract(totalOutput);
|
||||||
if (calculatedFee.signum() > 0) {
|
if (calculatedFee.signum() > 0) {
|
||||||
log.info(" with a fee of {}", bitcoinValueToFriendlyString(calculatedFee));
|
log.info(" with a fee of {}", bitcoinValueToFriendlyString(calculatedFee));
|
||||||
}
|
}
|
||||||
@ -2445,12 +2445,12 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Reduce the value of the first output of a transaction to pay the given feePerKb as appropriate for its size. */
|
/** Reduce the value of the first output of a transaction to pay the given feePerKb as appropriate for its size. */
|
||||||
private boolean adjustOutputDownwardsForFee(Transaction tx, CoinSelection coinSelection, BigInteger baseFee, BigInteger feePerKb) {
|
private boolean adjustOutputDownwardsForFee(Transaction tx, CoinSelection coinSelection, Coin baseFee, Coin feePerKb) {
|
||||||
TransactionOutput output = tx.getOutput(0);
|
TransactionOutput output = tx.getOutput(0);
|
||||||
// Check if we need additional fee due to the transaction's size
|
// Check if we need additional fee due to the transaction's size
|
||||||
int size = tx.bitcoinSerialize().length;
|
int size = tx.bitcoinSerialize().length;
|
||||||
size += estimateBytesForSigning(coinSelection);
|
size += estimateBytesForSigning(coinSelection);
|
||||||
BigInteger fee = baseFee.add(BigInteger.valueOf((size / 1000) + 1).multiply(feePerKb));
|
Coin fee = baseFee.add(Coin.valueOf((size / 1000) + 1).multiply(feePerKb));
|
||||||
output.setValue(output.getValue().subtract(fee));
|
output.setValue(output.getValue().subtract(fee));
|
||||||
// Check if we need additional fee due to the output's value
|
// 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(Utils.CENT) < 0 && fee.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0)
|
||||||
@ -2538,21 +2538,21 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* Returns the AVAILABLE balance of this wallet. See {@link BalanceType#AVAILABLE} for details on what this
|
* Returns the AVAILABLE balance of this wallet. See {@link BalanceType#AVAILABLE} for details on what this
|
||||||
* means.
|
* means.
|
||||||
*/
|
*/
|
||||||
public BigInteger getBalance() {
|
public Coin getBalance() {
|
||||||
return getBalance(BalanceType.AVAILABLE);
|
return getBalance(BalanceType.AVAILABLE);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the balance of this wallet as calculated by the provided balanceType.
|
* Returns the balance of this wallet as calculated by the provided balanceType.
|
||||||
*/
|
*/
|
||||||
public BigInteger getBalance(BalanceType balanceType) {
|
public Coin getBalance(BalanceType balanceType) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
if (balanceType == BalanceType.AVAILABLE) {
|
if (balanceType == BalanceType.AVAILABLE) {
|
||||||
return getBalance(coinSelector);
|
return getBalance(coinSelector);
|
||||||
} else if (balanceType == BalanceType.ESTIMATED) {
|
} else if (balanceType == BalanceType.ESTIMATED) {
|
||||||
LinkedList<TransactionOutput> all = calculateAllSpendCandidates(false);
|
LinkedList<TransactionOutput> all = calculateAllSpendCandidates(false);
|
||||||
BigInteger value = BigInteger.ZERO;
|
Coin value = Coin.ZERO;
|
||||||
for (TransactionOutput out : all) value = value.add(out.getValue());
|
for (TransactionOutput out : all) value = value.add(out.getValue());
|
||||||
return value;
|
return value;
|
||||||
} else {
|
} else {
|
||||||
@ -2567,7 +2567,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* Returns the balance that would be considered spendable by the given coin selector. Just asks it to select
|
* Returns the balance that would be considered spendable by the given coin selector. Just asks it to select
|
||||||
* as many coins as possible and returns the total.
|
* as many coins as possible and returns the total.
|
||||||
*/
|
*/
|
||||||
public BigInteger getBalance(CoinSelector selector) {
|
public Coin getBalance(CoinSelector selector) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
checkNotNull(selector);
|
checkNotNull(selector);
|
||||||
@ -2580,7 +2580,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the available balance, including any unspent balance at watched addresses */
|
/** Returns the available balance, including any unspent balance at watched addresses */
|
||||||
public BigInteger getWatchedBalance() {
|
public Coin getWatchedBalance() {
|
||||||
return getWatchedBalance(coinSelector);
|
return getWatchedBalance(coinSelector);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2588,7 +2588,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* Returns the balance that would be considered spendable by the given coin selector, including
|
* Returns the balance that would be considered spendable by the given coin selector, including
|
||||||
* any unspent balance at watched addresses.
|
* any unspent balance at watched addresses.
|
||||||
*/
|
*/
|
||||||
public BigInteger getWatchedBalance(CoinSelector selector) {
|
public Coin getWatchedBalance(CoinSelector selector) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
checkNotNull(selector);
|
checkNotNull(selector);
|
||||||
@ -2619,8 +2619,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
BigInteger estimatedBalance = getBalance(BalanceType.ESTIMATED);
|
Coin estimatedBalance = getBalance(BalanceType.ESTIMATED);
|
||||||
BigInteger availableBalance = getBalance(BalanceType.AVAILABLE);
|
Coin availableBalance = getBalance(BalanceType.AVAILABLE);
|
||||||
builder.append(String.format("Wallet containing %s BTC (available: %s BTC) in:%n",
|
builder.append(String.format("Wallet containing %s BTC (available: %s BTC) in:%n",
|
||||||
bitcoinValueToPlainString(estimatedBalance), bitcoinValueToPlainString(availableBalance)));
|
bitcoinValueToPlainString(estimatedBalance), bitcoinValueToPlainString(availableBalance)));
|
||||||
builder.append(String.format(" %d pending transactions%n", pending.size()));
|
builder.append(String.format(" %d pending transactions%n", pending.size()));
|
||||||
@ -2861,7 +2861,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
notifyNewBestBlock(block);
|
notifyNewBestBlock(block);
|
||||||
}
|
}
|
||||||
checkState(isConsistent());
|
checkState(isConsistent());
|
||||||
final BigInteger balance = getBalance();
|
final Coin balance = getBalance();
|
||||||
log.info("post-reorg balance is {}", Utils.bitcoinValueToFriendlyString(balance));
|
log.info("post-reorg balance is {}", Utils.bitcoinValueToFriendlyString(balance));
|
||||||
// Inform event listeners that a re-org took place.
|
// Inform event listeners that a re-org took place.
|
||||||
queueOnReorganize();
|
queueOnReorganize();
|
||||||
@ -3307,8 +3307,8 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static class BalanceFutureRequest {
|
private static class BalanceFutureRequest {
|
||||||
public SettableFuture<BigInteger> future;
|
public SettableFuture<Coin> future;
|
||||||
public BigInteger value;
|
public Coin value;
|
||||||
public BalanceType type;
|
public BalanceType type;
|
||||||
}
|
}
|
||||||
@GuardedBy("lock") private List<BalanceFutureRequest> balanceFutureRequests = Lists.newLinkedList();
|
@GuardedBy("lock") private List<BalanceFutureRequest> balanceFutureRequests = Lists.newLinkedList();
|
||||||
@ -3327,11 +3327,11 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
* you can use {@link com.google.bitcoin.utils.Threading#waitForUserCode()} to block until the future had a
|
* you can use {@link com.google.bitcoin.utils.Threading#waitForUserCode()} to block until the future had a
|
||||||
* chance to be updated.</p>
|
* chance to be updated.</p>
|
||||||
*/
|
*/
|
||||||
public ListenableFuture<BigInteger> getBalanceFuture(final BigInteger value, final BalanceType type) {
|
public ListenableFuture<Coin> getBalanceFuture(final Coin value, final BalanceType type) {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
final SettableFuture<BigInteger> future = SettableFuture.create();
|
final SettableFuture<Coin> future = SettableFuture.create();
|
||||||
final BigInteger current = getBalance(type);
|
final Coin current = getBalance(type);
|
||||||
if (current.compareTo(value) >= 0) {
|
if (current.compareTo(value) >= 0) {
|
||||||
// Already have enough.
|
// Already have enough.
|
||||||
future.set(current);
|
future.set(current);
|
||||||
@ -3352,13 +3352,13 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Runs any balance futures in the user code thread.
|
// Runs any balance futures in the user code thread.
|
||||||
private void checkBalanceFuturesLocked(@Nullable BigInteger avail) {
|
private void checkBalanceFuturesLocked(@Nullable Coin avail) {
|
||||||
checkState(lock.isHeldByCurrentThread());
|
checkState(lock.isHeldByCurrentThread());
|
||||||
BigInteger estimated = null;
|
Coin estimated = null;
|
||||||
final ListIterator<BalanceFutureRequest> it = balanceFutureRequests.listIterator();
|
final ListIterator<BalanceFutureRequest> it = balanceFutureRequests.listIterator();
|
||||||
while (it.hasNext()) {
|
while (it.hasNext()) {
|
||||||
final BalanceFutureRequest req = it.next();
|
final BalanceFutureRequest req = it.next();
|
||||||
BigInteger val = null;
|
Coin val = null;
|
||||||
if (req.type == BalanceType.AVAILABLE) {
|
if (req.type == BalanceType.AVAILABLE) {
|
||||||
if (avail == null) avail = getBalance(BalanceType.AVAILABLE);
|
if (avail == null) avail = getBalance(BalanceType.AVAILABLE);
|
||||||
if (avail.compareTo(req.value) < 0) continue;
|
if (avail.compareTo(req.value) < 0) continue;
|
||||||
@ -3370,7 +3370,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
}
|
}
|
||||||
// Found one that's finished.
|
// Found one that's finished.
|
||||||
it.remove();
|
it.remove();
|
||||||
final BigInteger v = checkNotNull(val);
|
final Coin v = checkNotNull(val);
|
||||||
// Don't run any user-provided future listeners with our lock held.
|
// Don't run any user-provided future listeners with our lock held.
|
||||||
Threading.USER_THREAD.execute(new Runnable() {
|
Threading.USER_THREAD.execute(new Runnable() {
|
||||||
@Override public void run() {
|
@Override public void run() {
|
||||||
@ -3483,7 +3483,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void queueOnCoinsReceived(final Transaction tx, final BigInteger balance, final BigInteger newBalance) {
|
private void queueOnCoinsReceived(final Transaction tx, final Coin balance, final Coin newBalance) {
|
||||||
checkState(lock.isHeldByCurrentThread());
|
checkState(lock.isHeldByCurrentThread());
|
||||||
for (final ListenerRegistration<WalletEventListener> registration : eventListeners) {
|
for (final ListenerRegistration<WalletEventListener> registration : eventListeners) {
|
||||||
registration.executor.execute(new Runnable() {
|
registration.executor.execute(new Runnable() {
|
||||||
@ -3495,7 +3495,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void queueOnCoinsSent(final Transaction tx, final BigInteger prevBalance, final BigInteger newBalance) {
|
private void queueOnCoinsSent(final Transaction tx, final Coin prevBalance, final Coin newBalance) {
|
||||||
checkState(lock.isHeldByCurrentThread());
|
checkState(lock.isHeldByCurrentThread());
|
||||||
for (final ListenerRegistration<WalletEventListener> registration : eventListeners) {
|
for (final ListenerRegistration<WalletEventListener> registration : eventListeners) {
|
||||||
registration.executor.execute(new Runnable() {
|
registration.executor.execute(new Runnable() {
|
||||||
@ -3540,7 +3540,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
private CoinSelection bestCoinSelection;
|
private CoinSelection bestCoinSelection;
|
||||||
private TransactionOutput bestChangeOutput;
|
private TransactionOutput bestChangeOutput;
|
||||||
|
|
||||||
public FeeCalculation(SendRequest req, BigInteger value, List<TransactionInput> originalInputs,
|
public FeeCalculation(SendRequest req, Coin value, List<TransactionInput> originalInputs,
|
||||||
boolean needAtLeastReferenceFee, LinkedList<TransactionOutput> candidates) throws InsufficientMoneyException {
|
boolean needAtLeastReferenceFee, LinkedList<TransactionOutput> candidates) throws InsufficientMoneyException {
|
||||||
checkState(lock.isHeldByCurrentThread());
|
checkState(lock.isHeldByCurrentThread());
|
||||||
// There are 3 possibilities for what adding change might do:
|
// There are 3 possibilities for what adding change might do:
|
||||||
@ -3550,7 +3550,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
// If we get either of the last 2, we keep note of what the inputs looked like at the time and try to
|
// If we get either of the last 2, we keep note of what the inputs looked like at the time and try to
|
||||||
// add inputs as we go up the list (keeping track of minimum inputs for each category). At the end, we pick
|
// add inputs as we go up the list (keeping track of minimum inputs for each category). At the end, we pick
|
||||||
// the best input set as the one which generates the lowest total fee.
|
// the best input set as the one which generates the lowest total fee.
|
||||||
BigInteger additionalValueForNextCategory = null;
|
Coin additionalValueForNextCategory = null;
|
||||||
CoinSelection selection3 = null;
|
CoinSelection selection3 = null;
|
||||||
CoinSelection selection2 = null;
|
CoinSelection selection2 = null;
|
||||||
TransactionOutput selection2Change = null;
|
TransactionOutput selection2Change = null;
|
||||||
@ -3559,14 +3559,14 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
// We keep track of the last size of the transaction we calculated but only if the act of adding inputs and
|
// We keep track of the last size of the transaction we calculated but only if the act of adding inputs and
|
||||||
// change resulted in the size crossing a 1000 byte boundary. Otherwise it stays at zero.
|
// change resulted in the size crossing a 1000 byte boundary. Otherwise it stays at zero.
|
||||||
int lastCalculatedSize = 0;
|
int lastCalculatedSize = 0;
|
||||||
BigInteger valueNeeded, valueMissing = null;
|
Coin valueNeeded, valueMissing = null;
|
||||||
while (true) {
|
while (true) {
|
||||||
resetTxInputs(req, originalInputs);
|
resetTxInputs(req, originalInputs);
|
||||||
|
|
||||||
BigInteger fees = req.fee == null ? BigInteger.ZERO : req.fee;
|
Coin fees = req.fee == null ? Coin.ZERO : req.fee;
|
||||||
if (lastCalculatedSize > 0) {
|
if (lastCalculatedSize > 0) {
|
||||||
// If the size is exactly 1000 bytes then we'll over-pay, but this should be rare.
|
// If the size is exactly 1000 bytes then we'll over-pay, but this should be rare.
|
||||||
fees = fees.add(BigInteger.valueOf((lastCalculatedSize / 1000) + 1).multiply(req.feePerKb));
|
fees = fees.add(Coin.valueOf((lastCalculatedSize / 1000) + 1).multiply(req.feePerKb));
|
||||||
} else {
|
} else {
|
||||||
fees = fees.add(req.feePerKb); // First time around the loop.
|
fees = fees.add(req.feePerKb); // First time around the loop.
|
||||||
}
|
}
|
||||||
@ -3576,7 +3576,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
valueNeeded = value.add(fees);
|
valueNeeded = value.add(fees);
|
||||||
if (additionalValueForNextCategory != null)
|
if (additionalValueForNextCategory != null)
|
||||||
valueNeeded = valueNeeded.add(additionalValueForNextCategory);
|
valueNeeded = valueNeeded.add(additionalValueForNextCategory);
|
||||||
BigInteger additionalValueSelected = additionalValueForNextCategory;
|
Coin additionalValueSelected = additionalValueForNextCategory;
|
||||||
|
|
||||||
// Of the coins we could spend, pick some that we actually will spend.
|
// Of the coins we could spend, pick some that we actually will spend.
|
||||||
CoinSelector selector = req.coinSelector == null ? coinSelector : req.coinSelector;
|
CoinSelector selector = req.coinSelector == null ? coinSelector : req.coinSelector;
|
||||||
@ -3598,12 +3598,12 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
boolean eitherCategory2Or3 = false;
|
boolean eitherCategory2Or3 = false;
|
||||||
boolean isCategory3 = false;
|
boolean isCategory3 = false;
|
||||||
|
|
||||||
BigInteger change = selection.valueGathered.subtract(valueNeeded);
|
Coin change = selection.valueGathered.subtract(valueNeeded);
|
||||||
if (additionalValueSelected != null)
|
if (additionalValueSelected != null)
|
||||||
change = change.add(additionalValueSelected);
|
change = change.add(additionalValueSelected);
|
||||||
|
|
||||||
// If change is < 0.01 BTC, we will need to have at least minfee to be accepted by the network
|
// If change is < 0.01 BTC, we will need to have at least minfee to be accepted by the network
|
||||||
if (req.ensureMinRequiredFee && !change.equals(BigInteger.ZERO) &&
|
if (req.ensureMinRequiredFee && !change.equals(Coin.ZERO) &&
|
||||||
change.compareTo(Utils.CENT) < 0 && fees.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0) {
|
change.compareTo(Utils.CENT) < 0 && fees.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0) {
|
||||||
// This solution may fit into category 2, but it may also be category 3, we'll check that later
|
// This solution may fit into category 2, but it may also be category 3, we'll check that later
|
||||||
eitherCategory2Or3 = true;
|
eitherCategory2Or3 = true;
|
||||||
@ -3627,7 +3627,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
// This solution definitely fits in category 3
|
// This solution definitely fits in category 3
|
||||||
isCategory3 = true;
|
isCategory3 = true;
|
||||||
additionalValueForNextCategory = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(
|
additionalValueForNextCategory = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(
|
||||||
Transaction.MIN_NONDUST_OUTPUT.add(BigInteger.ONE));
|
Transaction.MIN_NONDUST_OUTPUT.add(Coin.ONE));
|
||||||
} else {
|
} else {
|
||||||
size += changeOutput.bitcoinSerialize().length + VarInt.sizeOf(req.tx.getOutputs().size()) - VarInt.sizeOf(req.tx.getOutputs().size() - 1);
|
size += changeOutput.bitcoinSerialize().length + VarInt.sizeOf(req.tx.getOutputs().size()) - VarInt.sizeOf(req.tx.getOutputs().size() - 1);
|
||||||
// This solution is either category 1 or 2
|
// This solution is either category 1 or 2
|
||||||
@ -3638,7 +3638,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
if (eitherCategory2Or3) {
|
if (eitherCategory2Or3) {
|
||||||
// This solution definitely fits in category 3 (we threw away change because it was smaller than MIN_TX_FEE)
|
// This solution definitely fits in category 3 (we threw away change because it was smaller than MIN_TX_FEE)
|
||||||
isCategory3 = true;
|
isCategory3 = true;
|
||||||
additionalValueForNextCategory = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE);
|
additionalValueForNextCategory = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3694,7 +3694,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
throw new InsufficientMoneyException(valueMissing);
|
throw new InsufficientMoneyException(valueMissing);
|
||||||
}
|
}
|
||||||
|
|
||||||
BigInteger lowestFee = null;
|
Coin lowestFee = null;
|
||||||
bestCoinSelection = null;
|
bestCoinSelection = null;
|
||||||
bestChangeOutput = null;
|
bestChangeOutput = null;
|
||||||
if (selection1 != null) {
|
if (selection1 != null) {
|
||||||
@ -3707,7 +3707,7 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (selection2 != null) {
|
if (selection2 != null) {
|
||||||
BigInteger fee = selection2.valueGathered.subtract(checkNotNull(selection2Change).getValue());
|
Coin fee = selection2.valueGathered.subtract(checkNotNull(selection2Change).getValue());
|
||||||
if (lowestFee == null || fee.compareTo(lowestFee) < 0) {
|
if (lowestFee == null || fee.compareTo(lowestFee) < 0) {
|
||||||
lowestFee = fee;
|
lowestFee = fee;
|
||||||
bestCoinSelection = selection2;
|
bestCoinSelection = selection2;
|
||||||
@ -3896,14 +3896,14 @@ public class Wallet extends BaseTaggableObject implements Serializable, BlockCha
|
|||||||
// bug that was fixed in 0.10, thus, making a re-key transaction depend on those would cause it to
|
// bug that was fixed in 0.10, thus, making a re-key transaction depend on those would cause it to
|
||||||
// never confirm at all.
|
// never confirm at all.
|
||||||
CoinSelector selector = new KeyTimeCoinSelector(this, keyRotationTimestamp, true);
|
CoinSelector selector = new KeyTimeCoinSelector(this, keyRotationTimestamp, true);
|
||||||
CoinSelection toMove = selector.select(BigInteger.ZERO, calculateAllSpendCandidates(true));
|
CoinSelection toMove = selector.select(Coin.ZERO, calculateAllSpendCandidates(true));
|
||||||
if (toMove.valueGathered.equals(BigInteger.ZERO)) return null; // Nothing to do.
|
if (toMove.valueGathered.equals(Coin.ZERO)) return null; // Nothing to do.
|
||||||
rekeyTx = new Transaction(params);
|
rekeyTx = new Transaction(params);
|
||||||
for (TransactionOutput output : toMove.gathered) {
|
for (TransactionOutput output : toMove.gathered) {
|
||||||
rekeyTx.addInput(output);
|
rekeyTx.addInput(output);
|
||||||
}
|
}
|
||||||
rekeyTx.addOutput(toMove.valueGathered, safeKey);
|
rekeyTx.addOutput(toMove.valueGathered, safeKey);
|
||||||
if (!adjustOutputDownwardsForFee(rekeyTx, toMove, BigInteger.ZERO, Transaction.REFERENCE_DEFAULT_MIN_TX_FEE)) {
|
if (!adjustOutputDownwardsForFee(rekeyTx, toMove, Coin.ZERO, Transaction.REFERENCE_DEFAULT_MIN_TX_FEE)) {
|
||||||
log.error("Failed to adjust rekey tx for fees.");
|
log.error("Failed to adjust rekey tx for fees.");
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ package com.google.bitcoin.core;
|
|||||||
import com.google.bitcoin.script.Script;
|
import com.google.bitcoin.script.Script;
|
||||||
import com.google.bitcoin.wallet.KeyChainEventListener;
|
import com.google.bitcoin.wallet.KeyChainEventListener;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -40,7 +39,7 @@ public interface WalletEventListener extends KeyChainEventListener {
|
|||||||
* @param prevBalance Balance before the coins were received.
|
* @param prevBalance Balance before the coins were received.
|
||||||
* @param newBalance Current balance of the wallet. This is the 'estimated' balance.
|
* @param newBalance Current balance of the wallet. This is the 'estimated' balance.
|
||||||
*/
|
*/
|
||||||
void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance);
|
void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is called when a transaction is seen that sends coins <b>from</b> this wallet, either
|
* This is called when a transaction is seen that sends coins <b>from</b> this wallet, either
|
||||||
@ -58,7 +57,7 @@ public interface WalletEventListener extends KeyChainEventListener {
|
|||||||
* @param prevBalance The wallets balance before this transaction was seen.
|
* @param prevBalance The wallets balance before this transaction was seen.
|
||||||
* @param newBalance The wallets balance after this transaction was seen. This is the 'estimated' balance.
|
* @param newBalance The wallets balance after this transaction was seen. This is the 'estimated' balance.
|
||||||
*/
|
*/
|
||||||
void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance);
|
void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance);
|
||||||
|
|
||||||
// TODO: Finish onReorganize to be more useful.
|
// TODO: Finish onReorganize to be more useful.
|
||||||
/**
|
/**
|
||||||
|
@ -4,8 +4,6 @@ import com.google.bitcoin.core.*;
|
|||||||
import com.google.bitcoin.protocols.channels.PaymentChannelCloseException;
|
import com.google.bitcoin.protocols.channels.PaymentChannelCloseException;
|
||||||
import com.google.bitcoin.protocols.channels.ServerConnectionEventHandler;
|
import com.google.bitcoin.protocols.channels.ServerConnectionEventHandler;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An event listener that relays events to a native C++ object. A pointer to that object is stored in
|
* An event listener that relays events to a native C++ object. A pointer to that object is stored in
|
||||||
* this class using JNI on the native side, thus several instances of this can point to different actual
|
* this class using JNI on the native side, thus several instances of this can point to different actual
|
||||||
@ -18,7 +16,7 @@ public class NativePaymentChannelServerConnectionEventHandler extends ServerConn
|
|||||||
public native void channelOpen(Sha256Hash channelId);
|
public native void channelOpen(Sha256Hash channelId);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public native void paymentIncrease(BigInteger by, BigInteger to);
|
public native void paymentIncrease(Coin by, Coin to);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public native void channelClosed(PaymentChannelCloseException.CloseReason reason);
|
public native void channelClosed(PaymentChannelCloseException.CloseReason reason);
|
||||||
|
@ -16,13 +16,13 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.jni;
|
package com.google.bitcoin.jni;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.ECKey;
|
import com.google.bitcoin.core.ECKey;
|
||||||
import com.google.bitcoin.core.Transaction;
|
import com.google.bitcoin.core.Transaction;
|
||||||
import com.google.bitcoin.core.Wallet;
|
import com.google.bitcoin.core.Wallet;
|
||||||
import com.google.bitcoin.core.WalletEventListener;
|
import com.google.bitcoin.core.WalletEventListener;
|
||||||
import com.google.bitcoin.script.Script;
|
import com.google.bitcoin.script.Script;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -34,10 +34,10 @@ public class NativeWalletEventListener implements WalletEventListener {
|
|||||||
public long ptr;
|
public long ptr;
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public native void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance);
|
public native void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public native void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance);
|
public native void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance);
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public native void onReorganize(Wallet wallet);
|
public native void onReorganize(Wallet wallet);
|
||||||
|
@ -16,11 +16,11 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.protocols.channels;
|
package com.google.bitcoin.protocols.channels;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.InsufficientMoneyException;
|
import com.google.bitcoin.core.InsufficientMoneyException;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import org.bitcoin.paymentchannel.Protos;
|
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import org.bitcoin.paymentchannel.Protos;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A class implementing this interface supports the basic operations of a payment channel. An implementation is provided
|
* A class implementing this interface supports the basic operations of a payment channel. An implementation is provided
|
||||||
@ -80,7 +80,7 @@ public interface IPaymentChannelClient {
|
|||||||
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
||||||
* @return a future that completes when the server acknowledges receipt and acceptance of the payment.
|
* @return a future that completes when the server acknowledges receipt and acceptance of the payment.
|
||||||
*/
|
*/
|
||||||
ListenableFuture<BigInteger> incrementPayment(BigInteger size) throws ValueOutOfRangeException, IllegalStateException;
|
ListenableFuture<Coin> incrementPayment(Coin size) throws ValueOutOfRangeException, IllegalStateException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Implements the connection between this client and the server, providing an interface which allows messages to be
|
* Implements the connection between this client and the server, providing an interface which allows messages to be
|
||||||
@ -118,7 +118,7 @@ public interface IPaymentChannelClient {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Indicates the channel has been successfully opened and
|
* <p>Indicates the channel has been successfully opened and
|
||||||
* {@link com.google.bitcoin.protocols.channels.PaymentChannelClient#incrementPayment(java.math.BigInteger)}
|
* {@link com.google.bitcoin.protocols.channels.PaymentChannelClient#incrementPayment(java.math.Coin)}
|
||||||
* may be called at will.</p>
|
* may be called at will.</p>
|
||||||
*
|
*
|
||||||
* <p>Called while holding a lock on the {@link com.google.bitcoin.protocols.channels.PaymentChannelClient}
|
* <p>Called while holding a lock on the {@link com.google.bitcoin.protocols.channels.PaymentChannelClient}
|
||||||
|
@ -29,7 +29,6 @@ import org.bitcoin.paymentchannel.Protos;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -85,14 +84,14 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
|||||||
|
|
||||||
// Information used during channel initialization to send to the server or check what the server sends to us
|
// Information used during channel initialization to send to the server or check what the server sends to us
|
||||||
private final ECKey myKey;
|
private final ECKey myKey;
|
||||||
private final BigInteger maxValue;
|
private final Coin maxValue;
|
||||||
|
|
||||||
private BigInteger missing;
|
private Coin missing;
|
||||||
|
|
||||||
@GuardedBy("lock") private long minPayment;
|
@GuardedBy("lock") private long minPayment;
|
||||||
|
|
||||||
@GuardedBy("lock") SettableFuture<BigInteger> increasePaymentFuture;
|
@GuardedBy("lock") SettableFuture<Coin> increasePaymentFuture;
|
||||||
@GuardedBy("lock") BigInteger lastPaymentActualAmount;
|
@GuardedBy("lock") Coin lastPaymentActualAmount;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>The maximum amount of time for which we will accept the server locking up our funds for the multisig
|
* <p>The maximum amount of time for which we will accept the server locking up our funds for the multisig
|
||||||
@ -122,7 +121,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
|||||||
* @param conn A callback listener which represents the connection to the server (forwards messages we generate to
|
* @param conn A callback listener which represents the connection to the server (forwards messages we generate to
|
||||||
* the server)
|
* the server)
|
||||||
*/
|
*/
|
||||||
public PaymentChannelClient(Wallet wallet, ECKey myKey, BigInteger maxValue, Sha256Hash serverId, ClientConnection conn) {
|
public PaymentChannelClient(Wallet wallet, ECKey myKey, Coin maxValue, Sha256Hash serverId, ClientConnection conn) {
|
||||||
this.wallet = checkNotNull(wallet);
|
this.wallet = checkNotNull(wallet);
|
||||||
this.myKey = checkNotNull(myKey);
|
this.myKey = checkNotNull(myKey);
|
||||||
this.maxValue = checkNotNull(maxValue);
|
this.maxValue = checkNotNull(maxValue);
|
||||||
@ -136,13 +135,13 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
|||||||
* <p>When InsufficientMoneyException is thrown due to the server requesting too much value, an instance of
|
* <p>When InsufficientMoneyException is thrown due to the server requesting too much value, an instance of
|
||||||
* PaymentChannelClient needs access to how many satoshis are missing.</p>
|
* PaymentChannelClient needs access to how many satoshis are missing.</p>
|
||||||
*/
|
*/
|
||||||
public BigInteger getMissing() {
|
public Coin getMissing() {
|
||||||
return missing;
|
return missing;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@GuardedBy("lock")
|
@GuardedBy("lock")
|
||||||
private CloseReason receiveInitiate(Protos.Initiate initiate, BigInteger contractValue, Protos.Error.Builder errorBuilder) throws VerificationException, InsufficientMoneyException {
|
private CloseReason receiveInitiate(Protos.Initiate initiate, Coin contractValue, Protos.Error.Builder errorBuilder) throws VerificationException, InsufficientMoneyException {
|
||||||
log.info("Got INITIATE message:\n{}", initiate.toString());
|
log.info("Got INITIATE message:\n{}", initiate.toString());
|
||||||
|
|
||||||
checkState(initiate.getExpireTimeSecs() > 0 && initiate.getMinAcceptedChannelSize() >= 0);
|
checkState(initiate.getExpireTimeSecs() > 0 && initiate.getMinAcceptedChannelSize() >= 0);
|
||||||
@ -156,7 +155,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
|||||||
return CloseReason.TIME_WINDOW_TOO_LARGE;
|
return CloseReason.TIME_WINDOW_TOO_LARGE;
|
||||||
}
|
}
|
||||||
|
|
||||||
BigInteger minChannelSize = BigInteger.valueOf(initiate.getMinAcceptedChannelSize());
|
Coin minChannelSize = Coin.valueOf(initiate.getMinAcceptedChannelSize());
|
||||||
if (contractValue.compareTo(minChannelSize) < 0) {
|
if (contractValue.compareTo(minChannelSize) < 0) {
|
||||||
log.error("Server requested too much value");
|
log.error("Server requested too much value");
|
||||||
errorBuilder.setCode(Protos.Error.ErrorCode.CHANNEL_VALUE_TOO_LARGE);
|
errorBuilder.setCode(Protos.Error.ErrorCode.CHANNEL_VALUE_TOO_LARGE);
|
||||||
@ -171,7 +170,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
|||||||
log.error("Server requested a min payment of {} but we expected {}", initiate.getMinPayment(), MIN_PAYMENT);
|
log.error("Server requested a min payment of {} but we expected {}", initiate.getMinPayment(), MIN_PAYMENT);
|
||||||
errorBuilder.setCode(Protos.Error.ErrorCode.MIN_PAYMENT_TOO_LARGE);
|
errorBuilder.setCode(Protos.Error.ErrorCode.MIN_PAYMENT_TOO_LARGE);
|
||||||
errorBuilder.setExpectedValue(MIN_PAYMENT);
|
errorBuilder.setExpectedValue(MIN_PAYMENT);
|
||||||
missing = BigInteger.valueOf(initiate.getMinPayment() - MIN_PAYMENT);
|
missing = Coin.valueOf(initiate.getMinPayment() - MIN_PAYMENT);
|
||||||
return CloseReason.SERVER_REQUESTED_TOO_MUCH_VALUE;
|
return CloseReason.SERVER_REQUESTED_TOO_MUCH_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -218,7 +217,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
|||||||
try {
|
try {
|
||||||
// Make an initial payment of the dust limit, and put it into the message as well. The size of the
|
// Make an initial payment of the dust limit, and put it into the message as well. The size of the
|
||||||
// server-requested dust limit was already sanity checked by this point.
|
// server-requested dust limit was already sanity checked by this point.
|
||||||
PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(BigInteger.valueOf(minPayment));
|
PaymentChannelClientState.IncrementedPayment payment = state().incrementPaymentBy(Coin.valueOf(minPayment));
|
||||||
Protos.UpdatePayment.Builder initialMsg = contractMsg.getInitialPaymentBuilder();
|
Protos.UpdatePayment.Builder initialMsg = contractMsg.getInitialPaymentBuilder();
|
||||||
initialMsg.setSignature(ByteString.copyFrom(payment.signature.encodeToBitcoin()));
|
initialMsg.setSignature(ByteString.copyFrom(payment.signature.encodeToBitcoin()));
|
||||||
initialMsg.setClientChangeValue(state.getValueRefunded().longValue());
|
initialMsg.setClientChangeValue(state.getValueRefunded().longValue());
|
||||||
@ -470,7 +469,7 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
|||||||
* @return a future that completes when the server acknowledges receipt and acceptance of the payment.
|
* @return a future that completes when the server acknowledges receipt and acceptance of the payment.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public ListenableFuture<BigInteger> incrementPayment(BigInteger size) throws ValueOutOfRangeException, IllegalStateException {
|
public ListenableFuture<Coin> incrementPayment(Coin size) throws ValueOutOfRangeException, IllegalStateException {
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN)
|
if (state() == null || !connectionOpen || step != InitStep.CHANNEL_OPEN)
|
||||||
@ -505,8 +504,8 @@ public class PaymentChannelClient implements IPaymentChannelClient {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void receivePaymentAck() {
|
private void receivePaymentAck() {
|
||||||
SettableFuture<BigInteger> future;
|
SettableFuture<Coin> future;
|
||||||
BigInteger value;
|
Coin value;
|
||||||
|
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.protocols.channels;
|
package com.google.bitcoin.protocols.channels;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.ECKey;
|
import com.google.bitcoin.core.ECKey;
|
||||||
import com.google.bitcoin.core.InsufficientMoneyException;
|
import com.google.bitcoin.core.InsufficientMoneyException;
|
||||||
import com.google.bitcoin.core.Sha256Hash;
|
import com.google.bitcoin.core.Sha256Hash;
|
||||||
@ -24,10 +25,10 @@ import com.google.bitcoin.net.NioClient;
|
|||||||
import com.google.bitcoin.net.ProtobufParser;
|
import com.google.bitcoin.net.ProtobufParser;
|
||||||
import com.google.common.util.concurrent.ListenableFuture;
|
import com.google.common.util.concurrent.ListenableFuture;
|
||||||
import com.google.common.util.concurrent.SettableFuture;
|
import com.google.common.util.concurrent.SettableFuture;
|
||||||
|
|
||||||
import org.bitcoin.paymentchannel.Protos;
|
import org.bitcoin.paymentchannel.Protos;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -60,7 +61,7 @@ public class PaymentChannelClientConnection {
|
|||||||
* @throws ValueOutOfRangeException if the balance of wallet is lower than maxValue.
|
* @throws ValueOutOfRangeException if the balance of wallet is lower than maxValue.
|
||||||
*/
|
*/
|
||||||
public PaymentChannelClientConnection(InetSocketAddress server, int timeoutSeconds, Wallet wallet, ECKey myKey,
|
public PaymentChannelClientConnection(InetSocketAddress server, int timeoutSeconds, Wallet wallet, ECKey myKey,
|
||||||
BigInteger maxValue, String serverId) throws IOException, ValueOutOfRangeException {
|
Coin maxValue, String serverId) throws IOException, ValueOutOfRangeException {
|
||||||
// Glue the object which vends/ingests protobuf messages in order to manage state to the network object which
|
// Glue the object which vends/ingests protobuf messages in order to manage state to the network object which
|
||||||
// reads/writes them to the wire in length prefixed form.
|
// reads/writes them to the wire in length prefixed form.
|
||||||
channelClient = new PaymentChannelClient(wallet, myKey, maxValue, Sha256Hash.create(serverId.getBytes()),
|
channelClient = new PaymentChannelClient(wallet, myKey, maxValue, Sha256Hash.create(serverId.getBytes()),
|
||||||
@ -119,7 +120,7 @@ public class PaymentChannelClientConnection {
|
|||||||
* an error before the channel has reached the open state.</p>
|
* an error before the channel has reached the open state.</p>
|
||||||
*
|
*
|
||||||
* <p>After this future completes successfully, you may call
|
* <p>After this future completes successfully, you may call
|
||||||
* {@link PaymentChannelClientConnection#incrementPayment(java.math.BigInteger)} to begin paying the server.</p>
|
* {@link PaymentChannelClientConnection#incrementPayment(java.math.Coin)} to begin paying the server.</p>
|
||||||
*/
|
*/
|
||||||
public ListenableFuture<PaymentChannelClientConnection> getChannelOpenFuture() {
|
public ListenableFuture<PaymentChannelClientConnection> getChannelOpenFuture() {
|
||||||
return channelOpenFuture;
|
return channelOpenFuture;
|
||||||
@ -134,7 +135,7 @@ public class PaymentChannelClientConnection {
|
|||||||
* @throws IllegalStateException If the channel has been closed or is not yet open
|
* @throws IllegalStateException If the channel has been closed or is not yet open
|
||||||
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
* (see {@link PaymentChannelClientConnection#getChannelOpenFuture()} for the second)
|
||||||
*/
|
*/
|
||||||
public ListenableFuture<BigInteger> incrementPayment(BigInteger size) throws ValueOutOfRangeException, IllegalStateException {
|
public ListenableFuture<Coin> incrementPayment(Coin size) throws ValueOutOfRangeException, IllegalStateException {
|
||||||
return channelClient.incrementPayment(size);
|
return channelClient.incrementPayment(size);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,6 @@ import com.google.common.util.concurrent.ListenableFuture;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.*;
|
||||||
@ -75,20 +74,20 @@ public class PaymentChannelClientState {
|
|||||||
// and transactions that spend it.
|
// and transactions that spend it.
|
||||||
private final ECKey myKey, serverMultisigKey;
|
private final ECKey myKey, serverMultisigKey;
|
||||||
// How much value (in satoshis) is locked up into the channel.
|
// How much value (in satoshis) is locked up into the channel.
|
||||||
private final BigInteger totalValue;
|
private final Coin totalValue;
|
||||||
// When the channel will automatically settle in favor of the client, if the server halts before protocol termination
|
// When the channel will automatically settle in favor of the client, if the server halts before protocol termination
|
||||||
// specified in terms of block timestamps (so it can off real time by a few hours).
|
// specified in terms of block timestamps (so it can off real time by a few hours).
|
||||||
private final long expiryTime;
|
private final long expiryTime;
|
||||||
|
|
||||||
// The refund is a time locked transaction that spends all the money of the channel back to the client.
|
// The refund is a time locked transaction that spends all the money of the channel back to the client.
|
||||||
private Transaction refundTx;
|
private Transaction refundTx;
|
||||||
private BigInteger refundFees;
|
private Coin refundFees;
|
||||||
// The multi-sig contract locks the value of the channel up such that the agreement of both parties is required
|
// The multi-sig contract locks the value of the channel up such that the agreement of both parties is required
|
||||||
// to spend it.
|
// to spend it.
|
||||||
private Transaction multisigContract;
|
private Transaction multisigContract;
|
||||||
private Script multisigScript;
|
private Script multisigScript;
|
||||||
// How much value is currently allocated to us. Starts as being same as totalValue.
|
// How much value is currently allocated to us. Starts as being same as totalValue.
|
||||||
private BigInteger valueToMe;
|
private Coin valueToMe;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The different logical states the channel can be in. The channel starts out as NEW, and then steps through the
|
* The different logical states the channel can be in. The channel starts out as NEW, and then steps through the
|
||||||
@ -156,7 +155,7 @@ public class PaymentChannelClientState {
|
|||||||
* @throws VerificationException If either myKey's pubkey or serverMultisigKey's pubkey are non-canonical (ie invalid)
|
* @throws VerificationException If either myKey's pubkey or serverMultisigKey's pubkey are non-canonical (ie invalid)
|
||||||
*/
|
*/
|
||||||
public PaymentChannelClientState(Wallet wallet, ECKey myKey, ECKey serverMultisigKey,
|
public PaymentChannelClientState(Wallet wallet, ECKey myKey, ECKey serverMultisigKey,
|
||||||
BigInteger value, long expiryTimeInSeconds) throws VerificationException {
|
Coin value, long expiryTimeInSeconds) throws VerificationException {
|
||||||
checkArgument(value.signum() > 0);
|
checkArgument(value.signum() > 0);
|
||||||
this.wallet = checkNotNull(wallet);
|
this.wallet = checkNotNull(wallet);
|
||||||
initWalletListeners();
|
initWalletListeners();
|
||||||
@ -174,7 +173,7 @@ public class PaymentChannelClientState {
|
|||||||
}
|
}
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
synchronized (PaymentChannelClientState.this) {
|
synchronized (PaymentChannelClientState.this) {
|
||||||
if (multisigContract == null) return;
|
if (multisigContract == null) return;
|
||||||
if (isSettlementTransaction(tx)) {
|
if (isSettlementTransaction(tx)) {
|
||||||
@ -253,7 +252,7 @@ public class PaymentChannelClientState {
|
|||||||
editContractSendRequest(req);
|
editContractSendRequest(req);
|
||||||
req.shuffleOutputs = false; // TODO: Fix things so shuffling is usable.
|
req.shuffleOutputs = false; // TODO: Fix things so shuffling is usable.
|
||||||
wallet.completeTx(req);
|
wallet.completeTx(req);
|
||||||
BigInteger multisigFee = req.fee;
|
Coin multisigFee = req.fee;
|
||||||
multisigContract = req.tx;
|
multisigContract = req.tx;
|
||||||
// Build a refund transaction that protects us in the case of a bad server that's just trying to cause havoc
|
// Build a refund transaction that protects us in the case of a bad server that's just trying to cause havoc
|
||||||
// by locking up peoples money (perhaps as a precursor to a ransom attempt). We time lock it so the server
|
// by locking up peoples money (perhaps as a precursor to a ransom attempt). We time lock it so the server
|
||||||
@ -266,7 +265,7 @@ public class PaymentChannelClientState {
|
|||||||
refundTx.setLockTime(expiryTime);
|
refundTx.setLockTime(expiryTime);
|
||||||
if (totalValue.compareTo(Utils.CENT) < 0) {
|
if (totalValue.compareTo(Utils.CENT) < 0) {
|
||||||
// Must pay min fee.
|
// Must pay min fee.
|
||||||
final BigInteger valueAfterFee = totalValue.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
final Coin valueAfterFee = totalValue.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
||||||
if (Transaction.MIN_NONDUST_OUTPUT.compareTo(valueAfterFee) > 0)
|
if (Transaction.MIN_NONDUST_OUTPUT.compareTo(valueAfterFee) > 0)
|
||||||
throw new ValueOutOfRangeException("totalValue too small to use");
|
throw new ValueOutOfRangeException("totalValue too small to use");
|
||||||
refundTx.addOutput(valueAfterFee, myKey.toAddress(params));
|
refundTx.addOutput(valueAfterFee, myKey.toAddress(params));
|
||||||
@ -292,7 +291,7 @@ public class PaymentChannelClientState {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the transaction that locks the money to the agreement of both parties. Do not mutate the result.
|
* Returns the transaction that locks the money to the agreement of both parties. Do not mutate the result.
|
||||||
* Once this step is done, you can use {@link PaymentChannelClientState#incrementPaymentBy(java.math.BigInteger)} to
|
* Once this step is done, you can use {@link PaymentChannelClientState#incrementPaymentBy(java.math.Coin)} to
|
||||||
* start paying the server.
|
* start paying the server.
|
||||||
*/
|
*/
|
||||||
public synchronized Transaction getMultisigContract() {
|
public synchronized Transaction getMultisigContract() {
|
||||||
@ -348,7 +347,7 @@ public class PaymentChannelClientState {
|
|||||||
state = State.SAVE_STATE_IN_WALLET;
|
state = State.SAVE_STATE_IN_WALLET;
|
||||||
}
|
}
|
||||||
|
|
||||||
private synchronized Transaction makeUnsignedChannelContract(BigInteger valueToMe) throws ValueOutOfRangeException {
|
private synchronized Transaction makeUnsignedChannelContract(Coin valueToMe) throws ValueOutOfRangeException {
|
||||||
Transaction tx = new Transaction(wallet.getParams());
|
Transaction tx = new Transaction(wallet.getParams());
|
||||||
tx.addInput(multisigContract.getOutput(0));
|
tx.addInput(multisigContract.getOutput(0));
|
||||||
// Our output always comes first.
|
// Our output always comes first.
|
||||||
@ -373,7 +372,7 @@ public class PaymentChannelClientState {
|
|||||||
/** Container for a signature and an amount that was sent. */
|
/** Container for a signature and an amount that was sent. */
|
||||||
public static class IncrementedPayment {
|
public static class IncrementedPayment {
|
||||||
public TransactionSignature signature;
|
public TransactionSignature signature;
|
||||||
public BigInteger amount;
|
public Coin amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -391,17 +390,17 @@ public class PaymentChannelClientState {
|
|||||||
* @throws ValueOutOfRangeException If size is negative or the channel does not have sufficient money in it to
|
* @throws ValueOutOfRangeException If size is negative or the channel does not have sufficient money in it to
|
||||||
* complete this payment.
|
* complete this payment.
|
||||||
*/
|
*/
|
||||||
public synchronized IncrementedPayment incrementPaymentBy(BigInteger size) throws ValueOutOfRangeException {
|
public synchronized IncrementedPayment incrementPaymentBy(Coin size) throws ValueOutOfRangeException {
|
||||||
checkState(state == State.READY);
|
checkState(state == State.READY);
|
||||||
checkNotExpired();
|
checkNotExpired();
|
||||||
checkNotNull(size); // Validity of size will be checked by makeUnsignedChannelContract.
|
checkNotNull(size); // Validity of size will be checked by makeUnsignedChannelContract.
|
||||||
if (size.signum() < 0)
|
if (size.signum() < 0)
|
||||||
throw new ValueOutOfRangeException("Tried to decrement payment");
|
throw new ValueOutOfRangeException("Tried to decrement payment");
|
||||||
BigInteger newValueToMe = valueToMe.subtract(size);
|
Coin newValueToMe = valueToMe.subtract(size);
|
||||||
if (newValueToMe.compareTo(Transaction.MIN_NONDUST_OUTPUT) < 0 && newValueToMe.signum() > 0) {
|
if (newValueToMe.compareTo(Transaction.MIN_NONDUST_OUTPUT) < 0 && newValueToMe.signum() > 0) {
|
||||||
log.info("New value being sent back as change was smaller than minimum nondust output, sending all");
|
log.info("New value being sent back as change was smaller than minimum nondust output, sending all");
|
||||||
size = valueToMe;
|
size = valueToMe;
|
||||||
newValueToMe = BigInteger.ZERO;
|
newValueToMe = Coin.ZERO;
|
||||||
}
|
}
|
||||||
if (newValueToMe.signum() < 0)
|
if (newValueToMe.signum() < 0)
|
||||||
throw new ValueOutOfRangeException("Channel has too little money to pay " + size + " satoshis");
|
throw new ValueOutOfRangeException("Channel has too little money to pay " + size + " satoshis");
|
||||||
@ -410,7 +409,7 @@ public class PaymentChannelClientState {
|
|||||||
Transaction.SigHash mode;
|
Transaction.SigHash mode;
|
||||||
// If we spent all the money we put into this channel, we (by definition) don't care what the outputs are, so
|
// If we spent all the money we put into this channel, we (by definition) don't care what the outputs are, so
|
||||||
// we sign with SIGHASH_NONE to let the server do what it wants.
|
// we sign with SIGHASH_NONE to let the server do what it wants.
|
||||||
if (newValueToMe.equals(BigInteger.ZERO))
|
if (newValueToMe.equals(Coin.ZERO))
|
||||||
mode = Transaction.SigHash.NONE;
|
mode = Transaction.SigHash.NONE;
|
||||||
else
|
else
|
||||||
mode = Transaction.SigHash.SINGLE;
|
mode = Transaction.SigHash.SINGLE;
|
||||||
@ -500,7 +499,7 @@ public class PaymentChannelClientState {
|
|||||||
* Returns the fees that will be paid if the refund transaction has to be claimed because the server failed to settle
|
* Returns the fees that will be paid if the refund transaction has to be claimed because the server failed to settle
|
||||||
* the channel properly. May only be called after {@link PaymentChannelClientState#initiate()}
|
* the channel properly. May only be called after {@link PaymentChannelClientState#initiate()}
|
||||||
*/
|
*/
|
||||||
public synchronized BigInteger getRefundTxFees() {
|
public synchronized Coin getRefundTxFees() {
|
||||||
checkState(state.compareTo(State.NEW) > 0);
|
checkState(state.compareTo(State.NEW) > 0);
|
||||||
return refundFees;
|
return refundFees;
|
||||||
}
|
}
|
||||||
@ -518,14 +517,14 @@ public class PaymentChannelClientState {
|
|||||||
/**
|
/**
|
||||||
* Gets the total value of this channel (ie the maximum payment possible)
|
* Gets the total value of this channel (ie the maximum payment possible)
|
||||||
*/
|
*/
|
||||||
public BigInteger getTotalValue() {
|
public Coin getTotalValue() {
|
||||||
return totalValue;
|
return totalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the current amount refunded to us from the multisig contract (ie totalValue-valueSentToServer)
|
* Gets the current amount refunded to us from the multisig contract (ie totalValue-valueSentToServer)
|
||||||
*/
|
*/
|
||||||
public synchronized BigInteger getValueRefunded() {
|
public synchronized Coin getValueRefunded() {
|
||||||
checkState(state == State.READY);
|
checkState(state == State.READY);
|
||||||
return valueToMe;
|
return valueToMe;
|
||||||
}
|
}
|
||||||
@ -533,7 +532,7 @@ public class PaymentChannelClientState {
|
|||||||
/**
|
/**
|
||||||
* Returns the amount of money sent on this channel so far.
|
* Returns the amount of money sent on this channel so far.
|
||||||
*/
|
*/
|
||||||
public synchronized BigInteger getValueSpent() {
|
public synchronized Coin getValueSpent() {
|
||||||
return getTotalValue().subtract(getValueRefunded());
|
return getTotalValue().subtract(getValueRefunded());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ import org.bitcoin.paymentchannel.Protos;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -102,7 +101,7 @@ public class PaymentChannelServer {
|
|||||||
* @param by The increase in total payment
|
* @param by The increase in total payment
|
||||||
* @param to The new total payment to us (not including fees which may be required to claim the payment)
|
* @param to The new total payment to us (not including fees which may be required to claim the payment)
|
||||||
*/
|
*/
|
||||||
public void paymentIncrease(BigInteger by, BigInteger to);
|
public void paymentIncrease(Coin by, Coin to);
|
||||||
}
|
}
|
||||||
private final ServerConnection conn;
|
private final ServerConnection conn;
|
||||||
|
|
||||||
@ -119,7 +118,7 @@ public class PaymentChannelServer {
|
|||||||
@GuardedBy("lock") private ECKey myKey;
|
@GuardedBy("lock") private ECKey myKey;
|
||||||
|
|
||||||
// The minimum accepted channel value
|
// The minimum accepted channel value
|
||||||
private final BigInteger minAcceptedChannelSize;
|
private final Coin minAcceptedChannelSize;
|
||||||
|
|
||||||
// The state manager for this channel
|
// The state manager for this channel
|
||||||
@GuardedBy("lock") private PaymentChannelServerState state;
|
@GuardedBy("lock") private PaymentChannelServerState state;
|
||||||
@ -151,7 +150,7 @@ public class PaymentChannelServer {
|
|||||||
* the client and will close the connection on request)
|
* the client and will close the connection on request)
|
||||||
*/
|
*/
|
||||||
public PaymentChannelServer(TransactionBroadcaster broadcaster, Wallet wallet,
|
public PaymentChannelServer(TransactionBroadcaster broadcaster, Wallet wallet,
|
||||||
BigInteger minAcceptedChannelSize, ServerConnection conn) {
|
Coin minAcceptedChannelSize, ServerConnection conn) {
|
||||||
this.broadcaster = checkNotNull(broadcaster);
|
this.broadcaster = checkNotNull(broadcaster);
|
||||||
this.wallet = checkNotNull(wallet);
|
this.wallet = checkNotNull(wallet);
|
||||||
this.minAcceptedChannelSize = checkNotNull(minAcceptedChannelSize);
|
this.minAcceptedChannelSize = checkNotNull(minAcceptedChannelSize);
|
||||||
@ -310,10 +309,10 @@ public class PaymentChannelServer {
|
|||||||
private void receiveUpdatePaymentMessage(Protos.UpdatePayment msg, boolean sendAck) throws VerificationException, ValueOutOfRangeException, InsufficientMoneyException {
|
private void receiveUpdatePaymentMessage(Protos.UpdatePayment msg, boolean sendAck) throws VerificationException, ValueOutOfRangeException, InsufficientMoneyException {
|
||||||
log.info("Got a payment update");
|
log.info("Got a payment update");
|
||||||
|
|
||||||
BigInteger lastBestPayment = state.getBestValueToMe();
|
Coin lastBestPayment = state.getBestValueToMe();
|
||||||
final BigInteger refundSize = BigInteger.valueOf(msg.getClientChangeValue());
|
final Coin refundSize = Coin.valueOf(msg.getClientChangeValue());
|
||||||
boolean stillUsable = state.incrementPayment(refundSize, msg.getSignature().toByteArray());
|
boolean stillUsable = state.incrementPayment(refundSize, msg.getSignature().toByteArray());
|
||||||
BigInteger bestPaymentChange = state.getBestValueToMe().subtract(lastBestPayment);
|
Coin bestPaymentChange = state.getBestValueToMe().subtract(lastBestPayment);
|
||||||
|
|
||||||
if (bestPaymentChange.signum() > 0)
|
if (bestPaymentChange.signum() > 0)
|
||||||
conn.paymentIncrease(bestPaymentChange, state.getBestValueToMe());
|
conn.paymentIncrease(bestPaymentChange, state.getBestValueToMe());
|
||||||
|
@ -17,17 +17,19 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.protocols.channels;
|
package com.google.bitcoin.protocols.channels;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.Sha256Hash;
|
import com.google.bitcoin.core.Sha256Hash;
|
||||||
import com.google.bitcoin.core.TransactionBroadcaster;
|
import com.google.bitcoin.core.TransactionBroadcaster;
|
||||||
import com.google.bitcoin.core.Wallet;
|
import com.google.bitcoin.core.Wallet;
|
||||||
import com.google.bitcoin.net.NioServer;
|
import com.google.bitcoin.net.NioServer;
|
||||||
import com.google.bitcoin.net.ProtobufParser;
|
import com.google.bitcoin.net.ProtobufParser;
|
||||||
import com.google.bitcoin.net.StreamParserFactory;
|
import com.google.bitcoin.net.StreamParserFactory;
|
||||||
|
|
||||||
import org.bitcoin.paymentchannel.Protos;
|
import org.bitcoin.paymentchannel.Protos;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
@ -46,7 +48,7 @@ public class PaymentChannelServerListener {
|
|||||||
|
|
||||||
// The event handler factory which creates new ServerConnectionEventHandler per connection
|
// The event handler factory which creates new ServerConnectionEventHandler per connection
|
||||||
private final HandlerFactory eventHandlerFactory;
|
private final HandlerFactory eventHandlerFactory;
|
||||||
private final BigInteger minAcceptedChannelSize;
|
private final Coin minAcceptedChannelSize;
|
||||||
|
|
||||||
private NioServer server;
|
private NioServer server;
|
||||||
private final int timeoutSeconds;
|
private final int timeoutSeconds;
|
||||||
@ -80,7 +82,7 @@ public class PaymentChannelServerListener {
|
|||||||
eventHandler.channelOpen(contractHash);
|
eventHandler.channelOpen(contractHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override public void paymentIncrease(BigInteger by, BigInteger to) {
|
@Override public void paymentIncrease(Coin by, Coin to) {
|
||||||
eventHandler.paymentIncrease(by, to);
|
eventHandler.paymentIncrease(by, to);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -161,7 +163,7 @@ public class PaymentChannelServerListener {
|
|||||||
* @param eventHandlerFactory A factory which generates event handlers which are created for each new connection
|
* @param eventHandlerFactory A factory which generates event handlers which are created for each new connection
|
||||||
*/
|
*/
|
||||||
public PaymentChannelServerListener(TransactionBroadcaster broadcaster, Wallet wallet,
|
public PaymentChannelServerListener(TransactionBroadcaster broadcaster, Wallet wallet,
|
||||||
final int timeoutSeconds, BigInteger minAcceptedChannelSize,
|
final int timeoutSeconds, Coin minAcceptedChannelSize,
|
||||||
HandlerFactory eventHandlerFactory) throws IOException {
|
HandlerFactory eventHandlerFactory) throws IOException {
|
||||||
this.wallet = checkNotNull(wallet);
|
this.wallet = checkNotNull(wallet);
|
||||||
this.broadcaster = checkNotNull(broadcaster);
|
this.broadcaster = checkNotNull(broadcaster);
|
||||||
|
@ -30,7 +30,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.*;
|
||||||
@ -101,9 +100,9 @@ public class PaymentChannelServerState {
|
|||||||
private byte[] bestValueSignature;
|
private byte[] bestValueSignature;
|
||||||
|
|
||||||
// The total value locked into the multi-sig output and the value to us in the last signature the client provided
|
// The total value locked into the multi-sig output and the value to us in the last signature the client provided
|
||||||
private BigInteger totalValue;
|
private Coin totalValue;
|
||||||
private BigInteger bestValueToMe = BigInteger.ZERO;
|
private Coin bestValueToMe = Coin.ZERO;
|
||||||
private BigInteger feePaidForPayment;
|
private Coin feePaidForPayment;
|
||||||
|
|
||||||
// The refund/change transaction output that goes back to the client
|
// The refund/change transaction output that goes back to the client
|
||||||
private TransactionOutput clientOutput;
|
private TransactionOutput clientOutput;
|
||||||
@ -126,7 +125,7 @@ public class PaymentChannelServerState {
|
|||||||
this.totalValue = multisigContract.getOutput(0).getValue();
|
this.totalValue = multisigContract.getOutput(0).getValue();
|
||||||
this.bestValueToMe = checkNotNull(storedServerChannel.bestValueToMe);
|
this.bestValueToMe = checkNotNull(storedServerChannel.bestValueToMe);
|
||||||
this.bestValueSignature = storedServerChannel.bestValueSignature;
|
this.bestValueSignature = storedServerChannel.bestValueSignature;
|
||||||
checkArgument(bestValueToMe.equals(BigInteger.ZERO) || bestValueSignature != null);
|
checkArgument(bestValueToMe.equals(Coin.ZERO) || bestValueSignature != null);
|
||||||
this.storedServerChannel = storedServerChannel;
|
this.storedServerChannel = storedServerChannel;
|
||||||
storedServerChannel.state = this;
|
storedServerChannel.state = this;
|
||||||
this.state = State.READY;
|
this.state = State.READY;
|
||||||
@ -263,9 +262,9 @@ public class PaymentChannelServerState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a payment transaction with valueToMe going back to us
|
// Create a payment transaction with valueToMe going back to us
|
||||||
private synchronized Wallet.SendRequest makeUnsignedChannelContract(BigInteger valueToMe) {
|
private synchronized Wallet.SendRequest makeUnsignedChannelContract(Coin valueToMe) {
|
||||||
Transaction tx = new Transaction(wallet.getParams());
|
Transaction tx = new Transaction(wallet.getParams());
|
||||||
if (!totalValue.subtract(valueToMe).equals(BigInteger.ZERO)) {
|
if (!totalValue.subtract(valueToMe).equals(Coin.ZERO)) {
|
||||||
clientOutput.setValue(totalValue.subtract(valueToMe));
|
clientOutput.setValue(totalValue.subtract(valueToMe));
|
||||||
tx.addOutput(clientOutput);
|
tx.addOutput(clientOutput);
|
||||||
}
|
}
|
||||||
@ -283,17 +282,17 @@ public class PaymentChannelServerState {
|
|||||||
* @throws VerificationException If the signature does not verify or size is out of range (incl being rejected by the network as dust).
|
* @throws VerificationException If the signature does not verify or size is out of range (incl being rejected by the network as dust).
|
||||||
* @return true if there is more value left on the channel, false if it is now fully used up.
|
* @return true if there is more value left on the channel, false if it is now fully used up.
|
||||||
*/
|
*/
|
||||||
public synchronized boolean incrementPayment(BigInteger refundSize, byte[] signatureBytes) throws VerificationException, ValueOutOfRangeException, InsufficientMoneyException {
|
public synchronized boolean incrementPayment(Coin refundSize, byte[] signatureBytes) throws VerificationException, ValueOutOfRangeException, InsufficientMoneyException {
|
||||||
checkState(state == State.READY);
|
checkState(state == State.READY);
|
||||||
checkNotNull(refundSize);
|
checkNotNull(refundSize);
|
||||||
checkNotNull(signatureBytes);
|
checkNotNull(signatureBytes);
|
||||||
TransactionSignature signature = TransactionSignature.decodeFromBitcoin(signatureBytes, true);
|
TransactionSignature signature = TransactionSignature.decodeFromBitcoin(signatureBytes, true);
|
||||||
// We allow snapping to zero for the payment amount because it's treated specially later, but not less than
|
// We allow snapping to zero for the payment amount because it's treated specially later, but not less than
|
||||||
// the dust level because that would prevent the transaction from being relayed/mined.
|
// the dust level because that would prevent the transaction from being relayed/mined.
|
||||||
final boolean fullyUsedUp = refundSize.equals(BigInteger.ZERO);
|
final boolean fullyUsedUp = refundSize.equals(Coin.ZERO);
|
||||||
if (refundSize.compareTo(clientOutput.getMinNonDustValue()) < 0 && !fullyUsedUp)
|
if (refundSize.compareTo(clientOutput.getMinNonDustValue()) < 0 && !fullyUsedUp)
|
||||||
throw new ValueOutOfRangeException("Attempt to refund negative value or value too small to be accepted by the network");
|
throw new ValueOutOfRangeException("Attempt to refund negative value or value too small to be accepted by the network");
|
||||||
BigInteger newValueToMe = totalValue.subtract(refundSize);
|
Coin newValueToMe = totalValue.subtract(refundSize);
|
||||||
if (newValueToMe.signum() < 0)
|
if (newValueToMe.signum() < 0)
|
||||||
throw new ValueOutOfRangeException("Attempt to refund more than the contract allows.");
|
throw new ValueOutOfRangeException("Attempt to refund more than the contract allows.");
|
||||||
if (newValueToMe.compareTo(bestValueToMe) < 0)
|
if (newValueToMe.compareTo(bestValueToMe) < 0)
|
||||||
@ -439,14 +438,14 @@ public class PaymentChannelServerState {
|
|||||||
/**
|
/**
|
||||||
* Gets the highest payment to ourselves (which we will receive on settle(), not including fees)
|
* Gets the highest payment to ourselves (which we will receive on settle(), not including fees)
|
||||||
*/
|
*/
|
||||||
public synchronized BigInteger getBestValueToMe() {
|
public synchronized Coin getBestValueToMe() {
|
||||||
return bestValueToMe;
|
return bestValueToMe;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the fee paid in the final payment transaction (only available if settle() did not throw an exception)
|
* Gets the fee paid in the final payment transaction (only available if settle() did not throw an exception)
|
||||||
*/
|
*/
|
||||||
public synchronized BigInteger getFeePaid() {
|
public synchronized Coin getFeePaid() {
|
||||||
checkState(state == State.CLOSED || state == State.CLOSING);
|
checkState(state == State.CLOSED || state == State.CLOSING);
|
||||||
return feePaidForPayment;
|
return feePaidForPayment;
|
||||||
}
|
}
|
||||||
|
@ -16,10 +16,10 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.protocols.channels;
|
package com.google.bitcoin.protocols.channels;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
import com.google.bitcoin.core.Coin;
|
||||||
|
|
||||||
import com.google.bitcoin.core.Sha256Hash;
|
import com.google.bitcoin.core.Sha256Hash;
|
||||||
import com.google.bitcoin.net.ProtobufParser;
|
import com.google.bitcoin.net.ProtobufParser;
|
||||||
|
|
||||||
import org.bitcoin.paymentchannel.Protos;
|
import org.bitcoin.paymentchannel.Protos;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
@ -70,7 +70,7 @@ public abstract class ServerConnectionEventHandler {
|
|||||||
* @param by The increase in total payment
|
* @param by The increase in total payment
|
||||||
* @param to The new total payment to us (not including fees which may be required to claim the payment)
|
* @param to The new total payment to us (not including fees which may be required to claim the payment)
|
||||||
*/
|
*/
|
||||||
public abstract void paymentIncrease(BigInteger by, BigInteger to);
|
public abstract void paymentIncrease(Coin by, Coin to);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Called when the channel was closed for some reason. May be called without a call to
|
* <p>Called when the channel was closed for some reason. May be called without a call to
|
||||||
|
@ -26,7 +26,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.Timer;
|
import java.util.Timer;
|
||||||
@ -69,8 +68,8 @@ public class StoredPaymentChannelClientStates implements WalletExtension {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** Returns the outstanding amount of money sent back to us for all channels to this server added together. */
|
/** Returns the outstanding amount of money sent back to us for all channels to this server added together. */
|
||||||
public BigInteger getBalanceForServer(Sha256Hash id) {
|
public Coin getBalanceForServer(Sha256Hash id) {
|
||||||
BigInteger balance = BigInteger.ZERO;
|
Coin balance = Coin.ZERO;
|
||||||
lock.lock();
|
lock.lock();
|
||||||
try {
|
try {
|
||||||
Set<StoredClientChannel> setChannels = mapChannels.get(id);
|
Set<StoredClientChannel> setChannels = mapChannels.get(id);
|
||||||
@ -120,7 +119,7 @@ public class StoredPaymentChannelClientStates implements WalletExtension {
|
|||||||
synchronized (channel) {
|
synchronized (channel) {
|
||||||
// Check if the channel is usable (has money, inactive) and if so, activate it.
|
// Check if the channel is usable (has money, inactive) and if so, activate it.
|
||||||
log.info("Considering channel {} contract {}", channel.hashCode(), channel.contract.getHash());
|
log.info("Considering channel {} contract {}", channel.hashCode(), channel.contract.getHash());
|
||||||
if (channel.close != null || channel.valueToMe.equals(BigInteger.ZERO)) {
|
if (channel.close != null || channel.valueToMe.equals(Coin.ZERO)) {
|
||||||
log.info(" ... but is closed or empty");
|
log.info(" ... but is closed or empty");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -256,8 +255,8 @@ public class StoredPaymentChannelClientStates implements WalletExtension {
|
|||||||
new Transaction(params, storedState.getContractTransaction().toByteArray()),
|
new Transaction(params, storedState.getContractTransaction().toByteArray()),
|
||||||
refundTransaction,
|
refundTransaction,
|
||||||
ECKey.fromPrivate(storedState.getMyKey().toByteArray()),
|
ECKey.fromPrivate(storedState.getMyKey().toByteArray()),
|
||||||
BigInteger.valueOf(storedState.getValueToMe()),
|
Coin.valueOf(storedState.getValueToMe()),
|
||||||
BigInteger.valueOf(storedState.getRefundFees()), false);
|
Coin.valueOf(storedState.getRefundFees()), false);
|
||||||
if (storedState.hasCloseTransactionHash())
|
if (storedState.hasCloseTransactionHash())
|
||||||
channel.close = containingWallet.getTransaction(new Sha256Hash(storedState.toByteArray()));
|
channel.close = containingWallet.getTransaction(new Sha256Hash(storedState.toByteArray()));
|
||||||
putChannel(channel, false);
|
putChannel(channel, false);
|
||||||
@ -292,13 +291,13 @@ class StoredClientChannel {
|
|||||||
// The transaction that closed the channel (generated by the server)
|
// The transaction that closed the channel (generated by the server)
|
||||||
Transaction close;
|
Transaction close;
|
||||||
ECKey myKey;
|
ECKey myKey;
|
||||||
BigInteger valueToMe, refundFees;
|
Coin valueToMe, refundFees;
|
||||||
|
|
||||||
// In-memory flag to indicate intent to resume this channel (or that the channel is already in use)
|
// In-memory flag to indicate intent to resume this channel (or that the channel is already in use)
|
||||||
boolean active = false;
|
boolean active = false;
|
||||||
|
|
||||||
StoredClientChannel(Sha256Hash id, Transaction contract, Transaction refund, ECKey myKey, BigInteger valueToMe,
|
StoredClientChannel(Sha256Hash id, Transaction contract, Transaction refund, ECKey myKey, Coin valueToMe,
|
||||||
BigInteger refundFees, boolean active) {
|
Coin refundFees, boolean active) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.contract = contract;
|
this.contract = contract;
|
||||||
this.refund = refund;
|
this.refund = refund;
|
||||||
|
@ -24,7 +24,6 @@ import net.jcip.annotations.GuardedBy;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.locks.ReentrantLock;
|
import java.util.concurrent.locks.ReentrantLock;
|
||||||
|
|
||||||
@ -183,7 +182,7 @@ public class StoredPaymentChannelServerStates implements WalletExtension {
|
|||||||
new TransactionOutput(params, null, storedState.getClientOutput().toByteArray(), 0),
|
new TransactionOutput(params, null, storedState.getClientOutput().toByteArray(), 0),
|
||||||
storedState.getRefundTransactionUnlockTimeSecs(),
|
storedState.getRefundTransactionUnlockTimeSecs(),
|
||||||
ECKey.fromPrivate(storedState.getMyKey().toByteArray()),
|
ECKey.fromPrivate(storedState.getMyKey().toByteArray()),
|
||||||
BigInteger.valueOf(storedState.getBestValueToMe()),
|
Coin.valueOf(storedState.getBestValueToMe()),
|
||||||
storedState.hasBestValueSignature() ? storedState.getBestValueSignature().toByteArray() : null);
|
storedState.hasBestValueSignature() ? storedState.getBestValueSignature().toByteArray() : null);
|
||||||
putChannel(channel);
|
putChannel(channel);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,6 @@ package com.google.bitcoin.protocols.channels;
|
|||||||
import com.google.bitcoin.core.*;
|
import com.google.bitcoin.core.*;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
@ -30,7 +29,7 @@ import static com.google.common.base.Preconditions.checkArgument;
|
|||||||
* time approaches.
|
* time approaches.
|
||||||
*/
|
*/
|
||||||
public class StoredServerChannel {
|
public class StoredServerChannel {
|
||||||
BigInteger bestValueToMe;
|
Coin bestValueToMe;
|
||||||
byte[] bestValueSignature;
|
byte[] bestValueSignature;
|
||||||
long refundTransactionUnlockTimeSecs;
|
long refundTransactionUnlockTimeSecs;
|
||||||
Transaction contract;
|
Transaction contract;
|
||||||
@ -43,7 +42,7 @@ public class StoredServerChannel {
|
|||||||
PaymentChannelServerState state = null;
|
PaymentChannelServerState state = null;
|
||||||
|
|
||||||
StoredServerChannel(@Nullable PaymentChannelServerState state, Transaction contract, TransactionOutput clientOutput,
|
StoredServerChannel(@Nullable PaymentChannelServerState state, Transaction contract, TransactionOutput clientOutput,
|
||||||
long refundTransactionUnlockTimeSecs, ECKey myKey, BigInteger bestValueToMe, @Nullable byte[] bestValueSignature) {
|
long refundTransactionUnlockTimeSecs, ECKey myKey, Coin bestValueToMe, @Nullable byte[] bestValueSignature) {
|
||||||
this.contract = contract;
|
this.contract = contract;
|
||||||
this.clientOutput = clientOutput;
|
this.clientOutput = clientOutput;
|
||||||
this.refundTransactionUnlockTimeSecs = refundTransactionUnlockTimeSecs;
|
this.refundTransactionUnlockTimeSecs = refundTransactionUnlockTimeSecs;
|
||||||
@ -57,7 +56,7 @@ public class StoredServerChannel {
|
|||||||
* <p>Updates the best value to the server to the given newValue and newSignature without any checking.</p>
|
* <p>Updates the best value to the server to the given newValue and newSignature without any checking.</p>
|
||||||
* <p>Does <i>NOT</i> notify the wallet of an update to the {@link StoredPaymentChannelServerStates}.</p>
|
* <p>Does <i>NOT</i> notify the wallet of an update to the {@link StoredPaymentChannelServerStates}.</p>
|
||||||
*/
|
*/
|
||||||
synchronized void updateValueToMe(BigInteger newValue, byte[] newSignature) {
|
synchronized void updateValueToMe(Coin newValue, byte[] newSignature) {
|
||||||
this.bestValueToMe = newValue;
|
this.bestValueToMe = newValue;
|
||||||
this.bestValueSignature = newSignature;
|
this.bestValueSignature = newSignature;
|
||||||
}
|
}
|
||||||
@ -107,11 +106,11 @@ public class StoredServerChannel {
|
|||||||
final String newline = String.format("%n");
|
final String newline = String.format("%n");
|
||||||
return String.format("Stored server channel (%s)%n" +
|
return String.format("Stored server channel (%s)%n" +
|
||||||
" Key: %s%n" +
|
" Key: %s%n" +
|
||||||
" Value to me: %d%n" +
|
" Value to me: %s%n" +
|
||||||
" Client output: %s%n" +
|
" Client output: %s%n" +
|
||||||
" Refund unlock: %s (%d unix time)%n" +
|
" Refund unlock: %s (%d unix time)%n" +
|
||||||
" Contract: %s%n",
|
" Contract: %s%n",
|
||||||
connectedHandler != null ? "connected" : "disconnected", myKey, bestValueToMe,
|
connectedHandler != null ? "connected" : "disconnected", myKey, bestValueToMe.toString(),
|
||||||
clientOutput, new Date(refundTransactionUnlockTimeSecs * 1000), refundTransactionUnlockTimeSecs,
|
clientOutput, new Date(refundTransactionUnlockTimeSecs * 1000), refundTransactionUnlockTimeSecs,
|
||||||
contract.toString().replaceAll(newline, newline + " "));
|
contract.toString().replaceAll(newline, newline + " "));
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
package com.google.bitcoin.protocols.payments;
|
package com.google.bitcoin.protocols.payments;
|
||||||
|
|
||||||
import com.google.bitcoin.core.Address;
|
import com.google.bitcoin.core.Address;
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.NetworkParameters;
|
import com.google.bitcoin.core.NetworkParameters;
|
||||||
import com.google.bitcoin.core.Transaction;
|
import com.google.bitcoin.core.Transaction;
|
||||||
import com.google.bitcoin.crypto.X509Utils;
|
import com.google.bitcoin.crypto.X509Utils;
|
||||||
@ -30,7 +31,6 @@ import org.bitcoin.protocols.payments.Protos;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.security.*;
|
import java.security.*;
|
||||||
import java.security.cert.*;
|
import java.security.cert.*;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
@ -67,7 +67,7 @@ public class PaymentProtocol {
|
|||||||
* @return created payment request, in its builder form
|
* @return created payment request, in its builder form
|
||||||
*/
|
*/
|
||||||
public static Protos.PaymentRequest.Builder createPaymentRequest(NetworkParameters params,
|
public static Protos.PaymentRequest.Builder createPaymentRequest(NetworkParameters params,
|
||||||
@Nullable BigInteger amount, Address toAddress, @Nullable String memo, @Nullable String paymentUrl,
|
@Nullable Coin amount, Address toAddress, @Nullable String memo, @Nullable String paymentUrl,
|
||||||
@Nullable byte[] merchantData) {
|
@Nullable byte[] merchantData) {
|
||||||
return createPaymentRequest(params, ImmutableList.of(createPayToAddressOutput(amount, toAddress)), memo,
|
return createPaymentRequest(params, ImmutableList.of(createPayToAddressOutput(amount, toAddress)), memo,
|
||||||
paymentUrl, merchantData);
|
paymentUrl, merchantData);
|
||||||
@ -282,7 +282,7 @@ public class PaymentProtocol {
|
|||||||
* @return created payment message
|
* @return created payment message
|
||||||
*/
|
*/
|
||||||
public static Protos.Payment createPaymentMessage(List<Transaction> transactions,
|
public static Protos.Payment createPaymentMessage(List<Transaction> transactions,
|
||||||
@Nullable BigInteger refundAmount, @Nullable Address refundAddress, @Nullable String memo,
|
@Nullable Coin refundAmount, @Nullable Address refundAddress, @Nullable String memo,
|
||||||
@Nullable byte[] merchantData) {
|
@Nullable byte[] merchantData) {
|
||||||
if (refundAddress != null) {
|
if (refundAddress != null) {
|
||||||
if (refundAmount == null)
|
if (refundAmount == null)
|
||||||
@ -387,7 +387,7 @@ public class PaymentProtocol {
|
|||||||
* @param address address to pay to
|
* @param address address to pay to
|
||||||
* @return output
|
* @return output
|
||||||
*/
|
*/
|
||||||
public static Protos.Output createPayToAddressOutput(@Nullable BigInteger amount, Address address) {
|
public static Protos.Output createPayToAddressOutput(@Nullable Coin amount, Address address) {
|
||||||
Protos.Output.Builder output = Protos.Output.newBuilder();
|
Protos.Output.Builder output = Protos.Output.newBuilder();
|
||||||
if (amount != null) {
|
if (amount != null) {
|
||||||
if (amount.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
if (amount.compareTo(NetworkParameters.MAX_MONEY) > 0)
|
||||||
@ -404,10 +404,10 @@ public class PaymentProtocol {
|
|||||||
* Value object to hold amount/script pairs.
|
* Value object to hold amount/script pairs.
|
||||||
*/
|
*/
|
||||||
public static class Output implements Serializable {
|
public static class Output implements Serializable {
|
||||||
public final @Nullable BigInteger amount;
|
public final @Nullable Coin amount;
|
||||||
public final byte[] scriptData;
|
public final byte[] scriptData;
|
||||||
|
|
||||||
public Output(@Nullable BigInteger amount, byte[] scriptData) {
|
public Output(@Nullable Coin amount, byte[] scriptData) {
|
||||||
this.amount = amount;
|
this.amount = amount;
|
||||||
this.scriptData = scriptData;
|
this.scriptData = scriptData;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,6 @@ import org.bitcoin.protocols.payments.Protos;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.*;
|
import java.net.*;
|
||||||
import java.security.KeyStoreException;
|
import java.security.KeyStoreException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
@ -71,7 +70,7 @@ public class PaymentSession {
|
|||||||
private final TrustStoreLoader trustStoreLoader;
|
private final TrustStoreLoader trustStoreLoader;
|
||||||
private Protos.PaymentRequest paymentRequest;
|
private Protos.PaymentRequest paymentRequest;
|
||||||
private Protos.PaymentDetails paymentDetails;
|
private Protos.PaymentDetails paymentDetails;
|
||||||
private BigInteger totalValue = BigInteger.ZERO;
|
private Coin totalValue = Coin.ZERO;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stores the calculated PKI verification data, or null if none is available.
|
* Stores the calculated PKI verification data, or null if none is available.
|
||||||
@ -224,7 +223,7 @@ public class PaymentSession {
|
|||||||
public List<PaymentProtocol.Output> getOutputs() {
|
public List<PaymentProtocol.Output> getOutputs() {
|
||||||
List<PaymentProtocol.Output> outputs = new ArrayList<PaymentProtocol.Output>(paymentDetails.getOutputsCount());
|
List<PaymentProtocol.Output> outputs = new ArrayList<PaymentProtocol.Output>(paymentDetails.getOutputsCount());
|
||||||
for (Protos.Output output : paymentDetails.getOutputsList()) {
|
for (Protos.Output output : paymentDetails.getOutputsList()) {
|
||||||
BigInteger amount = output.hasAmount() ? BigInteger.valueOf(output.getAmount()) : null;
|
Coin amount = output.hasAmount() ? Coin.valueOf(output.getAmount()) : null;
|
||||||
outputs.add(new PaymentProtocol.Output(amount, output.getScript().toByteArray()));
|
outputs.add(new PaymentProtocol.Output(amount, output.getScript().toByteArray()));
|
||||||
}
|
}
|
||||||
return outputs;
|
return outputs;
|
||||||
@ -243,7 +242,7 @@ public class PaymentSession {
|
|||||||
/**
|
/**
|
||||||
* Returns the total amount of bitcoins requested.
|
* Returns the total amount of bitcoins requested.
|
||||||
*/
|
*/
|
||||||
public BigInteger getValue() {
|
public Coin getValue() {
|
||||||
return totalValue;
|
return totalValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -297,7 +296,7 @@ public class PaymentSession {
|
|||||||
public Wallet.SendRequest getSendRequest() {
|
public Wallet.SendRequest getSendRequest() {
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
for (Protos.Output output : paymentDetails.getOutputsList())
|
for (Protos.Output output : paymentDetails.getOutputsList())
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(output.getAmount()), output.getScript().toByteArray()));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(output.getAmount()), output.getScript().toByteArray()));
|
||||||
return Wallet.SendRequest.forTx(tx);
|
return Wallet.SendRequest.forTx(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -397,7 +396,7 @@ public class PaymentSession {
|
|||||||
throw new PaymentProtocolException.InvalidOutputs("No outputs");
|
throw new PaymentProtocolException.InvalidOutputs("No outputs");
|
||||||
for (Protos.Output output : paymentDetails.getOutputsList()) {
|
for (Protos.Output output : paymentDetails.getOutputsList()) {
|
||||||
if (output.hasAmount())
|
if (output.hasAmount())
|
||||||
totalValue = totalValue.add(BigInteger.valueOf(output.getAmount()));
|
totalValue = totalValue.add(Coin.valueOf(output.getAmount()));
|
||||||
}
|
}
|
||||||
// This won't ever happen in practice. It would only happen if the user provided outputs
|
// This won't ever happen in practice. It would only happen if the user provided outputs
|
||||||
// that are obviously invalid. Still, we don't want to silently overflow.
|
// that are obviously invalid. Still, we don't want to silently overflow.
|
||||||
|
@ -650,7 +650,7 @@ public class H2FullPrunedBlockStore implements FullPrunedBlockStore {
|
|||||||
}
|
}
|
||||||
// Parse it.
|
// Parse it.
|
||||||
int height = results.getInt(1);
|
int height = results.getInt(1);
|
||||||
BigInteger value = new BigInteger(results.getBytes(2));
|
Coin value = new Coin(results.getBytes(2));
|
||||||
// Tell the StoredTransactionOutput that we are a coinbase, as that is encoded in height
|
// Tell the StoredTransactionOutput that we are a coinbase, as that is encoded in height
|
||||||
return new StoredTransactionOutput(hash, index, value, height, true, results.getBytes(3));
|
return new StoredTransactionOutput(hash, index, value, height, true, results.getBytes(3));
|
||||||
} catch (SQLException ex) {
|
} catch (SQLException ex) {
|
||||||
|
@ -744,7 +744,7 @@ public class PostgresFullPrunedBlockStore implements FullPrunedBlockStore {
|
|||||||
}
|
}
|
||||||
// Parse it.
|
// Parse it.
|
||||||
int height = results.getInt(1);
|
int height = results.getInt(1);
|
||||||
BigInteger value = new BigInteger(results.getBytes(2));
|
Coin value = new Coin(results.getBytes(2));
|
||||||
// Tell the StoredTransactionOutput that we are a coinbase, as that is encoded in height
|
// Tell the StoredTransactionOutput that we are a coinbase, as that is encoded in height
|
||||||
StoredTransactionOutput txout = new StoredTransactionOutput(hash, index, value, height, true, results.getBytes(3));
|
StoredTransactionOutput txout = new StoredTransactionOutput(hash, index, value, height, true, results.getBytes(3));
|
||||||
return txout;
|
return txout;
|
||||||
|
@ -503,7 +503,7 @@ public class WalletProtobufSerializer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (Protos.TransactionOutput outputProto : txProto.getTransactionOutputList()) {
|
for (Protos.TransactionOutput outputProto : txProto.getTransactionOutputList()) {
|
||||||
BigInteger value = BigInteger.valueOf(outputProto.getValue());
|
Coin value = Coin.valueOf(outputProto.getValue());
|
||||||
byte[] scriptBytes = outputProto.getScriptBytes().toByteArray();
|
byte[] scriptBytes = outputProto.getScriptBytes().toByteArray();
|
||||||
TransactionOutput output = new TransactionOutput(params, tx, value, scriptBytes);
|
TransactionOutput output = new TransactionOutput(params, tx, value, scriptBytes);
|
||||||
tx.addOutput(output);
|
tx.addOutput(output);
|
||||||
@ -515,7 +515,7 @@ public class WalletProtobufSerializer {
|
|||||||
inputProto.getTransactionOutPointIndex() & 0xFFFFFFFFL,
|
inputProto.getTransactionOutPointIndex() & 0xFFFFFFFFL,
|
||||||
byteStringToHash(inputProto.getTransactionOutPointHash())
|
byteStringToHash(inputProto.getTransactionOutPointHash())
|
||||||
);
|
);
|
||||||
BigInteger value = inputProto.hasValue() ? BigInteger.valueOf(inputProto.getValue()) : null;
|
Coin value = inputProto.hasValue() ? Coin.valueOf(inputProto.getValue()) : null;
|
||||||
TransactionInput input = new TransactionInput(params, tx, scriptBytes, outpoint, value);
|
TransactionInput input = new TransactionInput(params, tx, scriptBytes, outpoint, value);
|
||||||
if (inputProto.hasSequence()) {
|
if (inputProto.hasSequence()) {
|
||||||
input.setSequenceNumber(inputProto.getSequence());
|
input.setSequenceNumber(inputProto.getSequence());
|
||||||
|
@ -22,7 +22,6 @@ import com.google.bitcoin.store.BlockStoreException;
|
|||||||
|
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,7 +32,7 @@ public class FakeTxBuilder {
|
|||||||
* Create a fake TX of sufficient realism to exercise the unit tests. Two outputs, one to us, one to somewhere
|
* Create a fake TX of sufficient realism to exercise the unit tests. Two outputs, one to us, one to somewhere
|
||||||
* else to simulate change. There is one random input.
|
* else to simulate change. There is one random input.
|
||||||
*/
|
*/
|
||||||
public static Transaction createFakeTxWithChangeAddress(NetworkParameters params, BigInteger nanocoins, Address to, Address changeOutput) {
|
public static Transaction createFakeTxWithChangeAddress(NetworkParameters params, Coin nanocoins, Address to, Address changeOutput) {
|
||||||
Transaction t = new Transaction(params);
|
Transaction t = new Transaction(params);
|
||||||
TransactionOutput outputToMe = new TransactionOutput(params, t, nanocoins, to);
|
TransactionOutput outputToMe = new TransactionOutput(params, t, nanocoins, to);
|
||||||
t.addOutput(outputToMe);
|
t.addOutput(outputToMe);
|
||||||
@ -54,7 +53,7 @@ public class FakeTxBuilder {
|
|||||||
* Create a fake TX of sufficient realism to exercise the unit tests. Two outputs, one to us, one to somewhere
|
* Create a fake TX of sufficient realism to exercise the unit tests. Two outputs, one to us, one to somewhere
|
||||||
* else to simulate change. There is one random input.
|
* else to simulate change. There is one random input.
|
||||||
*/
|
*/
|
||||||
public static Transaction createFakeTx(NetworkParameters params, BigInteger nanocoins, Address to) {
|
public static Transaction createFakeTx(NetworkParameters params, Coin nanocoins, Address to) {
|
||||||
return createFakeTxWithChangeAddress(params, nanocoins, to, new ECKey().toAddress(params));
|
return createFakeTxWithChangeAddress(params, nanocoins, to, new ECKey().toAddress(params));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,7 +61,7 @@ public class FakeTxBuilder {
|
|||||||
* Create a fake TX of sufficient realism to exercise the unit tests. Two outputs, one to us, one to somewhere
|
* Create a fake TX of sufficient realism to exercise the unit tests. Two outputs, one to us, one to somewhere
|
||||||
* else to simulate change. There is one random input.
|
* else to simulate change. There is one random input.
|
||||||
*/
|
*/
|
||||||
public static Transaction createFakeTx(NetworkParameters params, BigInteger nanocoins, ECKey to) {
|
public static Transaction createFakeTx(NetworkParameters params, Coin nanocoins, ECKey to) {
|
||||||
Transaction t = new Transaction(params);
|
Transaction t = new Transaction(params);
|
||||||
TransactionOutput outputToMe = new TransactionOutput(params, t, nanocoins, to);
|
TransactionOutput outputToMe = new TransactionOutput(params, t, nanocoins, to);
|
||||||
t.addOutput(outputToMe);
|
t.addOutput(outputToMe);
|
||||||
@ -82,7 +81,7 @@ public class FakeTxBuilder {
|
|||||||
/**
|
/**
|
||||||
* Transaction[0] is a feeder transaction, supplying BTC to Transaction[1]
|
* Transaction[0] is a feeder transaction, supplying BTC to Transaction[1]
|
||||||
*/
|
*/
|
||||||
public static Transaction[] createFakeTx(NetworkParameters params, BigInteger nanocoins,
|
public static Transaction[] createFakeTx(NetworkParameters params, Coin nanocoins,
|
||||||
Address to, Address from) {
|
Address to, Address from) {
|
||||||
// Create fake TXes of sufficient realism to exercise the unit tests. This transaction send BTC from the
|
// Create fake TXes of sufficient realism to exercise the unit tests. This transaction send BTC from the
|
||||||
// from address, to the to address with to one to somewhere else to simulate change.
|
// from address, to the to address with to one to somewhere else to simulate change.
|
||||||
@ -134,7 +133,7 @@ public class FakeTxBuilder {
|
|||||||
*/
|
*/
|
||||||
public static DoubleSpends createFakeDoubleSpendTxns(NetworkParameters params, Address to) {
|
public static DoubleSpends createFakeDoubleSpendTxns(NetworkParameters params, Address to) {
|
||||||
DoubleSpends doubleSpends = new DoubleSpends();
|
DoubleSpends doubleSpends = new DoubleSpends();
|
||||||
BigInteger value = Utils.toNanoCoins(1, 0);
|
Coin value = Utils.toNanoCoins(1, 0);
|
||||||
Address someBadGuy = new ECKey().toAddress(params);
|
Address someBadGuy = new ECKey().toAddress(params);
|
||||||
|
|
||||||
doubleSpends.t1 = new Transaction(params);
|
doubleSpends.t1 = new Transaction(params);
|
||||||
|
@ -29,7 +29,6 @@ import com.google.common.util.concurrent.SettableFuture;
|
|||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import javax.net.SocketFactory;
|
import javax.net.SocketFactory;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
@ -82,7 +81,7 @@ public class TestWithNetworkConnections {
|
|||||||
BriefLogFormatter.init();
|
BriefLogFormatter.init();
|
||||||
|
|
||||||
unitTestParams = UnitTestParams.get();
|
unitTestParams = UnitTestParams.get();
|
||||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
|
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||||
this.blockStore = blockStore;
|
this.blockStore = blockStore;
|
||||||
wallet = new Wallet(unitTestParams);
|
wallet = new Wallet(unitTestParams);
|
||||||
key = wallet.freshReceiveKey();
|
key = wallet.freshReceiveKey();
|
||||||
|
@ -24,7 +24,6 @@ import com.google.bitcoin.utils.BriefLogFormatter;
|
|||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeBlock;
|
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeBlock;
|
||||||
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeTx;
|
import static com.google.bitcoin.testing.FakeTxBuilder.createFakeTx;
|
||||||
@ -49,7 +48,7 @@ public class TestWithWallet {
|
|||||||
|
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
BriefLogFormatter.init();
|
BriefLogFormatter.init();
|
||||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
|
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||||
wallet = new Wallet(params);
|
wallet = new Wallet(params);
|
||||||
myKey = wallet.currentReceiveKey();
|
myKey = wallet.currentReceiveKey();
|
||||||
myAddress = myKey.toAddress(params);
|
myAddress = myKey.toAddress(params);
|
||||||
@ -83,17 +82,17 @@ public class TestWithWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected Transaction sendMoneyToWallet(Wallet wallet, BigInteger value, Address toAddress, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
protected Transaction sendMoneyToWallet(Wallet wallet, Coin value, Address toAddress, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
||||||
return sendMoneyToWallet(wallet, createFakeTx(params, value, toAddress), type);
|
return sendMoneyToWallet(wallet, createFakeTx(params, value, toAddress), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected Transaction sendMoneyToWallet(Wallet wallet, BigInteger value, ECKey toPubKey, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
protected Transaction sendMoneyToWallet(Wallet wallet, Coin value, ECKey toPubKey, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
||||||
return sendMoneyToWallet(wallet, createFakeTx(params, value, toPubKey), type);
|
return sendMoneyToWallet(wallet, createFakeTx(params, value, toPubKey), type);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
protected Transaction sendMoneyToWallet(BigInteger value, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
protected Transaction sendMoneyToWallet(Coin value, AbstractBlockChain.NewBlockType type) throws IOException, VerificationException {
|
||||||
return sendMoneyToWallet(this.wallet, createFakeTx(params, value, myAddress), type);
|
return sendMoneyToWallet(this.wallet, createFakeTx(params, value, myAddress), type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,14 +20,16 @@ package com.google.bitcoin.uri;
|
|||||||
|
|
||||||
import com.google.bitcoin.core.Address;
|
import com.google.bitcoin.core.Address;
|
||||||
import com.google.bitcoin.core.AddressFormatException;
|
import com.google.bitcoin.core.AddressFormatException;
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.NetworkParameters;
|
import com.google.bitcoin.core.NetworkParameters;
|
||||||
import com.google.bitcoin.core.Utils;
|
import com.google.bitcoin.core.Utils;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import java.io.UnsupportedEncodingException;
|
import java.io.UnsupportedEncodingException;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.URI;
|
import java.net.URI;
|
||||||
import java.net.URISyntaxException;
|
import java.net.URISyntaxException;
|
||||||
import java.net.URLDecoder;
|
import java.net.URLDecoder;
|
||||||
@ -207,7 +209,7 @@ public class BitcoinURI {
|
|||||||
if (FIELD_AMOUNT.equals(nameToken)) {
|
if (FIELD_AMOUNT.equals(nameToken)) {
|
||||||
// Decode the amount (contains an optional decimal component to 8dp).
|
// Decode the amount (contains an optional decimal component to 8dp).
|
||||||
try {
|
try {
|
||||||
BigInteger amount = Utils.toNanoCoins(valueToken);
|
Coin amount = Utils.toNanoCoins(valueToken);
|
||||||
putWithValidation(FIELD_AMOUNT, amount);
|
putWithValidation(FIELD_AMOUNT, amount);
|
||||||
} catch (NumberFormatException e) {
|
} catch (NumberFormatException e) {
|
||||||
throw new OptionalFieldValidationException(String.format("'%s' is not a valid amount", valueToken), e);
|
throw new OptionalFieldValidationException(String.format("'%s' is not a valid amount", valueToken), e);
|
||||||
@ -263,8 +265,8 @@ public class BitcoinURI {
|
|||||||
* @return The amount name encoded using a pure integer value based at
|
* @return The amount name encoded using a pure integer value based at
|
||||||
* 10,000,000 units is 1 BTC. May be null if no amount is specified
|
* 10,000,000 units is 1 BTC. May be null if no amount is specified
|
||||||
*/
|
*/
|
||||||
public BigInteger getAmount() {
|
public Coin getAmount() {
|
||||||
return (BigInteger) parameterMap.get(FIELD_AMOUNT);
|
return (Coin) parameterMap.get(FIELD_AMOUNT);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -313,7 +315,7 @@ public class BitcoinURI {
|
|||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static String convertToBitcoinURI(Address address, BigInteger amount, String label, String message) {
|
public static String convertToBitcoinURI(Address address, Coin amount, String label, String message) {
|
||||||
return convertToBitcoinURI(address.toString(), amount, label, message);
|
return convertToBitcoinURI(address.toString(), amount, label, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -326,11 +328,11 @@ public class BitcoinURI {
|
|||||||
* @param message A message
|
* @param message A message
|
||||||
* @return A String containing the Bitcoin URI
|
* @return A String containing the Bitcoin URI
|
||||||
*/
|
*/
|
||||||
public static String convertToBitcoinURI(String address, @Nullable BigInteger amount, @Nullable String label,
|
public static String convertToBitcoinURI(String address, @Nullable Coin amount, @Nullable String label,
|
||||||
@Nullable String message) {
|
@Nullable String message) {
|
||||||
checkNotNull(address);
|
checkNotNull(address);
|
||||||
if (amount != null && amount.signum() < 0) {
|
if (amount != null && amount.signum() < 0) {
|
||||||
throw new IllegalArgumentException("Amount must be positive");
|
throw new IllegalArgumentException("Coin must be positive");
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
|
@ -1,22 +1,22 @@
|
|||||||
package com.google.bitcoin.wallet;
|
package com.google.bitcoin.wallet;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.TransactionOutput;
|
import com.google.bitcoin.core.TransactionOutput;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the results of a
|
* Represents the results of a
|
||||||
* {@link com.google.bitcoin.wallet.CoinSelector#select(java.math.BigInteger, java.util.LinkedList)} operation. A
|
* {@link com.google.bitcoin.wallet.CoinSelector#select(java.math.Coin, java.util.LinkedList)} operation. A
|
||||||
* coin selection represents a list of spendable transaction outputs that sum together to give valueGathered.
|
* coin selection represents a list of spendable transaction outputs that sum together to give valueGathered.
|
||||||
* Different coin selections could be produced by different coin selectors from the same input set, according
|
* Different coin selections could be produced by different coin selectors from the same input set, according
|
||||||
* to their varying policies.
|
* to their varying policies.
|
||||||
*/
|
*/
|
||||||
public class CoinSelection {
|
public class CoinSelection {
|
||||||
public BigInteger valueGathered;
|
public Coin valueGathered;
|
||||||
public Collection<TransactionOutput> gathered;
|
public Collection<TransactionOutput> gathered;
|
||||||
|
|
||||||
public CoinSelection(BigInteger valueGathered, Collection<TransactionOutput> gathered) {
|
public CoinSelection(Coin valueGathered, Collection<TransactionOutput> gathered) {
|
||||||
this.valueGathered = valueGathered;
|
this.valueGathered = valueGathered;
|
||||||
this.gathered = gathered;
|
this.gathered = gathered;
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
package com.google.bitcoin.wallet;
|
package com.google.bitcoin.wallet;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.TransactionOutput;
|
import com.google.bitcoin.core.TransactionOutput;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -17,5 +17,5 @@ public interface CoinSelector {
|
|||||||
* this call and can be edited freely. See the docs for CoinSelection to learn more, or look a the implementation
|
* this call and can be edited freely. See the docs for CoinSelection to learn more, or look a the implementation
|
||||||
* of {@link com.google.bitcoin.wallet.DefaultCoinSelector}.
|
* of {@link com.google.bitcoin.wallet.DefaultCoinSelector}.
|
||||||
*/
|
*/
|
||||||
public CoinSelection select(BigInteger target, LinkedList<TransactionOutput> candidates);
|
public CoinSelection select(Coin target, LinkedList<TransactionOutput> candidates);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package com.google.bitcoin.wallet;
|
package com.google.bitcoin.wallet;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.NetworkParameters;
|
import com.google.bitcoin.core.NetworkParameters;
|
||||||
import com.google.bitcoin.core.Transaction;
|
import com.google.bitcoin.core.Transaction;
|
||||||
import com.google.bitcoin.core.TransactionConfidence;
|
import com.google.bitcoin.core.TransactionConfidence;
|
||||||
@ -16,7 +17,7 @@ import java.util.*;
|
|||||||
* "spending" more priority than would be required to get the transaction we are creating confirmed.
|
* "spending" more priority than would be required to get the transaction we are creating confirmed.
|
||||||
*/
|
*/
|
||||||
public class DefaultCoinSelector implements CoinSelector {
|
public class DefaultCoinSelector implements CoinSelector {
|
||||||
public CoinSelection select(BigInteger biTarget, LinkedList<TransactionOutput> candidates) {
|
public CoinSelection select(Coin biTarget, LinkedList<TransactionOutput> candidates) {
|
||||||
long target = biTarget.longValue();
|
long target = biTarget.longValue();
|
||||||
HashSet<TransactionOutput> selected = new HashSet<TransactionOutput>();
|
HashSet<TransactionOutput> selected = new HashSet<TransactionOutput>();
|
||||||
// Sort the inputs by age*value so we get the highest "coindays" spent.
|
// Sort the inputs by age*value so we get the highest "coindays" spent.
|
||||||
@ -39,7 +40,7 @@ public class DefaultCoinSelector implements CoinSelector {
|
|||||||
}
|
}
|
||||||
// Total may be lower than target here, if the given candidates were insufficient to create to requested
|
// Total may be lower than target here, if the given candidates were insufficient to create to requested
|
||||||
// transaction.
|
// transaction.
|
||||||
return new CoinSelection(BigInteger.valueOf(total), selected);
|
return new CoinSelection(Coin.valueOf(total), selected);
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisibleForTesting static void sortOutputs(ArrayList<TransactionOutput> outputs) {
|
@VisibleForTesting static void sortOutputs(ArrayList<TransactionOutput> outputs) {
|
||||||
@ -53,10 +54,10 @@ public class DefaultCoinSelector implements CoinSelector {
|
|||||||
depth1 = conf1.getDepthInBlocks();
|
depth1 = conf1.getDepthInBlocks();
|
||||||
if (conf2.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING)
|
if (conf2.getConfidenceType() == TransactionConfidence.ConfidenceType.BUILDING)
|
||||||
depth2 = conf2.getDepthInBlocks();
|
depth2 = conf2.getDepthInBlocks();
|
||||||
BigInteger aValue = a.getValue();
|
Coin aValue = a.getValue();
|
||||||
BigInteger bValue = b.getValue();
|
Coin bValue = b.getValue();
|
||||||
BigInteger aCoinDepth = aValue.multiply(BigInteger.valueOf(depth1));
|
BigInteger aCoinDepth = aValue.toBigInteger().multiply(BigInteger.valueOf(depth1));
|
||||||
BigInteger bCoinDepth = bValue.multiply(BigInteger.valueOf(depth2));
|
BigInteger bCoinDepth = bValue.toBigInteger().multiply(BigInteger.valueOf(depth2));
|
||||||
int c1 = bCoinDepth.compareTo(aCoinDepth);
|
int c1 = bCoinDepth.compareTo(aCoinDepth);
|
||||||
if (c1 != 0) return c1;
|
if (c1 != 0) return c1;
|
||||||
// The "coin*days" destroyed are equal, sort by value alone to get the lowest transaction size.
|
// The "coin*days" destroyed are equal, sort by value alone to get the lowest transaction size.
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.wallet;
|
package com.google.bitcoin.wallet;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.NetworkParameters;
|
import com.google.bitcoin.core.NetworkParameters;
|
||||||
import com.google.bitcoin.core.Transaction;
|
import com.google.bitcoin.core.Transaction;
|
||||||
import com.google.bitcoin.core.TransactionConfidence;
|
import com.google.bitcoin.core.TransactionConfidence;
|
||||||
@ -24,13 +25,11 @@ import com.google.bitcoin.core.TransactionInput;
|
|||||||
import com.google.bitcoin.core.TransactionOutput;
|
import com.google.bitcoin.core.TransactionOutput;
|
||||||
import com.google.bitcoin.core.Wallet;
|
import com.google.bitcoin.core.Wallet;
|
||||||
import com.google.bitcoin.script.ScriptChunk;
|
import com.google.bitcoin.script.ScriptChunk;
|
||||||
|
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkState;
|
import static com.google.common.base.Preconditions.checkState;
|
||||||
@ -48,7 +47,7 @@ public class DefaultRiskAnalysis implements RiskAnalysis {
|
|||||||
* rejected by the network. Currently it's 546 satoshis. This is different from {@link Transaction#MIN_NONDUST_OUTPUT}
|
* rejected by the network. Currently it's 546 satoshis. This is different from {@link Transaction#MIN_NONDUST_OUTPUT}
|
||||||
* because of an upcoming fee change in Bitcoin Core 0.9.
|
* because of an upcoming fee change in Bitcoin Core 0.9.
|
||||||
*/
|
*/
|
||||||
public static final BigInteger MIN_ANALYSIS_NONDUST_OUTPUT = BigInteger.valueOf(546);
|
public static final Coin MIN_ANALYSIS_NONDUST_OUTPUT = Coin.valueOf(546);
|
||||||
|
|
||||||
protected final Transaction tx;
|
protected final Transaction tx;
|
||||||
protected final List<Transaction> dependencies;
|
protected final List<Transaction> dependencies;
|
||||||
|
@ -22,7 +22,6 @@ import com.google.common.collect.Lists;
|
|||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
@ -48,10 +47,10 @@ public class KeyTimeCoinSelector implements CoinSelector {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public CoinSelection select(BigInteger target, LinkedList<TransactionOutput> candidates) {
|
public CoinSelection select(Coin target, LinkedList<TransactionOutput> candidates) {
|
||||||
try {
|
try {
|
||||||
LinkedList<TransactionOutput> gathered = Lists.newLinkedList();
|
LinkedList<TransactionOutput> gathered = Lists.newLinkedList();
|
||||||
BigInteger valueGathered = BigInteger.ZERO;
|
Coin valueGathered = Coin.ZERO;
|
||||||
for (TransactionOutput output : candidates) {
|
for (TransactionOutput output : candidates) {
|
||||||
if (ignorePending && !isConfirmed(output))
|
if (ignorePending && !isConfirmed(output))
|
||||||
continue;
|
continue;
|
||||||
|
@ -5978,7 +5978,7 @@ public final class Protos {
|
|||||||
internal_static_payments_Output_fieldAccessorTable = new
|
internal_static_payments_Output_fieldAccessorTable = new
|
||||||
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
com.google.protobuf.GeneratedMessage.FieldAccessorTable(
|
||||||
internal_static_payments_Output_descriptor,
|
internal_static_payments_Output_descriptor,
|
||||||
new java.lang.String[] { "Amount", "Script", });
|
new java.lang.String[] { "Coin", "Script", });
|
||||||
internal_static_payments_PaymentDetails_descriptor =
|
internal_static_payments_PaymentDetails_descriptor =
|
||||||
getDescriptor().getMessageTypes().get(1);
|
getDescriptor().getMessageTypes().get(1);
|
||||||
internal_static_payments_PaymentDetails_fieldAccessorTable = new
|
internal_static_payments_PaymentDetails_fieldAccessorTable = new
|
||||||
|
@ -65,7 +65,7 @@ public class BlockChainTest {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
BriefLogFormatter.initVerbose();
|
BriefLogFormatter.initVerbose();
|
||||||
testNetChain = new BlockChain(testNet, new Wallet(testNet), new MemoryBlockStore(testNet));
|
testNetChain = new BlockChain(testNet, new Wallet(testNet), new MemoryBlockStore(testNet));
|
||||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
|
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||||
|
|
||||||
unitTestParams = UnitTestParams.get();
|
unitTestParams = UnitTestParams.get();
|
||||||
wallet = new Wallet(unitTestParams) {
|
wallet = new Wallet(unitTestParams) {
|
||||||
@ -278,7 +278,7 @@ public class BlockChainTest {
|
|||||||
b1.addTransaction(t2);
|
b1.addTransaction(t2);
|
||||||
b1.solve();
|
b1.solve();
|
||||||
chain.add(b1);
|
chain.add(b1);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -300,7 +300,7 @@ public class BlockChainTest {
|
|||||||
assertNotNull(coinbaseTransaction);
|
assertNotNull(coinbaseTransaction);
|
||||||
|
|
||||||
// The coinbase tx is not yet available to spend.
|
// The coinbase tx is not yet available to spend.
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(50, 0));
|
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(50, 0));
|
||||||
assertTrue(!coinbaseTransaction.isMature());
|
assertTrue(!coinbaseTransaction.isMature());
|
||||||
|
|
||||||
@ -321,7 +321,7 @@ public class BlockChainTest {
|
|||||||
chain.add(b2);
|
chain.add(b2);
|
||||||
|
|
||||||
// Wallet still does not have the coinbase transaction available for spend.
|
// Wallet still does not have the coinbase transaction available for spend.
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(50, 0));
|
assertEquals(wallet.getBalance(BalanceType.ESTIMATED), Utils.toNanoCoins(50, 0));
|
||||||
|
|
||||||
// The coinbase transaction is still not mature.
|
// The coinbase transaction is still not mature.
|
||||||
|
@ -164,7 +164,7 @@ public class BlockTest {
|
|||||||
//assertTrue(tx.length == tx.bitcoinSerialize().length && tx.length == 8);
|
//assertTrue(tx.length == tx.bitcoinSerialize().length && tx.length == 8);
|
||||||
byte[] outputScript = new byte[10];
|
byte[] outputScript = new byte[10];
|
||||||
Arrays.fill(outputScript, (byte) ScriptOpCodes.OP_FALSE);
|
Arrays.fill(outputScript, (byte) ScriptOpCodes.OP_FALSE);
|
||||||
tx.addOutput(new TransactionOutput(params, null, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, null, Coin.valueOf(1), outputScript));
|
||||||
tx.addInput(new TransactionInput(params, null, new byte[] {(byte) ScriptOpCodes.OP_FALSE},
|
tx.addInput(new TransactionInput(params, null, new byte[] {(byte) ScriptOpCodes.OP_FALSE},
|
||||||
new TransactionOutPoint(params, 0, Sha256Hash.create(new byte[] {1}))));
|
new TransactionOutPoint(params, 0, Sha256Hash.create(new byte[] {1}))));
|
||||||
int origTxLength = 8 + 2 + 8 + 1 + 10 + 40 + 1 + 1;
|
int origTxLength = 8 + 2 + 8 + 1 + 10 + 40 + 1 + 1;
|
||||||
|
@ -22,6 +22,7 @@ import com.google.bitcoin.store.MemoryBlockStore;
|
|||||||
import com.google.bitcoin.testing.FakeTxBuilder;
|
import com.google.bitcoin.testing.FakeTxBuilder;
|
||||||
import com.google.bitcoin.utils.BriefLogFormatter;
|
import com.google.bitcoin.utils.BriefLogFormatter;
|
||||||
import com.google.bitcoin.utils.Threading;
|
import com.google.bitcoin.utils.Threading;
|
||||||
|
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.slf4j.Logger;
|
import org.slf4j.Logger;
|
||||||
@ -53,7 +54,7 @@ public class ChainSplitTest {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
BriefLogFormatter.init();
|
BriefLogFormatter.init();
|
||||||
Utils.setMockClock(); // Use mock clock
|
Utils.setMockClock(); // Use mock clock
|
||||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
|
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||||
unitTestParams = UnitTestParams.get();
|
unitTestParams = UnitTestParams.get();
|
||||||
wallet = new Wallet(unitTestParams);
|
wallet = new Wallet(unitTestParams);
|
||||||
ECKey key1 = wallet.freshReceiveKey();
|
ECKey key1 = wallet.freshReceiveKey();
|
||||||
@ -164,11 +165,11 @@ public class ChainSplitTest {
|
|||||||
assertTrue(chain.add(b2));
|
assertTrue(chain.add(b2));
|
||||||
// genesis -> b1 -> b2
|
// genesis -> b1 -> b2
|
||||||
// \-> b3 -> b4
|
// \-> b3 -> b4
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
Block b3 = b1.createNextBlock(coinsTo);
|
Block b3 = b1.createNextBlock(coinsTo);
|
||||||
Block b4 = b3.createNextBlock(someOtherGuy);
|
Block b4 = b3.createNextBlock(someOtherGuy);
|
||||||
assertTrue(chain.add(b3));
|
assertTrue(chain.add(b3));
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertTrue(chain.add(b4));
|
assertTrue(chain.add(b4));
|
||||||
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
|
assertEquals("50.00", Utils.bitcoinValueToFriendlyString(wallet.getBalance()));
|
||||||
}
|
}
|
||||||
@ -183,7 +184,7 @@ public class ChainSplitTest {
|
|||||||
Transaction spend = wallet.createSend(dest, Utils.toNanoCoins(10, 0));
|
Transaction spend = wallet.createSend(dest, Utils.toNanoCoins(10, 0));
|
||||||
wallet.commitTx(spend);
|
wallet.commitTx(spend);
|
||||||
// Waiting for confirmation ... make it eligible for selection.
|
// Waiting for confirmation ... make it eligible for selection.
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
spend.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByAddress(new byte[]{1, 2, 3, 4})));
|
spend.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByAddress(new byte[]{1, 2, 3, 4})));
|
||||||
spend.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByAddress(new byte[]{5,6,7,8})));
|
spend.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByAddress(new byte[]{5,6,7,8})));
|
||||||
assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
|
assertEquals(ConfidenceType.PENDING, spend.getConfidence().getConfidenceType());
|
||||||
@ -276,7 +277,7 @@ public class ChainSplitTest {
|
|||||||
// -> b2
|
// -> b2
|
||||||
Block b2 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
|
Block b2 = unitTestParams.getGenesisBlock().createNextBlock(coinsTo);
|
||||||
chain.add(b2);
|
chain.add(b2);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
// genesis -> b1 -> b3
|
// genesis -> b1 -> b3
|
||||||
// -> b2
|
// -> b2
|
||||||
Block b3 = b1.createNextBlock(someOtherGuy);
|
Block b3 = b1.createNextBlock(someOtherGuy);
|
||||||
@ -399,7 +400,7 @@ public class ChainSplitTest {
|
|||||||
final ArrayList<Transaction> txns = new ArrayList<Transaction>(3);
|
final ArrayList<Transaction> txns = new ArrayList<Transaction>(3);
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
txns.add(tx);
|
txns.add(tx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -552,7 +553,7 @@ public class ChainSplitTest {
|
|||||||
wallet.commitTx(t3);
|
wallet.commitTx(t3);
|
||||||
chain.add(FakeTxBuilder.makeSolvedTestBlock(b1, t2, t3));
|
chain.add(FakeTxBuilder.makeSolvedTestBlock(b1, t2, t3));
|
||||||
|
|
||||||
final BigInteger coins0point98 = Utils.COIN.subtract(Utils.CENT).subtract(Utils.CENT);
|
final Coin coins0point98 = Utils.COIN.subtract(Utils.CENT).subtract(Utils.CENT);
|
||||||
assertEquals(coins0point98, wallet.getBalance());
|
assertEquals(coins0point98, wallet.getBalance());
|
||||||
|
|
||||||
// Now round trip the wallet and force a re-org.
|
// Now round trip the wallet and force a re-org.
|
||||||
@ -577,7 +578,7 @@ public class ChainSplitTest {
|
|||||||
final ArrayList<Transaction> txns = new ArrayList<Transaction>(3);
|
final ArrayList<Transaction> txns = new ArrayList<Transaction>(3);
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
txns.add(tx);
|
txns.add(tx);
|
||||||
}
|
}
|
||||||
}, Threading.SAME_THREAD);
|
}, Threading.SAME_THREAD);
|
||||||
|
@ -42,7 +42,7 @@ public class CoinbaseBlockTest {
|
|||||||
private static final int BLOCK_OF_INTEREST = 169482;
|
private static final int BLOCK_OF_INTEREST = 169482;
|
||||||
private static final int BLOCK_LENGTH_AS_HEX = 37357;
|
private static final int BLOCK_LENGTH_AS_HEX = 37357;
|
||||||
private static final long BLOCK_NONCE = 3973947400L;
|
private static final long BLOCK_NONCE = 3973947400L;
|
||||||
private static final BigInteger BALANCE_AFTER_BLOCK = BigInteger.valueOf(22223642);
|
private static final Coin BALANCE_AFTER_BLOCK = Coin.valueOf(22223642);
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testReceiveCoinbaseTransaction() throws Exception {
|
public void testReceiveCoinbaseTransaction() throws Exception {
|
||||||
@ -70,7 +70,7 @@ public class CoinbaseBlockTest {
|
|||||||
wallet.importKey(miningKey);
|
wallet.importKey(miningKey);
|
||||||
|
|
||||||
// Initial balance should be zero by construction.
|
// Initial balance should be zero by construction.
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
|
|
||||||
// Give the wallet the first transaction in the block - this is the coinbase tx.
|
// Give the wallet the first transaction in the block - this is the coinbase tx.
|
||||||
List<Transaction> transactions = block.getTransactions();
|
List<Transaction> transactions = block.getTransactions();
|
||||||
@ -79,7 +79,7 @@ public class CoinbaseBlockTest {
|
|||||||
|
|
||||||
// Coinbase transaction should have been received successfully but be unavailable to spend (too young).
|
// Coinbase transaction should have been received successfully but be unavailable to spend (too young).
|
||||||
assertEquals(BALANCE_AFTER_BLOCK, wallet.getBalance(BalanceType.ESTIMATED));
|
assertEquals(BALANCE_AFTER_BLOCK, wallet.getBalance(BalanceType.ESTIMATED));
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance(BalanceType.AVAILABLE));
|
assertEquals(Coin.ZERO, wallet.getBalance(BalanceType.AVAILABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -65,9 +65,9 @@ class Rule {
|
|||||||
|
|
||||||
class TransactionOutPointWithValue {
|
class TransactionOutPointWithValue {
|
||||||
public TransactionOutPoint outpoint;
|
public TransactionOutPoint outpoint;
|
||||||
public BigInteger value;
|
public Coin value;
|
||||||
Script scriptPubKey;
|
Script scriptPubKey;
|
||||||
public TransactionOutPointWithValue(TransactionOutPoint outpoint, BigInteger value, Script scriptPubKey) {
|
public TransactionOutPointWithValue(TransactionOutPoint outpoint, Coin value, Script scriptPubKey) {
|
||||||
this.outpoint = outpoint;
|
this.outpoint = outpoint;
|
||||||
this.value = value;
|
this.value = value;
|
||||||
this.scriptPubKey = scriptPubKey;
|
this.scriptPubKey = scriptPubKey;
|
||||||
@ -217,7 +217,7 @@ public class FullBlockTestGenerator {
|
|||||||
// \-> b9 (4)
|
// \-> b9 (4)
|
||||||
// \-> b3 (1) -> b4 (2)
|
// \-> b3 (1) -> b4 (2)
|
||||||
//
|
//
|
||||||
Block b9 = createNextBlock(b6, chainHeadHeight + 5, out4, BigInteger.valueOf(1));
|
Block b9 = createNextBlock(b6, chainHeadHeight + 5, out4, Coin.valueOf(1));
|
||||||
blocks.add(new BlockAndValidity(blockToHeightMap, b9, false, true, b6.getHash(), chainHeadHeight + 4, "b9"));
|
blocks.add(new BlockAndValidity(blockToHeightMap, b9, false, true, b6.getHash(), chainHeadHeight + 4, "b9"));
|
||||||
|
|
||||||
// Create a fork that ends in a block with too much fee (the one that causes the reorg)
|
// Create a fork that ends in a block with too much fee (the one that causes the reorg)
|
||||||
@ -228,7 +228,7 @@ public class FullBlockTestGenerator {
|
|||||||
Block b10 = createNextBlock(b5, chainHeadHeight + 4, out3, null);
|
Block b10 = createNextBlock(b5, chainHeadHeight + 4, out3, null);
|
||||||
blocks.add(new BlockAndValidity(blockToHeightMap, b10, true, false, b6.getHash(), chainHeadHeight + 4, "b10"));
|
blocks.add(new BlockAndValidity(blockToHeightMap, b10, true, false, b6.getHash(), chainHeadHeight + 4, "b10"));
|
||||||
|
|
||||||
Block b11 = createNextBlock(b10, chainHeadHeight + 5, out4, BigInteger.valueOf(1));
|
Block b11 = createNextBlock(b10, chainHeadHeight + 5, out4, Coin.valueOf(1));
|
||||||
blocks.add(new BlockAndValidity(blockToHeightMap, b11, false, true, b6.getHash(), chainHeadHeight + 4, "b11"));
|
blocks.add(new BlockAndValidity(blockToHeightMap, b11, false, true, b6.getHash(), chainHeadHeight + 4, "b11"));
|
||||||
|
|
||||||
// Try again, but with a valid fork first
|
// Try again, but with a valid fork first
|
||||||
@ -254,7 +254,7 @@ public class FullBlockTestGenerator {
|
|||||||
|
|
||||||
TransactionOutPointWithValue out5 = spendableOutputs.poll();
|
TransactionOutPointWithValue out5 = spendableOutputs.poll();
|
||||||
|
|
||||||
Block b14 = createNextBlock(b13, chainHeadHeight + 6, out5, BigInteger.valueOf(1));
|
Block b14 = createNextBlock(b13, chainHeadHeight + 6, out5, Coin.valueOf(1));
|
||||||
// This will be "validly" added, though its actually invalid, it will just be marked orphan
|
// This will be "validly" added, though its actually invalid, it will just be marked orphan
|
||||||
// and will be discarded when an attempt is made to reorg to it.
|
// and will be discarded when an attempt is made to reorg to it.
|
||||||
// TODO: Use a WeakReference to check that it is freed properly after the reorg
|
// TODO: Use a WeakReference to check that it is freed properly after the reorg
|
||||||
@ -278,10 +278,10 @@ public class FullBlockTestGenerator {
|
|||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps];
|
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps];
|
||||||
Arrays.fill(outputScript, (byte) OP_CHECKSIG);
|
Arrays.fill(outputScript, (byte) OP_CHECKSIG);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b15.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b15.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b15.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b15.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b15.addTransaction(tx);
|
b15.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b15.solve();
|
b15.solve();
|
||||||
@ -303,10 +303,10 @@ public class FullBlockTestGenerator {
|
|||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps + 1];
|
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps + 1];
|
||||||
Arrays.fill(outputScript, (byte) OP_CHECKSIG);
|
Arrays.fill(outputScript, (byte) OP_CHECKSIG);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b16.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b16.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b16.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b16.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b16.addTransaction(tx);
|
b16.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b16.solve();
|
b16.solve();
|
||||||
@ -321,10 +321,10 @@ public class FullBlockTestGenerator {
|
|||||||
Block b17 = createNextBlock(b15, chainHeadHeight + 7, out6, null);
|
Block b17 = createNextBlock(b15, chainHeadHeight + 7, out6, null);
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {}));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {}));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b3.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b3.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b3.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b3.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b17.addTransaction(tx);
|
b17.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b17.solve();
|
b17.solve();
|
||||||
@ -339,10 +339,10 @@ public class FullBlockTestGenerator {
|
|||||||
Block b18 = createNextBlock(b13, chainHeadHeight + 6, out5, null);
|
Block b18 = createNextBlock(b13, chainHeadHeight + 6, out5, null);
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {}));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {}));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b3.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b3.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b3.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b3.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b18.addTransaction(tx);
|
b18.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b18.solve();
|
b18.solve();
|
||||||
@ -384,10 +384,10 @@ public class FullBlockTestGenerator {
|
|||||||
// Signature size is non-deterministic, so it may take several runs before finding any off-by-one errors
|
// Signature size is non-deterministic, so it may take several runs before finding any off-by-one errors
|
||||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIZE - b23.getMessageSize() - 138];
|
byte[] outputScript = new byte[Block.MAX_BLOCK_SIZE - b23.getMessageSize() - 138];
|
||||||
Arrays.fill(outputScript, (byte) OP_FALSE);
|
Arrays.fill(outputScript, (byte) OP_FALSE);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b23.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b23.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b23.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b23.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b23.addTransaction(tx);
|
b23.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b23.solve();
|
b23.solve();
|
||||||
@ -403,10 +403,10 @@ public class FullBlockTestGenerator {
|
|||||||
// Signature size is non-deterministic, so it may take several runs before finding any off-by-one errors
|
// Signature size is non-deterministic, so it may take several runs before finding any off-by-one errors
|
||||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIZE - b24.getMessageSize() - 135];
|
byte[] outputScript = new byte[Block.MAX_BLOCK_SIZE - b24.getMessageSize() - 135];
|
||||||
Arrays.fill(outputScript, (byte) OP_FALSE);
|
Arrays.fill(outputScript, (byte) OP_FALSE);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b24.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b24.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b24.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b24.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b24.addTransaction(tx);
|
b24.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b24.solve();
|
b24.solve();
|
||||||
@ -479,10 +479,10 @@ public class FullBlockTestGenerator {
|
|||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
byte[] outputScript = new byte[(Block.MAX_BLOCK_SIGOPS - sigOps)/20];
|
byte[] outputScript = new byte[(Block.MAX_BLOCK_SIGOPS - sigOps)/20];
|
||||||
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIG);
|
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIG);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b31.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b31.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b31.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b31.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b31.addTransaction(tx);
|
b31.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b31.solve();
|
b31.solve();
|
||||||
@ -506,10 +506,10 @@ public class FullBlockTestGenerator {
|
|||||||
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIG);
|
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIG);
|
||||||
for (int i = 0; i < (Block.MAX_BLOCK_SIGOPS - sigOps)%20; i++)
|
for (int i = 0; i < (Block.MAX_BLOCK_SIGOPS - sigOps)%20; i++)
|
||||||
outputScript[i] = (byte) OP_CHECKSIG;
|
outputScript[i] = (byte) OP_CHECKSIG;
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b32.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b32.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b32.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b32.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b32.addTransaction(tx);
|
b32.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b32.solve();
|
b32.solve();
|
||||||
@ -526,10 +526,10 @@ public class FullBlockTestGenerator {
|
|||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
byte[] outputScript = new byte[(Block.MAX_BLOCK_SIGOPS - sigOps)/20];
|
byte[] outputScript = new byte[(Block.MAX_BLOCK_SIGOPS - sigOps)/20];
|
||||||
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIGVERIFY);
|
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIGVERIFY);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b33.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b33.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b33.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b33.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b33.addTransaction(tx);
|
b33.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b33.solve();
|
b33.solve();
|
||||||
@ -553,10 +553,10 @@ public class FullBlockTestGenerator {
|
|||||||
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIGVERIFY);
|
Arrays.fill(outputScript, (byte) OP_CHECKMULTISIGVERIFY);
|
||||||
for (int i = 0; i < (Block.MAX_BLOCK_SIGOPS - sigOps)%20; i++)
|
for (int i = 0; i < (Block.MAX_BLOCK_SIGOPS - sigOps)%20; i++)
|
||||||
outputScript[i] = (byte) OP_CHECKSIG;
|
outputScript[i] = (byte) OP_CHECKSIG;
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b34.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b34.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b34.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b34.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b34.addTransaction(tx);
|
b34.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b34.solve();
|
b34.solve();
|
||||||
@ -573,10 +573,10 @@ public class FullBlockTestGenerator {
|
|||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps];
|
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps];
|
||||||
Arrays.fill(outputScript, (byte) OP_CHECKSIGVERIFY);
|
Arrays.fill(outputScript, (byte) OP_CHECKSIGVERIFY);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b35.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b35.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b35.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b35.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b35.addTransaction(tx);
|
b35.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b35.solve();
|
b35.solve();
|
||||||
@ -598,10 +598,10 @@ public class FullBlockTestGenerator {
|
|||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps + 1];
|
byte[] outputScript = new byte[Block.MAX_BLOCK_SIGOPS - sigOps + 1];
|
||||||
Arrays.fill(outputScript, (byte) OP_CHECKSIGVERIFY);
|
Arrays.fill(outputScript, (byte) OP_CHECKSIGVERIFY);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b36.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b36.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b36.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b36.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b36.addTransaction(tx);
|
b36.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b36.solve();
|
b36.solve();
|
||||||
@ -618,7 +618,7 @@ public class FullBlockTestGenerator {
|
|||||||
Block b37 = createNextBlock(b35, chainHeadHeight + 12, out11, null);
|
Block b37 = createNextBlock(b35, chainHeadHeight + 12, out11, null);
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {}));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {}));
|
||||||
addOnlyInputToTransaction(tx, out11); // double spend out11
|
addOnlyInputToTransaction(tx, out11); // double spend out11
|
||||||
b37.addTransaction(tx);
|
b37.addTransaction(tx);
|
||||||
}
|
}
|
||||||
@ -628,11 +628,11 @@ public class FullBlockTestGenerator {
|
|||||||
Block b38 = createNextBlock(b35, chainHeadHeight + 12, out11, null);
|
Block b38 = createNextBlock(b35, chainHeadHeight + 12, out11, null);
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {}));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {}));
|
||||||
// Attempt to spend b37's first non-coinbase tx, at which point b37 was still considered valid
|
// Attempt to spend b37's first non-coinbase tx, at which point b37 was still considered valid
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b37.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b37.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b37.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b37.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b38.addTransaction(tx);
|
b38.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b38.solve();
|
b38.solve();
|
||||||
@ -676,11 +676,11 @@ public class FullBlockTestGenerator {
|
|||||||
}
|
}
|
||||||
scriptPubKey.write(OP_EQUAL);
|
scriptPubKey.write(OP_EQUAL);
|
||||||
|
|
||||||
BigInteger lastOutputValue = out11.value.subtract(BigInteger.valueOf(1));
|
Coin lastOutputValue = out11.value.subtract(Coin.valueOf(1));
|
||||||
TransactionOutPoint lastOutPoint;
|
TransactionOutPoint lastOutPoint;
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), scriptPubKey.toByteArray()));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), scriptPubKey.toByteArray()));
|
||||||
tx.addOutput(new TransactionOutput(params, tx, lastOutputValue, new byte[]{OP_1}));
|
tx.addOutput(new TransactionOutput(params, tx, lastOutputValue, new byte[]{OP_1}));
|
||||||
addOnlyInputToTransaction(tx, out11);
|
addOnlyInputToTransaction(tx, out11);
|
||||||
lastOutPoint = new TransactionOutPoint(params, 1, tx.getHash());
|
lastOutPoint = new TransactionOutPoint(params, 1, tx.getHash());
|
||||||
@ -692,8 +692,8 @@ public class FullBlockTestGenerator {
|
|||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
|
|
||||||
lastOutputValue = lastOutputValue.subtract(BigInteger.valueOf(1));
|
lastOutputValue = lastOutputValue.subtract(Coin.valueOf(1));
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), scriptPubKey.toByteArray()));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), scriptPubKey.toByteArray()));
|
||||||
tx.addOutput(new TransactionOutput(params, tx, lastOutputValue, new byte[]{OP_1}));
|
tx.addOutput(new TransactionOutput(params, tx, lastOutputValue, new byte[]{OP_1}));
|
||||||
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_1}, lastOutPoint));
|
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_1}, lastOutPoint));
|
||||||
lastOutPoint = new TransactionOutPoint(params, 1, tx.getHash());
|
lastOutPoint = new TransactionOutPoint(params, 1, tx.getHash());
|
||||||
@ -729,7 +729,7 @@ public class FullBlockTestGenerator {
|
|||||||
byte[] scriptSig = null;
|
byte[] scriptSig = null;
|
||||||
for (int i = 1; i <= numTxes; i++) {
|
for (int i = 1; i <= numTxes; i++) {
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {OP_1}));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {OP_1}));
|
||||||
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_1}, lastOutPoint));
|
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_1}, lastOutPoint));
|
||||||
|
|
||||||
TransactionInput input = new TransactionInput(params, tx, new byte[]{},
|
TransactionInput input = new TransactionInput(params, tx, new byte[]{},
|
||||||
@ -770,7 +770,7 @@ public class FullBlockTestGenerator {
|
|||||||
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_1}, lastOutPoint));
|
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_1}, lastOutPoint));
|
||||||
byte[] scriptPubKey = new byte[Block.MAX_BLOCK_SIGOPS - sigOps + 1];
|
byte[] scriptPubKey = new byte[Block.MAX_BLOCK_SIGOPS - sigOps + 1];
|
||||||
Arrays.fill(scriptPubKey, (byte) OP_CHECKSIG);
|
Arrays.fill(scriptPubKey, (byte) OP_CHECKSIG);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, scriptPubKey));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, scriptPubKey));
|
||||||
b40.addTransaction(tx);
|
b40.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b40.solve();
|
b40.solve();
|
||||||
@ -795,7 +795,7 @@ public class FullBlockTestGenerator {
|
|||||||
byte[] scriptSig = null;
|
byte[] scriptSig = null;
|
||||||
for (int i = 1; i <= numTxes; i++) {
|
for (int i = 1; i <= numTxes; i++) {
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger
|
tx.addOutput(new TransactionOutput(params, tx, Coin
|
||||||
.valueOf(1), new byte[] {OP_1}));
|
.valueOf(1), new byte[] {OP_1}));
|
||||||
tx.addInput(new TransactionInput(params, tx,
|
tx.addInput(new TransactionInput(params, tx,
|
||||||
new byte[] {OP_1}, lastOutPoint));
|
new byte[] {OP_1}, lastOutPoint));
|
||||||
@ -847,7 +847,7 @@ public class FullBlockTestGenerator {
|
|||||||
new byte[] {OP_1}, lastOutPoint));
|
new byte[] {OP_1}, lastOutPoint));
|
||||||
byte[] scriptPubKey = new byte[Block.MAX_BLOCK_SIGOPS - sigOps];
|
byte[] scriptPubKey = new byte[Block.MAX_BLOCK_SIGOPS - sigOps];
|
||||||
Arrays.fill(scriptPubKey, (byte) OP_CHECKSIG);
|
Arrays.fill(scriptPubKey, (byte) OP_CHECKSIG);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, scriptPubKey));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, scriptPubKey));
|
||||||
b41.addTransaction(tx);
|
b41.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b41.solve();
|
b41.solve();
|
||||||
@ -885,14 +885,14 @@ public class FullBlockTestGenerator {
|
|||||||
byte[] outScriptBytes = ScriptBuilder.createOutputScript(ECKey.fromPublicOnly(coinbaseOutKeyPubKey)).getProgram();
|
byte[] outScriptBytes = ScriptBuilder.createOutputScript(ECKey.fromPublicOnly(coinbaseOutKeyPubKey)).getProgram();
|
||||||
{
|
{
|
||||||
b44.setDifficultyTarget(b43.getDifficultyTarget());
|
b44.setDifficultyTarget(b43.getDifficultyTarget());
|
||||||
b44.addCoinbaseTransaction(coinbaseOutKeyPubKey, BigInteger.ZERO);
|
b44.addCoinbaseTransaction(coinbaseOutKeyPubKey, Coin.ZERO);
|
||||||
|
|
||||||
Transaction t = new Transaction(params);
|
Transaction t = new Transaction(params);
|
||||||
// Entirely invalid scriptPubKey to ensure we aren't pre-verifying too much
|
// Entirely invalid scriptPubKey to ensure we aren't pre-verifying too much
|
||||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
||||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(1), outScriptBytes));
|
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(1), outScriptBytes));
|
||||||
// Spendable output
|
// Spendable output
|
||||||
t.addOutput(new TransactionOutput(params, t, BigInteger.ZERO, new byte[] {OP_1}));
|
t.addOutput(new TransactionOutput(params, t, Coin.ZERO, new byte[] {OP_1}));
|
||||||
addOnlyInputToTransaction(t, out14);
|
addOnlyInputToTransaction(t, out14);
|
||||||
b44.addTransaction(t);
|
b44.addTransaction(t);
|
||||||
|
|
||||||
@ -912,10 +912,10 @@ public class FullBlockTestGenerator {
|
|||||||
|
|
||||||
Transaction t = new Transaction(params);
|
Transaction t = new Transaction(params);
|
||||||
// Entirely invalid scriptPubKey to ensure we aren't pre-verifying too much
|
// Entirely invalid scriptPubKey to ensure we aren't pre-verifying too much
|
||||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
||||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(1), outScriptBytes));
|
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(1), outScriptBytes));
|
||||||
// Spendable output
|
// Spendable output
|
||||||
t.addOutput(new TransactionOutput(params, t, BigInteger.ZERO, new byte[] {OP_1}));
|
t.addOutput(new TransactionOutput(params, t, Coin.ZERO, new byte[] {OP_1}));
|
||||||
addOnlyInputToTransaction(t, out15);
|
addOnlyInputToTransaction(t, out15);
|
||||||
try {
|
try {
|
||||||
b45.addTransaction(t);
|
b45.addTransaction(t);
|
||||||
@ -989,7 +989,7 @@ public class FullBlockTestGenerator {
|
|||||||
{
|
{
|
||||||
Transaction coinbase = new Transaction(params);
|
Transaction coinbase = new Transaction(params);
|
||||||
coinbase.addInput(new TransactionInput(params, coinbase, new byte[]{(byte) 0xff, 110, 1}));
|
coinbase.addInput(new TransactionInput(params, coinbase, new byte[]{(byte) 0xff, 110, 1}));
|
||||||
coinbase.addOutput(new TransactionOutput(params, coinbase, BigInteger.ONE, outScriptBytes));
|
coinbase.addOutput(new TransactionOutput(params, coinbase, Coin.ONE, outScriptBytes));
|
||||||
b51.addTransaction(coinbase, false);
|
b51.addTransaction(coinbase, false);
|
||||||
}
|
}
|
||||||
b51.solve();
|
b51.solve();
|
||||||
@ -999,10 +999,10 @@ public class FullBlockTestGenerator {
|
|||||||
Block b52 = createNextBlock(b44, chainHeadHeight + 16, out15, null);
|
Block b52 = createNextBlock(b44, chainHeadHeight + 16, out15, null);
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), new byte[] {}));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), new byte[] {}));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b52.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b52.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b52.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b52.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b52.addTransaction(tx);
|
b52.addTransaction(tx);
|
||||||
b52.addTransaction(tx);
|
b52.addTransaction(tx);
|
||||||
}
|
}
|
||||||
@ -1047,10 +1047,10 @@ public class FullBlockTestGenerator {
|
|||||||
Transaction b56txToDuplicate;
|
Transaction b56txToDuplicate;
|
||||||
{
|
{
|
||||||
b56txToDuplicate = new Transaction(params);
|
b56txToDuplicate = new Transaction(params);
|
||||||
b56txToDuplicate.addOutput(new TransactionOutput(params, b56txToDuplicate, BigInteger.valueOf(1), new byte[] {}));
|
b56txToDuplicate.addOutput(new TransactionOutput(params, b56txToDuplicate, Coin.valueOf(1), new byte[] {}));
|
||||||
addOnlyInputToTransaction(b56txToDuplicate, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(b56txToDuplicate, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b57.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b57.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b57.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b57.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b57.addTransaction(b56txToDuplicate);
|
b57.addTransaction(b56txToDuplicate);
|
||||||
}
|
}
|
||||||
b57.solve();
|
b57.solve();
|
||||||
@ -1081,7 +1081,7 @@ public class FullBlockTestGenerator {
|
|||||||
Block b58 = createNextBlock(b57, chainHeadHeight + 18, out17, null);
|
Block b58 = createNextBlock(b57, chainHeadHeight + 18, out17, null);
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] {}));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] {}));
|
||||||
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_1},
|
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_1},
|
||||||
new TransactionOutPoint(params, 3, b58.getTransactions().get(1).getHash())));
|
new TransactionOutPoint(params, 3, b58.getTransactions().get(1).getHash())));
|
||||||
b58.addTransaction(tx);
|
b58.addTransaction(tx);
|
||||||
@ -1094,7 +1094,7 @@ public class FullBlockTestGenerator {
|
|||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx,
|
tx.addOutput(new TransactionOutput(params, tx,
|
||||||
b59.getTransactions().get(1).getOutputs().get(2).getValue().add(BigInteger.ONE), new byte[] {}));
|
b59.getTransactions().get(1).getOutputs().get(2).getValue().add(Coin.ONE), new byte[] {}));
|
||||||
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_1},
|
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_1},
|
||||||
new TransactionOutPoint(params, 2, b59.getTransactions().get(1).getHash())));
|
new TransactionOutPoint(params, 2, b59.getTransactions().get(1).getHash())));
|
||||||
b59.addTransaction(tx);
|
b59.addTransaction(tx);
|
||||||
@ -1132,7 +1132,7 @@ public class FullBlockTestGenerator {
|
|||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.setLockTime(0xffffffffL);
|
tx.setLockTime(0xffffffffL);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] {OP_TRUE}));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] {OP_TRUE}));
|
||||||
addOnlyInputToTransaction(tx, out18, 0);
|
addOnlyInputToTransaction(tx, out18, 0);
|
||||||
b62.addTransaction(tx);
|
b62.addTransaction(tx);
|
||||||
Preconditions.checkState(!tx.isFinal(chainHeadHeight + 17, b62.getTimeSeconds()));
|
Preconditions.checkState(!tx.isFinal(chainHeadHeight + 17, b62.getTimeSeconds()));
|
||||||
@ -1164,10 +1164,10 @@ public class FullBlockTestGenerator {
|
|||||||
// Signature size is non-deterministic, so it may take several runs before finding any off-by-one errors
|
// Signature size is non-deterministic, so it may take several runs before finding any off-by-one errors
|
||||||
byte[] outputScript = new byte[Block.MAX_BLOCK_SIZE - b64Created.getMessageSize() - 138];
|
byte[] outputScript = new byte[Block.MAX_BLOCK_SIZE - b64Created.getMessageSize() - 138];
|
||||||
Arrays.fill(outputScript, (byte) OP_FALSE);
|
Arrays.fill(outputScript, (byte) OP_FALSE);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b64Created.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b64Created.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b64Created.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b64Created.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b64Created.addTransaction(tx);
|
b64Created.addTransaction(tx);
|
||||||
b64Created.solve();
|
b64Created.solve();
|
||||||
|
|
||||||
@ -1210,7 +1210,7 @@ public class FullBlockTestGenerator {
|
|||||||
addOnlyInputToTransaction(tx1, out19, 0);
|
addOnlyInputToTransaction(tx1, out19, 0);
|
||||||
b65.addTransaction(tx1);
|
b65.addTransaction(tx1);
|
||||||
Transaction tx2 = new Transaction(params);
|
Transaction tx2 = new Transaction(params);
|
||||||
tx2.addOutput(new TransactionOutput(params, tx2, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
tx2.addOutput(new TransactionOutput(params, tx2, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||||
tx2.addInput(new TransactionInput(params, tx2, new byte[]{OP_TRUE},
|
tx2.addInput(new TransactionInput(params, tx2, new byte[]{OP_TRUE},
|
||||||
new TransactionOutPoint(params, 0, tx1.getHash())));
|
new TransactionOutPoint(params, 0, tx1.getHash())));
|
||||||
b65.addTransaction(tx2);
|
b65.addTransaction(tx2);
|
||||||
@ -1234,7 +1234,7 @@ public class FullBlockTestGenerator {
|
|||||||
tx1.addOutput(new TransactionOutput(params, tx1, out20.value, new byte[]{OP_TRUE}));
|
tx1.addOutput(new TransactionOutput(params, tx1, out20.value, new byte[]{OP_TRUE}));
|
||||||
addOnlyInputToTransaction(tx1, out20, 0);
|
addOnlyInputToTransaction(tx1, out20, 0);
|
||||||
Transaction tx2 = new Transaction(params);
|
Transaction tx2 = new Transaction(params);
|
||||||
tx2.addOutput(new TransactionOutput(params, tx2, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
tx2.addOutput(new TransactionOutput(params, tx2, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||||
tx2.addInput(new TransactionInput(params, tx2, new byte[]{OP_TRUE},
|
tx2.addInput(new TransactionInput(params, tx2, new byte[]{OP_TRUE},
|
||||||
new TransactionOutPoint(params, 0, tx1.getHash())));
|
new TransactionOutPoint(params, 0, tx1.getHash())));
|
||||||
b66.addTransaction(tx2);
|
b66.addTransaction(tx2);
|
||||||
@ -1254,7 +1254,7 @@ public class FullBlockTestGenerator {
|
|||||||
addOnlyInputToTransaction(tx1, out20, 0);
|
addOnlyInputToTransaction(tx1, out20, 0);
|
||||||
b67.addTransaction(tx1);
|
b67.addTransaction(tx1);
|
||||||
Transaction tx2 = new Transaction(params);
|
Transaction tx2 = new Transaction(params);
|
||||||
tx2.addOutput(new TransactionOutput(params, tx2, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
tx2.addOutput(new TransactionOutput(params, tx2, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||||
tx2.addInput(new TransactionInput(params, tx2, new byte[]{OP_TRUE},
|
tx2.addInput(new TransactionInput(params, tx2, new byte[]{OP_TRUE},
|
||||||
new TransactionOutPoint(params, 0, tx1.getHash())));
|
new TransactionOutPoint(params, 0, tx1.getHash())));
|
||||||
b67.addTransaction(tx2);
|
b67.addTransaction(tx2);
|
||||||
@ -1271,20 +1271,20 @@ public class FullBlockTestGenerator {
|
|||||||
// -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20)
|
// -> b43 (13) -> b53 (14) -> b55 (15) -> b57 (16) -> b60 (17) -> b64 (18) -> b65 (19) -> b69 (20)
|
||||||
// \-> b68 (20)
|
// \-> b68 (20)
|
||||||
//
|
//
|
||||||
Block b68 = createNextBlock(b65, chainHeadHeight + 21, null, BigInteger.TEN);
|
Block b68 = createNextBlock(b65, chainHeadHeight + 21, null, Coin.TEN);
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, out20.value.subtract(BigInteger.valueOf(9)), new byte[]{OP_TRUE}));
|
tx.addOutput(new TransactionOutput(params, tx, out20.value.subtract(Coin.valueOf(9)), new byte[]{OP_TRUE}));
|
||||||
addOnlyInputToTransaction(tx, out20, 0);
|
addOnlyInputToTransaction(tx, out20, 0);
|
||||||
b68.addTransaction(tx);
|
b68.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b68.solve();
|
b68.solve();
|
||||||
blocks.add(new BlockAndValidity(blockToHeightMap, b68, false, true, b65.getHash(), chainHeadHeight + 20, "b68"));
|
blocks.add(new BlockAndValidity(blockToHeightMap, b68, false, true, b65.getHash(), chainHeadHeight + 20, "b68"));
|
||||||
|
|
||||||
Block b69 = createNextBlock(b65, chainHeadHeight + 21, null, BigInteger.TEN);
|
Block b69 = createNextBlock(b65, chainHeadHeight + 21, null, Coin.TEN);
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, out20.value.subtract(BigInteger.TEN), new byte[]{OP_TRUE}));
|
tx.addOutput(new TransactionOutput(params, tx, out20.value.subtract(Coin.TEN), new byte[]{OP_TRUE}));
|
||||||
addOnlyInputToTransaction(tx, out20, 0);
|
addOnlyInputToTransaction(tx, out20, 0);
|
||||||
b69.addTransaction(tx);
|
b69.addTransaction(tx);
|
||||||
}
|
}
|
||||||
@ -1304,7 +1304,7 @@ public class FullBlockTestGenerator {
|
|||||||
Block b70 = createNextBlock(b69, chainHeadHeight + 22, out21, null);
|
Block b70 = createNextBlock(b69, chainHeadHeight + 22, out21, null);
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||||
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_TRUE},
|
tx.addInput(new TransactionInput(params, tx, new byte[]{OP_TRUE},
|
||||||
new TransactionOutPoint(params, 0, new Sha256Hash("23c70ed7c0506e9178fc1a987f40a33946d4ad4c962b5ae3a52546da53af0c5c"))));
|
new TransactionOutPoint(params, 0, new Sha256Hash("23c70ed7c0506e9178fc1a987f40a33946d4ad4c962b5ae3a52546da53af0c5c"))));
|
||||||
b70.addTransaction(tx);
|
b70.addTransaction(tx);
|
||||||
@ -1319,10 +1319,10 @@ public class FullBlockTestGenerator {
|
|||||||
Block b72 = createNextBlock(b69, chainHeadHeight + 22, out21, null);
|
Block b72 = createNextBlock(b69, chainHeadHeight + 22, out21, null);
|
||||||
{
|
{
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b72.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b72.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b72.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b72.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b72.addTransaction(tx);
|
b72.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b72.solve();
|
b72.solve();
|
||||||
@ -1356,10 +1356,10 @@ public class FullBlockTestGenerator {
|
|||||||
// If we push an element that is too large, the CHECKSIGs after that push are still counted
|
// If we push an element that is too large, the CHECKSIGs after that push are still counted
|
||||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps] = OP_PUSHDATA4;
|
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps] = OP_PUSHDATA4;
|
||||||
Utils.uint32ToByteArrayLE(Script.MAX_SCRIPT_ELEMENT_SIZE + 1, outputScript, Block.MAX_BLOCK_SIGOPS - sigOps + 1);
|
Utils.uint32ToByteArrayLE(Script.MAX_SCRIPT_ELEMENT_SIZE + 1, outputScript, Block.MAX_BLOCK_SIGOPS - sigOps + 1);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b73.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b73.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b73.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b73.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b73.addTransaction(tx);
|
b73.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b73.solve();
|
b73.solve();
|
||||||
@ -1380,10 +1380,10 @@ public class FullBlockTestGenerator {
|
|||||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 3] = (byte)0xff;
|
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 3] = (byte)0xff;
|
||||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 4] = (byte)0xff;
|
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 4] = (byte)0xff;
|
||||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 5] = (byte)0xff;
|
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 5] = (byte)0xff;
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b74.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b74.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b74.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b74.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b74.addTransaction(tx);
|
b74.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b74.solve();
|
b74.solve();
|
||||||
@ -1404,10 +1404,10 @@ public class FullBlockTestGenerator {
|
|||||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 2] = (byte)0xff;
|
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 2] = (byte)0xff;
|
||||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 3] = (byte)0xff;
|
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 3] = (byte)0xff;
|
||||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 4] = (byte)0xff;
|
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps + 4] = (byte)0xff;
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b75.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b75.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b75.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b75.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b75.addTransaction(tx);
|
b75.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b75.solve();
|
b75.solve();
|
||||||
@ -1431,10 +1431,10 @@ public class FullBlockTestGenerator {
|
|||||||
// If we push an element that is filled with CHECKSIGs, they (obviously) arent counted
|
// If we push an element that is filled with CHECKSIGs, they (obviously) arent counted
|
||||||
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps] = OP_PUSHDATA4;
|
outputScript[Block.MAX_BLOCK_SIGOPS - sigOps] = OP_PUSHDATA4;
|
||||||
Utils.uint32ToByteArrayLE(Block.MAX_BLOCK_SIGOPS, outputScript, Block.MAX_BLOCK_SIGOPS - sigOps + 1);
|
Utils.uint32ToByteArrayLE(Block.MAX_BLOCK_SIGOPS, outputScript, Block.MAX_BLOCK_SIGOPS - sigOps + 1);
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.valueOf(1), outputScript));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.valueOf(1), outputScript));
|
||||||
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b76.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b76.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b76.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b76.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b76.addTransaction(tx);
|
b76.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b76.solve();
|
b76.solve();
|
||||||
@ -1460,10 +1460,10 @@ public class FullBlockTestGenerator {
|
|||||||
Block b78 = createNextBlock(b77, chainHeadHeight + 26, out25, null);
|
Block b78 = createNextBlock(b77, chainHeadHeight + 26, out25, null);
|
||||||
Transaction b78tx = new Transaction(params);
|
Transaction b78tx = new Transaction(params);
|
||||||
{
|
{
|
||||||
b78tx.addOutput(new TransactionOutput(params, b78tx, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
b78tx.addOutput(new TransactionOutput(params, b78tx, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||||
addOnlyInputToTransaction(b78tx, new TransactionOutPointWithValue(
|
addOnlyInputToTransaction(b78tx, new TransactionOutPointWithValue(
|
||||||
new TransactionOutPoint(params, 1, b77.getTransactions().get(1).getHash()),
|
new TransactionOutPoint(params, 1, b77.getTransactions().get(1).getHash()),
|
||||||
BigInteger.valueOf(1), b77.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
Coin.valueOf(1), b77.getTransactions().get(1).getOutputs().get(1).getScriptPubKey()));
|
||||||
b78.addTransaction(b78tx);
|
b78.addTransaction(b78tx);
|
||||||
}
|
}
|
||||||
b78.solve();
|
b78.solve();
|
||||||
@ -1472,7 +1472,7 @@ public class FullBlockTestGenerator {
|
|||||||
Block b79 = createNextBlock(b78, chainHeadHeight + 27, out26, null);
|
Block b79 = createNextBlock(b78, chainHeadHeight + 27, out26, null);
|
||||||
Transaction b79tx = new Transaction(params);
|
Transaction b79tx = new Transaction(params);
|
||||||
{
|
{
|
||||||
b79tx.addOutput(new TransactionOutput(params, b79tx, BigInteger.ZERO, new byte[]{OP_TRUE}));
|
b79tx.addOutput(new TransactionOutput(params, b79tx, Coin.ZERO, new byte[]{OP_TRUE}));
|
||||||
b79tx.addInput(new TransactionInput(params, b79tx, new byte[]{OP_TRUE}, new TransactionOutPoint(params, 0, b78tx.getHash())));
|
b79tx.addInput(new TransactionInput(params, b79tx, new byte[]{OP_TRUE}, new TransactionOutPoint(params, 0, b78tx.getHash())));
|
||||||
b79.addTransaction(b79tx);
|
b79.addTransaction(b79tx);
|
||||||
}
|
}
|
||||||
@ -1541,8 +1541,8 @@ public class FullBlockTestGenerator {
|
|||||||
while (block.getMessageSize() < Block.MAX_BLOCK_SIZE - 500) {
|
while (block.getMessageSize() < Block.MAX_BLOCK_SIZE - 500) {
|
||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addInput(new TransactionInput(params, tx, new byte[] { OP_TRUE }, lastOutput));
|
tx.addInput(new TransactionInput(params, tx, new byte[] { OP_TRUE }, lastOutput));
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] { OP_TRUE }));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] { OP_TRUE }));
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] { OP_TRUE }));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] { OP_TRUE }));
|
||||||
lastOutput = new TransactionOutPoint(params, 1, tx.getHash());
|
lastOutput = new TransactionOutPoint(params, 1, tx.getHash());
|
||||||
hashesToSpend.add(tx.getHash());
|
hashesToSpend.add(tx.getHash());
|
||||||
block.addTransaction(tx);
|
block.addTransaction(tx);
|
||||||
@ -1560,7 +1560,7 @@ public class FullBlockTestGenerator {
|
|||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addInput(new TransactionInput(params, tx, new byte[] { OP_TRUE },
|
tx.addInput(new TransactionInput(params, tx, new byte[] { OP_TRUE },
|
||||||
new TransactionOutPoint(params, 0, hashes.next())));
|
new TransactionOutPoint(params, 0, hashes.next())));
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] { OP_TRUE }));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] { OP_TRUE }));
|
||||||
block.addTransaction(tx);
|
block.addTransaction(tx);
|
||||||
}
|
}
|
||||||
block.solve();
|
block.solve();
|
||||||
@ -1586,7 +1586,7 @@ public class FullBlockTestGenerator {
|
|||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_TRUE},
|
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_TRUE},
|
||||||
new TransactionOutPoint(params, 0, hashesToSpend.get(0))));
|
new TransactionOutPoint(params, 0, hashesToSpend.get(0))));
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] { OP_TRUE }));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] { OP_TRUE }));
|
||||||
b1002.addTransaction(tx);
|
b1002.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b1002.solve();
|
b1002.solve();
|
||||||
@ -1602,7 +1602,7 @@ public class FullBlockTestGenerator {
|
|||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_TRUE},
|
tx.addInput(new TransactionInput(params, tx, new byte[] {OP_TRUE},
|
||||||
new TransactionOutPoint(params, 0, hashesToSpend.get(0))));
|
new TransactionOutPoint(params, 0, hashesToSpend.get(0))));
|
||||||
tx.addOutput(new TransactionOutput(params, tx, BigInteger.ZERO, new byte[] { OP_TRUE }));
|
tx.addOutput(new TransactionOutput(params, tx, Coin.ZERO, new byte[] { OP_TRUE }));
|
||||||
b1004.addTransaction(tx);
|
b1004.addTransaction(tx);
|
||||||
}
|
}
|
||||||
b1004.solve();
|
b1004.solve();
|
||||||
@ -1620,22 +1620,22 @@ public class FullBlockTestGenerator {
|
|||||||
|
|
||||||
private byte uniquenessCounter = 0;
|
private byte uniquenessCounter = 0;
|
||||||
private Block createNextBlock(Block baseBlock, int nextBlockHeight, TransactionOutPointWithValue prevOut,
|
private Block createNextBlock(Block baseBlock, int nextBlockHeight, TransactionOutPointWithValue prevOut,
|
||||||
BigInteger additionalCoinbaseValue) throws ScriptException {
|
Coin additionalCoinbaseValue) throws ScriptException {
|
||||||
Integer height = blockToHeightMap.get(baseBlock.getHash());
|
Integer height = blockToHeightMap.get(baseBlock.getHash());
|
||||||
if (height != null)
|
if (height != null)
|
||||||
Preconditions.checkState(height == nextBlockHeight - 1);
|
Preconditions.checkState(height == nextBlockHeight - 1);
|
||||||
BigInteger coinbaseValue = Utils.toNanoCoins(50, 0).shiftRight(nextBlockHeight / params.getSubsidyDecreaseBlockCount())
|
Coin coinbaseValue = Utils.toNanoCoins(50, 0).shiftRight(nextBlockHeight / params.getSubsidyDecreaseBlockCount())
|
||||||
.add((prevOut != null ? prevOut.value.subtract(BigInteger.ONE) : BigInteger.ZERO))
|
.add((prevOut != null ? prevOut.value.subtract(Coin.ONE) : Coin.ZERO))
|
||||||
.add(additionalCoinbaseValue == null ? BigInteger.ZERO : additionalCoinbaseValue);
|
.add(additionalCoinbaseValue == null ? Coin.ZERO : additionalCoinbaseValue);
|
||||||
Block block = baseBlock.createNextBlockWithCoinbase(coinbaseOutKeyPubKey, coinbaseValue);
|
Block block = baseBlock.createNextBlockWithCoinbase(coinbaseOutKeyPubKey, coinbaseValue);
|
||||||
if (prevOut != null) {
|
if (prevOut != null) {
|
||||||
Transaction t = new Transaction(params);
|
Transaction t = new Transaction(params);
|
||||||
// Entirely invalid scriptPubKey to ensure we aren't pre-verifying too much
|
// Entirely invalid scriptPubKey to ensure we aren't pre-verifying too much
|
||||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(0), new byte[] {OP_PUSHDATA1 - 1 }));
|
||||||
t.addOutput(new TransactionOutput(params, t, BigInteger.valueOf(1),
|
t.addOutput(new TransactionOutput(params, t, Coin.valueOf(1),
|
||||||
ScriptBuilder.createOutputScript(ECKey.fromPublicOnly(coinbaseOutKeyPubKey)).getProgram()));
|
ScriptBuilder.createOutputScript(ECKey.fromPublicOnly(coinbaseOutKeyPubKey)).getProgram()));
|
||||||
// Spendable output
|
// Spendable output
|
||||||
t.addOutput(new TransactionOutput(params, t, BigInteger.ZERO, new byte[] {OP_1, uniquenessCounter++}));
|
t.addOutput(new TransactionOutput(params, t, Coin.ZERO, new byte[] {OP_1, uniquenessCounter++}));
|
||||||
addOnlyInputToTransaction(t, prevOut);
|
addOnlyInputToTransaction(t, prevOut);
|
||||||
block.addTransaction(t);
|
block.addTransaction(t);
|
||||||
block.solve();
|
block.solve();
|
||||||
|
@ -34,7 +34,6 @@ import org.junit.Test;
|
|||||||
import org.junit.runner.RunWith;
|
import org.junit.runner.RunWith;
|
||||||
import org.junit.runners.Parameterized;
|
import org.junit.runners.Parameterized;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
@ -179,7 +178,7 @@ public class PeerGroupTest extends TestWithPeerGroup {
|
|||||||
expectedPeers.add(peerOf(p2));
|
expectedPeers.add(peerOf(p2));
|
||||||
assertEquals(tmp, expectedPeers);
|
assertEquals(tmp, expectedPeers);
|
||||||
|
|
||||||
BigInteger value = Utils.toNanoCoins(1, 0);
|
Coin value = Utils.toNanoCoins(1, 0);
|
||||||
Transaction t1 = FakeTxBuilder.createFakeTx(unitTestParams, value, address);
|
Transaction t1 = FakeTxBuilder.createFakeTx(unitTestParams, value, address);
|
||||||
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
||||||
inv.addTransaction(t1);
|
inv.addTransaction(t1);
|
||||||
|
@ -34,7 +34,6 @@ import org.junit.runners.Parameterized;
|
|||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketException;
|
import java.net.SocketException;
|
||||||
import java.nio.channels.CancelledKeyException;
|
import java.nio.channels.CancelledKeyException;
|
||||||
@ -245,7 +244,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
|||||||
|
|
||||||
peer.setDownloadData(true);
|
peer.setDownloadData(true);
|
||||||
// Make a transaction and tell the peer we have it.
|
// Make a transaction and tell the peer we have it.
|
||||||
BigInteger value = Utils.toNanoCoins(1, 0);
|
Coin value = Utils.toNanoCoins(1, 0);
|
||||||
Transaction tx = createFakeTx(unitTestParams, value, address);
|
Transaction tx = createFakeTx(unitTestParams, value, address);
|
||||||
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
||||||
InventoryItem item = new InventoryItem(InventoryItem.Type.Transaction, tx.getHash());
|
InventoryItem item = new InventoryItem(InventoryItem.Type.Transaction, tx.getHash());
|
||||||
@ -278,7 +277,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
|||||||
InboundMessageQueuer writeTarget2 = connect(peer2, peerVersion);
|
InboundMessageQueuer writeTarget2 = connect(peer2, peerVersion);
|
||||||
|
|
||||||
// Make a tx and advertise it to one of the peers.
|
// Make a tx and advertise it to one of the peers.
|
||||||
BigInteger value = Utils.toNanoCoins(1, 0);
|
Coin value = Utils.toNanoCoins(1, 0);
|
||||||
Transaction tx = createFakeTx(unitTestParams, value, this.address);
|
Transaction tx = createFakeTx(unitTestParams, value, this.address);
|
||||||
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
InventoryMessage inv = new InventoryMessage(unitTestParams);
|
||||||
InventoryItem item = new InventoryItem(InventoryItem.Type.Transaction, tx.getHash());
|
InventoryItem item = new InventoryItem(InventoryItem.Type.Transaction, tx.getHash());
|
||||||
@ -418,7 +417,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
|||||||
Block b2 = makeSolvedTestBlock(b1);
|
Block b2 = makeSolvedTestBlock(b1);
|
||||||
Transaction t = new Transaction(unitTestParams);
|
Transaction t = new Transaction(unitTestParams);
|
||||||
t.addInput(b1.getTransactions().get(0).getOutput(0));
|
t.addInput(b1.getTransactions().get(0).getOutput(0));
|
||||||
t.addOutput(new TransactionOutput(unitTestParams, t, BigInteger.ZERO, new byte[Block.MAX_BLOCK_SIZE - 1000]));
|
t.addOutput(new TransactionOutput(unitTestParams, t, Coin.ZERO, new byte[Block.MAX_BLOCK_SIZE - 1000]));
|
||||||
b2.addTransaction(t);
|
b2.addTransaction(t);
|
||||||
|
|
||||||
// Request the block.
|
// Request the block.
|
||||||
@ -659,7 +658,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
|||||||
final Transaction[] vtx = new Transaction[1];
|
final Transaction[] vtx = new Transaction[1];
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
vtx[0] = tx;
|
vtx[0] = tx;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -732,7 +731,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
|||||||
final Transaction[] vtx = new Transaction[1];
|
final Transaction[] vtx = new Transaction[1];
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
vtx[0] = tx;
|
vtx[0] = tx;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -817,7 +816,7 @@ public class PeerTest extends TestWithNetworkConnections {
|
|||||||
public void exceptionListener() throws Exception {
|
public void exceptionListener() throws Exception {
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
throw new NullPointerException("boo!");
|
throw new NullPointerException("boo!");
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -16,11 +16,10 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.core;
|
package com.google.bitcoin.core;
|
||||||
|
|
||||||
|
import java.math.BigInteger;
|
||||||
import org.junit.Assert;
|
import org.junit.Assert;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import static com.google.bitcoin.core.Utils.*;
|
import static com.google.bitcoin.core.Utils.*;
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
|
|
||||||
@ -59,7 +58,7 @@ public class UtilsTest {
|
|||||||
public void testFormatting() {
|
public void testFormatting() {
|
||||||
assertEquals("1.00", bitcoinValueToFriendlyString(toNanoCoins(1, 0)));
|
assertEquals("1.00", bitcoinValueToFriendlyString(toNanoCoins(1, 0)));
|
||||||
assertEquals("1.23", bitcoinValueToFriendlyString(toNanoCoins(1, 23)));
|
assertEquals("1.23", bitcoinValueToFriendlyString(toNanoCoins(1, 23)));
|
||||||
assertEquals("0.001", bitcoinValueToFriendlyString(BigInteger.valueOf(COIN.longValue() / 1000)));
|
assertEquals("0.001", bitcoinValueToFriendlyString(Coin.valueOf(COIN.longValue() / 1000)));
|
||||||
assertEquals("-1.23", bitcoinValueToFriendlyString(toNanoCoins(1, 23).negate()));
|
assertEquals("-1.23", bitcoinValueToFriendlyString(toNanoCoins(1, 23).negate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,7 +75,7 @@ public class UtilsTest {
|
|||||||
assertTrue(e.getMessage().contains("Value cannot be null"));
|
assertTrue(e.getMessage().contains("Value cannot be null"));
|
||||||
}
|
}
|
||||||
|
|
||||||
assertEquals("0.0015", bitcoinValueToPlainString(BigInteger.valueOf(150000)));
|
assertEquals("0.0015", bitcoinValueToPlainString(Coin.valueOf(150000)));
|
||||||
assertEquals("1.23", bitcoinValueToPlainString(toNanoCoins("1.23")));
|
assertEquals("1.23", bitcoinValueToPlainString(toNanoCoins("1.23")));
|
||||||
|
|
||||||
assertEquals("0.1", bitcoinValueToPlainString(toNanoCoins("0.1")));
|
assertEquals("0.1", bitcoinValueToPlainString(toNanoCoins("0.1")));
|
||||||
|
@ -152,7 +152,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
private Transaction cleanupCommon(Address destination) throws Exception {
|
private Transaction cleanupCommon(Address destination) throws Exception {
|
||||||
receiveATransaction(wallet, myAddress);
|
receiveATransaction(wallet, myAddress);
|
||||||
|
|
||||||
BigInteger v2 = toNanoCoins(0, 50);
|
Coin v2 = toNanoCoins(0, 50);
|
||||||
SendRequest req = SendRequest.to(destination, v2);
|
SendRequest req = SendRequest.to(destination, v2);
|
||||||
req.fee = toNanoCoins(0, 1);
|
req.fee = toNanoCoins(0, 1);
|
||||||
wallet.completeTx(req);
|
wallet.completeTx(req);
|
||||||
@ -164,7 +164,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
// At this point we have one pending and one spent
|
// At this point we have one pending and one spent
|
||||||
|
|
||||||
BigInteger v1 = toNanoCoins(0, 10);
|
Coin v1 = toNanoCoins(0, 10);
|
||||||
Transaction t = sendMoneyToWallet(wallet, v1, myAddress, null);
|
Transaction t = sendMoneyToWallet(wallet, v1, myAddress, null);
|
||||||
Threading.waitForUserCode();
|
Threading.waitForUserCode();
|
||||||
sendMoneyToWallet(wallet, t, null);
|
sendMoneyToWallet(wallet, t, null);
|
||||||
@ -199,7 +199,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Transaction t = cleanupCommon(destination);
|
Transaction t = cleanupCommon(destination);
|
||||||
|
|
||||||
// Now we have another incoming pending. Spend everything.
|
// Now we have another incoming pending. Spend everything.
|
||||||
BigInteger v3 = toNanoCoins(0, 58);
|
Coin v3 = toNanoCoins(0, 58);
|
||||||
SendRequest req = SendRequest.to(destination, v3);
|
SendRequest req = SendRequest.to(destination, v3);
|
||||||
|
|
||||||
// Force selection of the incoming coin so that we can spend it
|
// Force selection of the incoming coin so that we can spend it
|
||||||
@ -235,7 +235,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
receiveATransaction(wallet, toAddress);
|
receiveATransaction(wallet, toAddress);
|
||||||
|
|
||||||
// Try to send too much and fail.
|
// Try to send too much and fail.
|
||||||
BigInteger vHuge = toNanoCoins(10, 0);
|
Coin vHuge = toNanoCoins(10, 0);
|
||||||
Wallet.SendRequest req = Wallet.SendRequest.to(destination, vHuge);
|
Wallet.SendRequest req = Wallet.SendRequest.to(destination, vHuge);
|
||||||
try {
|
try {
|
||||||
wallet.completeTx(req);
|
wallet.completeTx(req);
|
||||||
@ -245,7 +245,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Prepare to send.
|
// Prepare to send.
|
||||||
BigInteger v2 = toNanoCoins(0, 50);
|
Coin v2 = toNanoCoins(0, 50);
|
||||||
req = Wallet.SendRequest.to(destination, v2);
|
req = Wallet.SendRequest.to(destination, v2);
|
||||||
req.fee = toNanoCoins(0, 1);
|
req.fee = toNanoCoins(0, 1);
|
||||||
|
|
||||||
@ -306,9 +306,9 @@ public class WalletTest extends TestWithWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void receiveATransaction(Wallet wallet, Address toAddress) throws Exception {
|
private void receiveATransaction(Wallet wallet, Address toAddress) throws Exception {
|
||||||
BigInteger v1 = Utils.toNanoCoins(1, 0);
|
Coin v1 = Utils.toNanoCoins(1, 0);
|
||||||
final ListenableFuture<BigInteger> availFuture = wallet.getBalanceFuture(v1, Wallet.BalanceType.AVAILABLE);
|
final ListenableFuture<Coin> availFuture = wallet.getBalanceFuture(v1, Wallet.BalanceType.AVAILABLE);
|
||||||
final ListenableFuture<BigInteger> estimatedFuture = wallet.getBalanceFuture(v1, Wallet.BalanceType.ESTIMATED);
|
final ListenableFuture<Coin> estimatedFuture = wallet.getBalanceFuture(v1, Wallet.BalanceType.ESTIMATED);
|
||||||
assertFalse(availFuture.isDone());
|
assertFalse(availFuture.isDone());
|
||||||
assertFalse(estimatedFuture.isDone());
|
assertFalse(estimatedFuture.isDone());
|
||||||
// Send some pending coins to the wallet.
|
// Send some pending coins to the wallet.
|
||||||
@ -316,7 +316,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Threading.waitForUserCode();
|
Threading.waitForUserCode();
|
||||||
final ListenableFuture<Transaction> depthFuture = t1.getConfidence().getDepthFuture(1);
|
final ListenableFuture<Transaction> depthFuture = t1.getConfidence().getDepthFuture(1);
|
||||||
assertFalse(depthFuture.isDone());
|
assertFalse(depthFuture.isDone());
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(v1, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
assertEquals(v1, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||||
assertFalse(availFuture.isDone());
|
assertFalse(availFuture.isDone());
|
||||||
// Our estimated balance has reached the requested level.
|
// Our estimated balance has reached the requested level.
|
||||||
@ -352,7 +352,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
final LinkedList<Transaction> txns = Lists.newLinkedList();
|
final LinkedList<Transaction> txns = Lists.newLinkedList();
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
txns.add(tx);
|
txns.add(tx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -369,7 +369,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void spendUnconfirmedChange(Wallet wallet, Transaction t2, KeyParameter aesKey) throws Exception {
|
private void spendUnconfirmedChange(Wallet wallet, Transaction t2, KeyParameter aesKey) throws Exception {
|
||||||
BigInteger v3 = toNanoCoins(0, 49);
|
Coin v3 = toNanoCoins(0, 49);
|
||||||
assertEquals(v3, wallet.getBalance());
|
assertEquals(v3, wallet.getBalance());
|
||||||
Wallet.SendRequest req = Wallet.SendRequest.to(new ECKey().toAddress(params), toNanoCoins(0, 48));
|
Wallet.SendRequest req = Wallet.SendRequest.to(new ECKey().toAddress(params), toNanoCoins(0, 48));
|
||||||
req.aesKey = aesKey;
|
req.aesKey = aesKey;
|
||||||
@ -395,7 +395,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Having a test for deprecated method getFromAddress() is no evil so we suppress the warning here.
|
// Having a test for deprecated method getFromAddress() is no evil so we suppress the warning here.
|
||||||
public void customTransactionSpending() throws Exception {
|
public void customTransactionSpending() throws Exception {
|
||||||
// We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
|
// We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
|
||||||
BigInteger v1 = Utils.toNanoCoins(3, 0);
|
Coin v1 = Utils.toNanoCoins(3, 0);
|
||||||
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
assertEquals(v1, wallet.getBalance());
|
assertEquals(v1, wallet.getBalance());
|
||||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||||
@ -403,9 +403,9 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
ECKey k2 = new ECKey();
|
ECKey k2 = new ECKey();
|
||||||
Address a2 = k2.toAddress(params);
|
Address a2 = k2.toAddress(params);
|
||||||
BigInteger v2 = toNanoCoins(0, 50);
|
Coin v2 = toNanoCoins(0, 50);
|
||||||
BigInteger v3 = toNanoCoins(0, 75);
|
Coin v3 = toNanoCoins(0, 75);
|
||||||
BigInteger v4 = toNanoCoins(1, 25);
|
Coin v4 = toNanoCoins(1, 25);
|
||||||
|
|
||||||
Transaction t2 = new Transaction(params);
|
Transaction t2 = new Transaction(params);
|
||||||
t2.addOutput(v2, a2);
|
t2.addOutput(v2, a2);
|
||||||
@ -431,13 +431,13 @@ public class WalletTest extends TestWithWallet {
|
|||||||
public void sideChain() throws Exception {
|
public void sideChain() throws Exception {
|
||||||
// The wallet receives a coin on the main chain, then on a side chain. Balance is equal to both added together
|
// The wallet receives a coin on the main chain, then on a side chain. Balance is equal to both added together
|
||||||
// as we assume the side chain tx is pending and will be included shortly.
|
// as we assume the side chain tx is pending and will be included shortly.
|
||||||
BigInteger v1 = Utils.toNanoCoins(1, 0);
|
Coin v1 = Utils.toNanoCoins(1, 0);
|
||||||
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
assertEquals(v1, wallet.getBalance());
|
assertEquals(v1, wallet.getBalance());
|
||||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||||
assertEquals(1, wallet.getTransactions(true).size());
|
assertEquals(1, wallet.getTransactions(true).size());
|
||||||
|
|
||||||
BigInteger v2 = toNanoCoins(0, 50);
|
Coin v2 = toNanoCoins(0, 50);
|
||||||
sendMoneyToWallet(v2, AbstractBlockChain.NewBlockType.SIDE_CHAIN);
|
sendMoneyToWallet(v2, AbstractBlockChain.NewBlockType.SIDE_CHAIN);
|
||||||
assertEquals(2, wallet.getTransactions(true).size());
|
assertEquals(2, wallet.getTransactions(true).size());
|
||||||
assertEquals(v1, wallet.getBalance());
|
assertEquals(v1, wallet.getBalance());
|
||||||
@ -447,9 +447,9 @@ public class WalletTest extends TestWithWallet {
|
|||||||
@Test
|
@Test
|
||||||
public void balance() throws Exception {
|
public void balance() throws Exception {
|
||||||
// Receive 5 coins then half a coin.
|
// Receive 5 coins then half a coin.
|
||||||
BigInteger v1 = toNanoCoins(5, 0);
|
Coin v1 = toNanoCoins(5, 0);
|
||||||
BigInteger v2 = toNanoCoins(0, 50);
|
Coin v2 = toNanoCoins(0, 50);
|
||||||
BigInteger expected = toNanoCoins(5, 50);
|
Coin expected = toNanoCoins(5, 50);
|
||||||
assertEquals(0, wallet.getTransactions(true).size());
|
assertEquals(0, wallet.getTransactions(true).size());
|
||||||
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||||
@ -458,7 +458,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
assertEquals(expected, wallet.getBalance());
|
assertEquals(expected, wallet.getBalance());
|
||||||
|
|
||||||
// Now spend one coin.
|
// Now spend one coin.
|
||||||
BigInteger v3 = toNanoCoins(1, 0);
|
Coin v3 = toNanoCoins(1, 0);
|
||||||
Transaction spend = wallet.createSend(new ECKey().toAddress(params), v3);
|
Transaction spend = wallet.createSend(new ECKey().toAddress(params), v3);
|
||||||
wallet.commitTx(spend);
|
wallet.commitTx(spend);
|
||||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
|
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.PENDING));
|
||||||
@ -474,7 +474,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
wallet.receiveFromBlock(spend, b3, BlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(spend, b3, BlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
|
|
||||||
// Change is confirmed. We started with 5.50 so we should have 4.50 left.
|
// Change is confirmed. We started with 5.50 so we should have 4.50 left.
|
||||||
BigInteger v4 = toNanoCoins(4, 50);
|
Coin v4 = toNanoCoins(4, 50);
|
||||||
assertEquals(v4, wallet.getBalance(Wallet.BalanceType.AVAILABLE));
|
assertEquals(v4, wallet.getBalance(Wallet.BalanceType.AVAILABLE));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -486,12 +486,12 @@ public class WalletTest extends TestWithWallet {
|
|||||||
@Test
|
@Test
|
||||||
public void blockChainCatchup() throws Exception {
|
public void blockChainCatchup() throws Exception {
|
||||||
// Test that we correctly process transactions arriving from the chain, with callbacks for inbound and outbound.
|
// Test that we correctly process transactions arriving from the chain, with callbacks for inbound and outbound.
|
||||||
final BigInteger bigints[] = new BigInteger[4];
|
final Coin bigints[] = new Coin[4];
|
||||||
final Transaction txn[] = new Transaction[2];
|
final Transaction txn[] = new Transaction[2];
|
||||||
final LinkedList<Transaction> confTxns = new LinkedList<Transaction>();
|
final LinkedList<Transaction> confTxns = new LinkedList<Transaction>();
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
super.onCoinsReceived(wallet, tx, prevBalance, newBalance);
|
super.onCoinsReceived(wallet, tx, prevBalance, newBalance);
|
||||||
bigints[0] = prevBalance;
|
bigints[0] = prevBalance;
|
||||||
bigints[1] = newBalance;
|
bigints[1] = newBalance;
|
||||||
@ -499,7 +499,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
super.onCoinsSent(wallet, tx, prevBalance, newBalance);
|
super.onCoinsSent(wallet, tx, prevBalance, newBalance);
|
||||||
bigints[2] = prevBalance;
|
bigints[2] = prevBalance;
|
||||||
bigints[3] = newBalance;
|
bigints[3] = newBalance;
|
||||||
@ -514,13 +514,13 @@ public class WalletTest extends TestWithWallet {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Receive some money.
|
// Receive some money.
|
||||||
BigInteger oneCoin = Utils.toNanoCoins(1, 0);
|
Coin oneCoin = Utils.toNanoCoins(1, 0);
|
||||||
Transaction tx1 = sendMoneyToWallet(oneCoin, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
Transaction tx1 = sendMoneyToWallet(oneCoin, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
Threading.waitForUserCode();
|
Threading.waitForUserCode();
|
||||||
assertEquals(null, txn[1]); // onCoinsSent not called.
|
assertEquals(null, txn[1]); // onCoinsSent not called.
|
||||||
assertEquals(tx1, confTxns.getFirst()); // onTransactionConfidenceChanged called
|
assertEquals(tx1, confTxns.getFirst()); // onTransactionConfidenceChanged called
|
||||||
assertEquals(txn[0].getHash(), tx1.getHash());
|
assertEquals(txn[0].getHash(), tx1.getHash());
|
||||||
assertEquals(BigInteger.ZERO, bigints[0]);
|
assertEquals(Coin.ZERO, bigints[0]);
|
||||||
assertEquals(oneCoin, bigints[1]);
|
assertEquals(oneCoin, bigints[1]);
|
||||||
assertEquals(TransactionConfidence.ConfidenceType.BUILDING, tx1.getConfidence().getConfidenceType());
|
assertEquals(TransactionConfidence.ConfidenceType.BUILDING, tx1.getConfidence().getConfidenceType());
|
||||||
assertEquals(1, tx1.getConfidence().getAppearedAtChainHeight());
|
assertEquals(1, tx1.getConfidence().getAppearedAtChainHeight());
|
||||||
@ -555,7 +555,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void balances() throws Exception {
|
public void balances() throws Exception {
|
||||||
BigInteger nanos = Utils.toNanoCoins(1, 0);
|
Coin nanos = Utils.toNanoCoins(1, 0);
|
||||||
Transaction tx1 = sendMoneyToWallet(nanos, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
Transaction tx1 = sendMoneyToWallet(nanos, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
assertEquals(nanos, tx1.getValueSentToMe(wallet, true));
|
assertEquals(nanos, tx1.getValueSentToMe(wallet, true));
|
||||||
// Send 0.10 to somebody else.
|
// Send 0.10 to somebody else.
|
||||||
@ -563,7 +563,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Reserialize.
|
// Reserialize.
|
||||||
Transaction send2 = new Transaction(params, send1.bitcoinSerialize());
|
Transaction send2 = new Transaction(params, send1.bitcoinSerialize());
|
||||||
assertEquals(nanos, send2.getValueSentFromMe(wallet));
|
assertEquals(nanos, send2.getValueSentFromMe(wallet));
|
||||||
assertEquals(BigInteger.ZERO.subtract(toNanoCoins(0, 10)), send2.getValue(wallet));
|
assertEquals(Coin.ZERO.subtract(toNanoCoins(0, 10)), send2.getValue(wallet));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -640,11 +640,11 @@ public class WalletTest extends TestWithWallet {
|
|||||||
public void bounce() throws Exception {
|
public void bounce() throws Exception {
|
||||||
// This test covers bug 64 (False double spends). Check that if we create a spend and it's immediately sent
|
// This test covers bug 64 (False double spends). Check that if we create a spend and it's immediately sent
|
||||||
// back to us, this isn't considered as a double spend.
|
// back to us, this isn't considered as a double spend.
|
||||||
BigInteger coin1 = Utils.toNanoCoins(1, 0);
|
Coin coin1 = Utils.toNanoCoins(1, 0);
|
||||||
sendMoneyToWallet(coin1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(coin1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
// Send half to some other guy. Sending only half then waiting for a confirm is important to ensure the tx is
|
// Send half to some other guy. Sending only half then waiting for a confirm is important to ensure the tx is
|
||||||
// in the unspent pool, not pending or spent.
|
// in the unspent pool, not pending or spent.
|
||||||
BigInteger coinHalf = Utils.toNanoCoins(0, 50);
|
Coin coinHalf = Utils.toNanoCoins(0, 50);
|
||||||
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
assertEquals(1, wallet.getPoolSize(WalletTransaction.Pool.UNSPENT));
|
||||||
assertEquals(1, wallet.getTransactions(true).size());
|
assertEquals(1, wallet.getTransactions(true).size());
|
||||||
Address someOtherGuy = new ECKey().toAddress(params);
|
Address someOtherGuy = new ECKey().toAddress(params);
|
||||||
@ -675,7 +675,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
send2 = new Transaction(params, send2.bitcoinSerialize());
|
send2 = new Transaction(params, send2.bitcoinSerialize());
|
||||||
// Broadcast send1, it's now pending.
|
// Broadcast send1, it's now pending.
|
||||||
wallet.commitTx(send1);
|
wallet.commitTx(send1);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
// Receive a block that overrides the send1 using send2.
|
// Receive a block that overrides the send1 using send2.
|
||||||
sendMoneyToWallet(send2, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(send2, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
// send1 got rolled back and replaced with a smaller send that only used one of our received coins, thus ...
|
// send1 got rolled back and replaced with a smaller send that only used one of our received coins, thus ...
|
||||||
@ -691,8 +691,8 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// This can (and has!) happened when a wallet is cloned between devices, and both devices decide to make the
|
// This can (and has!) happened when a wallet is cloned between devices, and both devices decide to make the
|
||||||
// same spend simultaneously - for example due a re-keying operation. It can also happen if there are malicious
|
// same spend simultaneously - for example due a re-keying operation. It can also happen if there are malicious
|
||||||
// nodes in the P2P network that are mutating transactions on the fly as occurred during Feb 2014.
|
// nodes in the P2P network that are mutating transactions on the fly as occurred during Feb 2014.
|
||||||
final BigInteger value = Utils.toNanoCoins(1, 0);
|
final Coin value = Utils.toNanoCoins(1, 0);
|
||||||
final BigInteger value2 = Utils.toNanoCoins(2, 0);
|
final Coin value2 = Utils.toNanoCoins(2, 0);
|
||||||
// Give us three coins and make sure we have some change.
|
// Give us three coins and make sure we have some change.
|
||||||
sendMoneyToWallet(value.add(value2), AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(value.add(value2), AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
final Address address = new ECKey().toAddress(params);
|
final Address address = new ECKey().toAddress(params);
|
||||||
@ -707,7 +707,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Now spend the change. This transaction should die permanently when the mutant appears in the chain.
|
// Now spend the change. This transaction should die permanently when the mutant appears in the chain.
|
||||||
Transaction send3 = checkNotNull(wallet.createSend(address, value));
|
Transaction send3 = checkNotNull(wallet.createSend(address, value));
|
||||||
wallet.commitTx(send3);
|
wallet.commitTx(send3);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
final LinkedList<Transaction> dead = new LinkedList<Transaction>();
|
final LinkedList<Transaction> dead = new LinkedList<Transaction>();
|
||||||
final TransactionConfidence.Listener listener = new TransactionConfidence.Listener() {
|
final TransactionConfidence.Listener listener = new TransactionConfidence.Listener() {
|
||||||
@Override
|
@Override
|
||||||
@ -758,7 +758,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Receive 1 BTC.
|
// Receive 1 BTC.
|
||||||
BigInteger nanos = Utils.toNanoCoins(1, 0);
|
Coin nanos = Utils.toNanoCoins(1, 0);
|
||||||
sendMoneyToWallet(nanos, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(nanos, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
Transaction received = wallet.getTransactions(false).iterator().next();
|
Transaction received = wallet.getTransactions(false).iterator().next();
|
||||||
// Create a send to a merchant.
|
// Create a send to a merchant.
|
||||||
@ -794,7 +794,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
@Test
|
@Test
|
||||||
public void pending1() throws Exception {
|
public void pending1() throws Exception {
|
||||||
// Check that if we receive a pending transaction that is then confirmed, we are notified as appropriate.
|
// Check that if we receive a pending transaction that is then confirmed, we are notified as appropriate.
|
||||||
final BigInteger nanos = Utils.toNanoCoins(1, 0);
|
final Coin nanos = Utils.toNanoCoins(1, 0);
|
||||||
final Transaction t1 = createFakeTx(params, nanos, myAddress);
|
final Transaction t1 = createFakeTx(params, nanos, myAddress);
|
||||||
|
|
||||||
// First one is "called" second is "pending".
|
// First one is "called" second is "pending".
|
||||||
@ -803,11 +803,11 @@ public class WalletTest extends TestWithWallet {
|
|||||||
final int[] walletChanged = new int[1];
|
final int[] walletChanged = new int[1];
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
// Check we got the expected transaction.
|
// Check we got the expected transaction.
|
||||||
assertEquals(tx, t1);
|
assertEquals(tx, t1);
|
||||||
// Check that it's considered to be pending inclusion in the block chain.
|
// Check that it's considered to be pending inclusion in the block chain.
|
||||||
assertEquals(prevBalance, BigInteger.ZERO);
|
assertEquals(prevBalance, Coin.ZERO);
|
||||||
assertEquals(newBalance, nanos);
|
assertEquals(newBalance, nanos);
|
||||||
flags[0] = true;
|
flags[0] = true;
|
||||||
flags[1] = tx.isPending();
|
flags[1] = tx.isPending();
|
||||||
@ -867,21 +867,21 @@ public class WalletTest extends TestWithWallet {
|
|||||||
public void pending2() throws Exception {
|
public void pending2() throws Exception {
|
||||||
// Check that if we receive a pending tx we did not send, it updates our spent flags correctly.
|
// Check that if we receive a pending tx we did not send, it updates our spent flags correctly.
|
||||||
final Transaction txn[] = new Transaction[1];
|
final Transaction txn[] = new Transaction[1];
|
||||||
final BigInteger bigints[] = new BigInteger[2];
|
final Coin bigints[] = new Coin[2];
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
txn[0] = tx;
|
txn[0] = tx;
|
||||||
bigints[0] = prevBalance;
|
bigints[0] = prevBalance;
|
||||||
bigints[1] = newBalance;
|
bigints[1] = newBalance;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// Receive some coins.
|
// Receive some coins.
|
||||||
BigInteger nanos = Utils.toNanoCoins(1, 0);
|
Coin nanos = Utils.toNanoCoins(1, 0);
|
||||||
sendMoneyToWallet(nanos, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(nanos, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
// Create a spend with them, but don't commit it (ie it's from somewhere else but using our keys). This TX
|
// Create a spend with them, but don't commit it (ie it's from somewhere else but using our keys). This TX
|
||||||
// will have change as we don't spend our entire balance.
|
// will have change as we don't spend our entire balance.
|
||||||
BigInteger halfNanos = Utils.toNanoCoins(0, 50);
|
Coin halfNanos = Utils.toNanoCoins(0, 50);
|
||||||
Transaction t2 = wallet.createSend(new ECKey().toAddress(params), halfNanos);
|
Transaction t2 = wallet.createSend(new ECKey().toAddress(params), halfNanos);
|
||||||
// Now receive it as pending.
|
// Now receive it as pending.
|
||||||
if (wallet.isPendingTransactionRelevant(t2))
|
if (wallet.isPendingTransactionRelevant(t2))
|
||||||
@ -900,7 +900,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Check that if we receive a pending tx, and it's overridden by a double spend from the main chain, we
|
// Check that if we receive a pending tx, and it's overridden by a double spend from the main chain, we
|
||||||
// are notified that it's dead. This should work even if the pending tx inputs are NOT ours, ie, they don't
|
// are notified that it's dead. This should work even if the pending tx inputs are NOT ours, ie, they don't
|
||||||
// connect to anything.
|
// connect to anything.
|
||||||
BigInteger nanos = Utils.toNanoCoins(1, 0);
|
Coin nanos = Utils.toNanoCoins(1, 0);
|
||||||
|
|
||||||
// Create two transactions that share the same input tx.
|
// Create two transactions that share the same input tx.
|
||||||
Address badGuy = new ECKey().toAddress(params);
|
Address badGuy = new ECKey().toAddress(params);
|
||||||
@ -918,7 +918,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
final Transaction[] called = new Transaction[2];
|
final Transaction[] called = new Transaction[2];
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
called[0] = tx;
|
called[0] = tx;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -933,7 +933,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
if (wallet.isPendingTransactionRelevant(t1))
|
if (wallet.isPendingTransactionRelevant(t1))
|
||||||
wallet.receivePending(t1, null);
|
wallet.receivePending(t1, null);
|
||||||
Threading.waitForUserCode();
|
Threading.waitForUserCode();
|
||||||
@ -943,7 +943,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
called[0] = called[1] = null;
|
called[0] = called[1] = null;
|
||||||
sendMoneyToWallet(t2, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(t2, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
Threading.waitForUserCode();
|
Threading.waitForUserCode();
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(t1, called[0]); // dead
|
assertEquals(t1, called[0]); // dead
|
||||||
assertEquals(t2, called[1]); // replacement
|
assertEquals(t2, called[1]); // replacement
|
||||||
}
|
}
|
||||||
@ -1021,8 +1021,8 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Test that a spend to the same wallet is dealt with correctly.
|
// Test that a spend to the same wallet is dealt with correctly.
|
||||||
// It should appear in the wallet and confirm.
|
// It should appear in the wallet and confirm.
|
||||||
// This is a bit of a silly thing to do in the real world as all it does is burn a fee but it is perfectly valid.
|
// This is a bit of a silly thing to do in the real world as all it does is burn a fee but it is perfectly valid.
|
||||||
BigInteger coin1 = Utils.toNanoCoins(1, 0);
|
Coin coin1 = Utils.toNanoCoins(1, 0);
|
||||||
BigInteger coinHalf = Utils.toNanoCoins(0, 50);
|
Coin coinHalf = Utils.toNanoCoins(0, 50);
|
||||||
// Start by giving us 1 coin.
|
// Start by giving us 1 coin.
|
||||||
sendMoneyToWallet(coin1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(coin1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
// Send half to ourselves. We should then have a balance available to spend of zero.
|
// Send half to ourselves. We should then have a balance available to spend of zero.
|
||||||
@ -1031,7 +1031,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Transaction outbound1 = wallet.createSend(myAddress, coinHalf);
|
Transaction outbound1 = wallet.createSend(myAddress, coinHalf);
|
||||||
wallet.commitTx(outbound1);
|
wallet.commitTx(outbound1);
|
||||||
// We should have a zero available balance before the next block.
|
// We should have a zero available balance before the next block.
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
sendMoneyToWallet(outbound1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(outbound1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
// We should have a balance of 1 BTC after the block is received.
|
// We should have a balance of 1 BTC after the block is received.
|
||||||
assertEquals(coin1, wallet.getBalance());
|
assertEquals(coin1, wallet.getBalance());
|
||||||
@ -1039,9 +1039,9 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void lastBlockSeen() throws Exception {
|
public void lastBlockSeen() throws Exception {
|
||||||
BigInteger v1 = toNanoCoins(5, 0);
|
Coin v1 = toNanoCoins(5, 0);
|
||||||
BigInteger v2 = toNanoCoins(0, 50);
|
Coin v2 = toNanoCoins(0, 50);
|
||||||
BigInteger v3 = toNanoCoins(0, 25);
|
Coin v3 = toNanoCoins(0, 25);
|
||||||
Transaction t1 = createFakeTx(params, v1, myAddress);
|
Transaction t1 = createFakeTx(params, v1, myAddress);
|
||||||
Transaction t2 = createFakeTx(params, v2, myAddress);
|
Transaction t2 = createFakeTx(params, v2, myAddress);
|
||||||
Transaction t3 = createFakeTx(params, v3, myAddress);
|
Transaction t3 = createFakeTx(params, v3, myAddress);
|
||||||
@ -1072,13 +1072,13 @@ public class WalletTest extends TestWithWallet {
|
|||||||
public void pubkeyOnlyScripts() throws Exception {
|
public void pubkeyOnlyScripts() throws Exception {
|
||||||
// Verify that we support outputs like OP_PUBKEY and the corresponding inputs.
|
// Verify that we support outputs like OP_PUBKEY and the corresponding inputs.
|
||||||
ECKey key1 = wallet.freshReceiveKey();
|
ECKey key1 = wallet.freshReceiveKey();
|
||||||
BigInteger value = toNanoCoins(5, 0);
|
Coin value = toNanoCoins(5, 0);
|
||||||
Transaction t1 = createFakeTx(params, value, key1);
|
Transaction t1 = createFakeTx(params, value, key1);
|
||||||
if (wallet.isPendingTransactionRelevant(t1))
|
if (wallet.isPendingTransactionRelevant(t1))
|
||||||
wallet.receivePending(t1, null);
|
wallet.receivePending(t1, null);
|
||||||
// TX should have been seen as relevant.
|
// TX should have been seen as relevant.
|
||||||
assertEquals(value, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
assertEquals(value, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance(Wallet.BalanceType.AVAILABLE));
|
assertEquals(Coin.ZERO, wallet.getBalance(Wallet.BalanceType.AVAILABLE));
|
||||||
Block b1 = createFakeBlock(blockStore, t1).block;
|
Block b1 = createFakeBlock(blockStore, t1).block;
|
||||||
chain.add(b1);
|
chain.add(b1);
|
||||||
// TX should have been seen as relevant, extracted and processed.
|
// TX should have been seen as relevant, extracted and processed.
|
||||||
@ -1114,7 +1114,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
ECKey key = new ECKey();
|
ECKey key = new ECKey();
|
||||||
Address watchedAddress = key.toAddress(params);
|
Address watchedAddress = key.toAddress(params);
|
||||||
wallet.addWatchedAddress(watchedAddress);
|
wallet.addWatchedAddress(watchedAddress);
|
||||||
BigInteger value = toNanoCoins(5, 0);
|
Coin value = toNanoCoins(5, 0);
|
||||||
Transaction t1 = createFakeTx(params, value, watchedAddress);
|
Transaction t1 = createFakeTx(params, value, watchedAddress);
|
||||||
assertTrue(wallet.isPendingTransactionRelevant(t1));
|
assertTrue(wallet.isPendingTransactionRelevant(t1));
|
||||||
}
|
}
|
||||||
@ -1127,7 +1127,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Transaction t1 = createFakeTx(params, CENT, watchedAddress);
|
Transaction t1 = createFakeTx(params, CENT, watchedAddress);
|
||||||
StoredBlock b3 = createFakeBlock(blockStore, t1).storedBlock;
|
StoredBlock b3 = createFakeBlock(blockStore, t1).storedBlock;
|
||||||
wallet.receiveFromBlock(t1, b3, BlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(t1, b3, BlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(CENT, wallet.getWatchedBalance());
|
assertEquals(CENT, wallet.getWatchedBalance());
|
||||||
|
|
||||||
// We can't spend watched balances
|
// We can't spend watched balances
|
||||||
@ -1273,11 +1273,11 @@ public class WalletTest extends TestWithWallet {
|
|||||||
@Test
|
@Test
|
||||||
public void spendOutputFromPendingTransaction() throws Exception {
|
public void spendOutputFromPendingTransaction() throws Exception {
|
||||||
// We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
|
// We'll set up a wallet that receives a coin, then sends a coin of lesser value and keeps the change.
|
||||||
BigInteger v1 = Utils.toNanoCoins(1, 0);
|
Coin v1 = Utils.toNanoCoins(1, 0);
|
||||||
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(v1, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
// First create our current transaction
|
// First create our current transaction
|
||||||
ECKey k2 = wallet.freshReceiveKey();
|
ECKey k2 = wallet.freshReceiveKey();
|
||||||
BigInteger v2 = toNanoCoins(0, 50);
|
Coin v2 = toNanoCoins(0, 50);
|
||||||
Transaction t2 = new Transaction(params);
|
Transaction t2 = new Transaction(params);
|
||||||
TransactionOutput o2 = new TransactionOutput(params, t2, v2, k2.toAddress(params));
|
TransactionOutput o2 = new TransactionOutput(params, t2, v2, k2.toAddress(params));
|
||||||
t2.addOutput(o2);
|
t2.addOutput(o2);
|
||||||
@ -1293,7 +1293,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
// Now try to the spend the output.
|
// Now try to the spend the output.
|
||||||
ECKey k3 = new ECKey();
|
ECKey k3 = new ECKey();
|
||||||
BigInteger v3 = toNanoCoins(0, 25);
|
Coin v3 = toNanoCoins(0, 25);
|
||||||
Transaction t3 = new Transaction(params);
|
Transaction t3 = new Transaction(params);
|
||||||
t3.addOutput(v3, k3.toAddress(params));
|
t3.addOutput(v3, k3.toAddress(params));
|
||||||
t3.addInput(o2);
|
t3.addInput(o2);
|
||||||
@ -1314,7 +1314,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Check that if a pending transaction spends outputs of chain-included transactions, we mark them as spent.
|
// Check that if a pending transaction spends outputs of chain-included transactions, we mark them as spent.
|
||||||
// See bug 345. This can happen if there is a pending transaction floating around and then you replay the
|
// See bug 345. This can happen if there is a pending transaction floating around and then you replay the
|
||||||
// chain without emptying the memory pool (or refilling it from a peer).
|
// chain without emptying the memory pool (or refilling it from a peer).
|
||||||
BigInteger value = Utils.toNanoCoins(1, 0);
|
Coin value = Utils.toNanoCoins(1, 0);
|
||||||
Transaction tx1 = createFakeTx(params, value, myAddress);
|
Transaction tx1 = createFakeTx(params, value, myAddress);
|
||||||
Transaction tx2 = new Transaction(params);
|
Transaction tx2 = new Transaction(params);
|
||||||
tx2.addInput(tx1.getOutput(0));
|
tx2.addInput(tx1.getOutput(0));
|
||||||
@ -1325,7 +1325,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
BlockPair bp = createFakeBlock(blockStore, tx1);
|
BlockPair bp = createFakeBlock(blockStore, tx1);
|
||||||
wallet.receiveFromBlock(tx1, bp.storedBlock, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(tx1, bp.storedBlock, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
wallet.notifyNewBestBlock(bp.storedBlock);
|
wallet.notifyNewBestBlock(bp.storedBlock);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(1, wallet.getPoolSize(Pool.SPENT));
|
assertEquals(1, wallet.getPoolSize(Pool.SPENT));
|
||||||
assertEquals(1, wallet.getPoolSize(Pool.PENDING));
|
assertEquals(1, wallet.getPoolSize(Pool.PENDING));
|
||||||
assertEquals(0, wallet.getPoolSize(Pool.UNSPENT));
|
assertEquals(0, wallet.getPoolSize(Pool.UNSPENT));
|
||||||
@ -1461,7 +1461,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Transaction tx = new Transaction(params);
|
Transaction tx = new Transaction(params);
|
||||||
byte[] bits = new byte[20];
|
byte[] bits = new byte[20];
|
||||||
new Random().nextBytes(bits);
|
new Random().nextBytes(bits);
|
||||||
BigInteger v = Utils.toNanoCoins(0, 1);
|
Coin v = Utils.toNanoCoins(0, 1);
|
||||||
// 3100 outputs to a random address.
|
// 3100 outputs to a random address.
|
||||||
for (int i = 0; i < 3100; i++) {
|
for (int i = 0; i < 3100; i++) {
|
||||||
tx.addOutput(v, new Address(params, bits));
|
tx.addOutput(v, new Address(params, bits));
|
||||||
@ -1481,26 +1481,26 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
// Generate a few outputs to us that are far too small to spend reasonably
|
// Generate a few outputs to us that are far too small to spend reasonably
|
||||||
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
|
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
|
||||||
Transaction tx1 = createFakeTx(params, BigInteger.ONE, myAddress);
|
Transaction tx1 = createFakeTx(params, Coin.ONE, myAddress);
|
||||||
wallet.receiveFromBlock(tx1, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(tx1, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
Transaction tx2 = createFakeTx(params, BigInteger.ONE, myAddress);
|
Transaction tx2 = createFakeTx(params, Coin.ONE, myAddress);
|
||||||
assertTrue(!tx1.getHash().equals(tx2.getHash()));
|
assertTrue(!tx1.getHash().equals(tx2.getHash()));
|
||||||
wallet.receiveFromBlock(tx2, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 1);
|
wallet.receiveFromBlock(tx2, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 1);
|
||||||
Transaction tx3 = createFakeTx(params, BigInteger.TEN, myAddress);
|
Transaction tx3 = createFakeTx(params, Coin.TEN, myAddress);
|
||||||
wallet.receiveFromBlock(tx3, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 2);
|
wallet.receiveFromBlock(tx3, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 2);
|
||||||
|
|
||||||
// Not allowed to send dust.
|
// Not allowed to send dust.
|
||||||
try {
|
try {
|
||||||
wallet.createSend(notMyAddr, BigInteger.ONE);
|
wallet.createSend(notMyAddr, Coin.ONE);
|
||||||
fail();
|
fail();
|
||||||
} catch (Wallet.DustySendRequested e) {
|
} catch (Wallet.DustySendRequested e) {
|
||||||
// Expected.
|
// Expected.
|
||||||
}
|
}
|
||||||
// Spend it all without fee enforcement
|
// Spend it all without fee enforcement
|
||||||
SendRequest req = SendRequest.to(notMyAddr, BigInteger.TEN.add(BigInteger.ONE.add(BigInteger.ONE)));
|
SendRequest req = SendRequest.to(notMyAddr, Coin.TEN.add(Coin.ONE.add(Coin.ONE)));
|
||||||
req.ensureMinRequiredFee = false;
|
req.ensureMinRequiredFee = false;
|
||||||
assertNotNull(wallet.sendCoinsOffline(req));
|
assertNotNull(wallet.sendCoinsOffline(req));
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
|
|
||||||
// Add some reasonable-sized outputs
|
// Add some reasonable-sized outputs
|
||||||
block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
|
block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
|
||||||
@ -1508,7 +1508,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
wallet.receiveFromBlock(tx4, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(tx4, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
|
|
||||||
// Simple test to make sure if we have an ouput < 0.01 we get a fee
|
// Simple test to make sure if we have an ouput < 0.01 we get a fee
|
||||||
Transaction spend1 = wallet.createSend(notMyAddr, CENT.subtract(BigInteger.ONE));
|
Transaction spend1 = wallet.createSend(notMyAddr, CENT.subtract(Coin.ONE));
|
||||||
assertEquals(2, spend1.getOutputs().size());
|
assertEquals(2, spend1.getOutputs().size());
|
||||||
// We optimize for priority, so the output selected should be the largest one.
|
// We optimize for priority, so the output selected should be the largest one.
|
||||||
// We should have paid the default minfee.
|
// We should have paid the default minfee.
|
||||||
@ -1522,19 +1522,19 @@ public class WalletTest extends TestWithWallet {
|
|||||||
assertEquals(Utils.COIN, spend2.getOutput(0).getValue().add(spend2.getOutput(1).getValue()));
|
assertEquals(Utils.COIN, spend2.getOutput(0).getValue().add(spend2.getOutput(1).getValue()));
|
||||||
|
|
||||||
// ...but not more fee than what we request
|
// ...but not more fee than what we request
|
||||||
SendRequest request3 = SendRequest.to(notMyAddr, CENT.subtract(BigInteger.ONE));
|
SendRequest request3 = SendRequest.to(notMyAddr, CENT.subtract(Coin.ONE));
|
||||||
request3.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE);
|
request3.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE);
|
||||||
wallet.completeTx(request3);
|
wallet.completeTx(request3);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE), request3.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE), request3.fee);
|
||||||
Transaction spend3 = request3.tx;
|
Transaction spend3 = request3.tx;
|
||||||
assertEquals(2, spend3.getOutputs().size());
|
assertEquals(2, spend3.getOutputs().size());
|
||||||
// We optimize for priority, so the output selected should be the largest one.
|
// We optimize for priority, so the output selected should be the largest one.
|
||||||
assertEquals(spend3.getOutput(0).getValue().add(spend3.getOutput(1).getValue()),
|
assertEquals(spend3.getOutput(0).getValue().add(spend3.getOutput(1).getValue()),
|
||||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE)));
|
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE)));
|
||||||
|
|
||||||
// ...unless we need it
|
// ...unless we need it
|
||||||
SendRequest request4 = SendRequest.to(notMyAddr, CENT.subtract(BigInteger.ONE));
|
SendRequest request4 = SendRequest.to(notMyAddr, CENT.subtract(Coin.ONE));
|
||||||
request4.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(BigInteger.ONE);
|
request4.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(Coin.ONE);
|
||||||
wallet.completeTx(request4);
|
wallet.completeTx(request4);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request4.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request4.fee);
|
||||||
Transaction spend4 = request4.tx;
|
Transaction spend4 = request4.tx;
|
||||||
@ -1543,7 +1543,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
assertEquals(spend4.getOutput(0).getValue().add(spend4.getOutput(1).getValue()),
|
assertEquals(spend4.getOutput(0).getValue().add(spend4.getOutput(1).getValue()),
|
||||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||||
|
|
||||||
SendRequest request5 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.subtract(BigInteger.ONE)));
|
SendRequest request5 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.subtract(Coin.ONE)));
|
||||||
wallet.completeTx(request5);
|
wallet.completeTx(request5);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request5.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request5.fee);
|
||||||
Transaction spend5 = request5.tx;
|
Transaction spend5 = request5.tx;
|
||||||
@ -1555,15 +1555,15 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
SendRequest request6 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT));
|
SendRequest request6 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT));
|
||||||
wallet.completeTx(request6);
|
wallet.completeTx(request6);
|
||||||
assertEquals(BigInteger.ZERO, request6.fee);
|
assertEquals(Coin.ZERO, request6.fee);
|
||||||
Transaction spend6 = request6.tx;
|
Transaction spend6 = request6.tx;
|
||||||
// ...but not if change output == 0.01
|
// ...but not if change output == 0.01
|
||||||
assertEquals(2, spend6.getOutputs().size());
|
assertEquals(2, spend6.getOutputs().size());
|
||||||
// We optimize for priority, so the output selected should be the largest one
|
// We optimize for priority, so the output selected should be the largest one
|
||||||
assertEquals(Utils.COIN, spend6.getOutput(0).getValue().add(spend6.getOutput(1).getValue()));
|
assertEquals(Utils.COIN, spend6.getOutput(0).getValue().add(spend6.getOutput(1).getValue()));
|
||||||
|
|
||||||
SendRequest request7 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.subtract(BigInteger.valueOf(2)).multiply(BigInteger.valueOf(2))));
|
SendRequest request7 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.subtract(Coin.valueOf(2)).multiply(Coin.valueOf(2))));
|
||||||
request7.tx.addOutput(CENT.subtract(BigInteger.ONE), notMyAddr);
|
request7.tx.addOutput(CENT.subtract(Coin.ONE), notMyAddr);
|
||||||
wallet.completeTx(request7);
|
wallet.completeTx(request7);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request7.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request7.fee);
|
||||||
Transaction spend7 = request7.tx;
|
Transaction spend7 = request7.tx;
|
||||||
@ -1594,7 +1594,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)));
|
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)));
|
||||||
|
|
||||||
SendRequest request10 = SendRequest.to(notMyAddr, Utils.COIN.subtract(
|
SendRequest request10 = SendRequest.to(notMyAddr, Utils.COIN.subtract(
|
||||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(BigInteger.ONE)));
|
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(Coin.ONE)));
|
||||||
wallet.completeTx(request10);
|
wallet.completeTx(request10);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request10.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request10.fee);
|
||||||
Transaction spend10 = request10.tx;
|
Transaction spend10 = request10.tx;
|
||||||
@ -1605,16 +1605,16 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||||
|
|
||||||
SendRequest request11 = SendRequest.to(notMyAddr, Utils.COIN.subtract(
|
SendRequest request11 = SendRequest.to(notMyAddr, Utils.COIN.subtract(
|
||||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(BigInteger.valueOf(2))));
|
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(Coin.valueOf(2))));
|
||||||
request11.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE);
|
request11.fee = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE);
|
||||||
wallet.completeTx(request11);
|
wallet.completeTx(request11);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE), request11.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE), request11.fee);
|
||||||
Transaction spend11 = request11.tx;
|
Transaction spend11 = request11.tx;
|
||||||
// ...of course fee should be min(request.fee, MIN_TX_FEE) so we should get MIN_TX_FEE.add(ONE) here
|
// ...of course fee should be min(request.fee, MIN_TX_FEE) so we should get MIN_TX_FEE.add(ONE) here
|
||||||
assertEquals(2, spend11.getOutputs().size());
|
assertEquals(2, spend11.getOutputs().size());
|
||||||
// We optimize for priority, so the output selected should be the largest one.
|
// We optimize for priority, so the output selected should be the largest one.
|
||||||
assertEquals(spend11.getOutput(0).getValue().add(spend11.getOutput(1).getValue()),
|
assertEquals(spend11.getOutput(0).getValue().add(spend11.getOutput(1).getValue()),
|
||||||
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(BigInteger.ONE)));
|
Utils.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Coin.ONE)));
|
||||||
|
|
||||||
// Remove the coin from our wallet
|
// Remove the coin from our wallet
|
||||||
wallet.commitTx(spend11);
|
wallet.commitTx(spend11);
|
||||||
@ -1658,30 +1658,30 @@ public class WalletTest extends TestWithWallet {
|
|||||||
for (int i = 0; i < 29; i++)
|
for (int i = 0; i < 29; i++)
|
||||||
request15.tx.addOutput(CENT, notMyAddr);
|
request15.tx.addOutput(CENT, notMyAddr);
|
||||||
assertTrue(request15.tx.bitcoinSerialize().length > 1000);
|
assertTrue(request15.tx.bitcoinSerialize().length > 1000);
|
||||||
request15.feePerKb = BigInteger.ONE;
|
request15.feePerKb = Coin.ONE;
|
||||||
wallet.completeTx(request15);
|
wallet.completeTx(request15);
|
||||||
assertEquals(BigInteger.valueOf(2), request15.fee);
|
assertEquals(Coin.valueOf(2), request15.fee);
|
||||||
Transaction spend15 = request15.tx;
|
Transaction spend15 = request15.tx;
|
||||||
// If a transaction is over 1kb, 2 satoshis should be added.
|
// If a transaction is over 1kb, 2 satoshis should be added.
|
||||||
assertEquals(31, spend15.getOutputs().size());
|
assertEquals(31, spend15.getOutputs().size());
|
||||||
// We optimize for priority, so the output selected should be the largest one
|
// We optimize for priority, so the output selected should be the largest one
|
||||||
BigInteger outValue15 = BigInteger.ZERO;
|
Coin outValue15 = Coin.ZERO;
|
||||||
for (TransactionOutput out : spend15.getOutputs())
|
for (TransactionOutput out : spend15.getOutputs())
|
||||||
outValue15 = outValue15.add(out.getValue());
|
outValue15 = outValue15.add(out.getValue());
|
||||||
assertEquals(Utils.COIN.subtract(BigInteger.valueOf(2)), outValue15);
|
assertEquals(Utils.COIN.subtract(Coin.valueOf(2)), outValue15);
|
||||||
|
|
||||||
SendRequest request16 = SendRequest.to(notMyAddr, CENT);
|
SendRequest request16 = SendRequest.to(notMyAddr, CENT);
|
||||||
request16.feePerKb = BigInteger.ZERO;
|
request16.feePerKb = Coin.ZERO;
|
||||||
for (int i = 0; i < 29; i++)
|
for (int i = 0; i < 29; i++)
|
||||||
request16.tx.addOutput(CENT, notMyAddr);
|
request16.tx.addOutput(CENT, notMyAddr);
|
||||||
assertTrue(request16.tx.bitcoinSerialize().length > 1000);
|
assertTrue(request16.tx.bitcoinSerialize().length > 1000);
|
||||||
wallet.completeTx(request16);
|
wallet.completeTx(request16);
|
||||||
// Of course the fee shouldn't be added if feePerKb == 0
|
// Of course the fee shouldn't be added if feePerKb == 0
|
||||||
assertEquals(BigInteger.ZERO, request16.fee);
|
assertEquals(Coin.ZERO, request16.fee);
|
||||||
Transaction spend16 = request16.tx;
|
Transaction spend16 = request16.tx;
|
||||||
assertEquals(31, spend16.getOutputs().size());
|
assertEquals(31, spend16.getOutputs().size());
|
||||||
// We optimize for priority, so the output selected should be the largest one
|
// We optimize for priority, so the output selected should be the largest one
|
||||||
BigInteger outValue16 = BigInteger.ZERO;
|
Coin outValue16 = Coin.ZERO;
|
||||||
for (TransactionOutput out : spend16.getOutputs())
|
for (TransactionOutput out : spend16.getOutputs())
|
||||||
outValue16 = outValue16.add(out.getValue());
|
outValue16 = outValue16.add(out.getValue());
|
||||||
assertEquals(Utils.COIN, outValue16);
|
assertEquals(Utils.COIN, outValue16);
|
||||||
@ -1691,9 +1691,9 @@ public class WalletTest extends TestWithWallet {
|
|||||||
for (int i = 0; i < 22; i++)
|
for (int i = 0; i < 22; i++)
|
||||||
request17.tx.addOutput(CENT, notMyAddr);
|
request17.tx.addOutput(CENT, notMyAddr);
|
||||||
request17.tx.addOutput(new TransactionOutput(params, request17.tx, CENT, new byte[15]));
|
request17.tx.addOutput(new TransactionOutput(params, request17.tx, CENT, new byte[15]));
|
||||||
request17.feePerKb = BigInteger.ONE;
|
request17.feePerKb = Coin.ONE;
|
||||||
wallet.completeTx(request17);
|
wallet.completeTx(request17);
|
||||||
assertEquals(BigInteger.ONE, request17.fee);
|
assertEquals(Coin.ONE, request17.fee);
|
||||||
assertEquals(1, request17.tx.getInputs().size());
|
assertEquals(1, request17.tx.getInputs().size());
|
||||||
// Calculate its max length to make sure it is indeed 999
|
// Calculate its max length to make sure it is indeed 999
|
||||||
int theoreticalMaxLength17 = request17.tx.bitcoinSerialize().length + myKey.getPubKey().length + 75;
|
int theoreticalMaxLength17 = request17.tx.bitcoinSerialize().length + myKey.getPubKey().length + 75;
|
||||||
@ -1709,19 +1709,19 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Now check that it got a fee of 1 since its max size is 999 (1kb).
|
// Now check that it got a fee of 1 since its max size is 999 (1kb).
|
||||||
assertEquals(25, spend17.getOutputs().size());
|
assertEquals(25, spend17.getOutputs().size());
|
||||||
// We optimize for priority, so the output selected should be the largest one
|
// We optimize for priority, so the output selected should be the largest one
|
||||||
BigInteger outValue17 = BigInteger.ZERO;
|
Coin outValue17 = Coin.ZERO;
|
||||||
for (TransactionOutput out : spend17.getOutputs())
|
for (TransactionOutput out : spend17.getOutputs())
|
||||||
outValue17 = outValue17.add(out.getValue());
|
outValue17 = outValue17.add(out.getValue());
|
||||||
assertEquals(Utils.COIN.subtract(BigInteger.ONE), outValue17);
|
assertEquals(Utils.COIN.subtract(Coin.ONE), outValue17);
|
||||||
|
|
||||||
// Create a transaction who's max size could be up to 1001 (if signatures were maximum size)
|
// Create a transaction who's max size could be up to 1001 (if signatures were maximum size)
|
||||||
SendRequest request18 = SendRequest.to(notMyAddr, CENT);
|
SendRequest request18 = SendRequest.to(notMyAddr, CENT);
|
||||||
for (int i = 0; i < 22; i++)
|
for (int i = 0; i < 22; i++)
|
||||||
request18.tx.addOutput(CENT, notMyAddr);
|
request18.tx.addOutput(CENT, notMyAddr);
|
||||||
request18.tx.addOutput(new TransactionOutput(params, request18.tx, CENT, new byte[17]));
|
request18.tx.addOutput(new TransactionOutput(params, request18.tx, CENT, new byte[17]));
|
||||||
request18.feePerKb = BigInteger.ONE;
|
request18.feePerKb = Coin.ONE;
|
||||||
wallet.completeTx(request18);
|
wallet.completeTx(request18);
|
||||||
assertEquals(BigInteger.valueOf(2), request18.fee);
|
assertEquals(Coin.valueOf(2), request18.fee);
|
||||||
assertEquals(1, request18.tx.getInputs().size());
|
assertEquals(1, request18.tx.getInputs().size());
|
||||||
// Calculate its max length to make sure it is indeed 1001
|
// Calculate its max length to make sure it is indeed 1001
|
||||||
Transaction spend18 = request18.tx;
|
Transaction spend18 = request18.tx;
|
||||||
@ -1735,31 +1735,31 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Now check that it did get a fee since its max size is 1000
|
// Now check that it did get a fee since its max size is 1000
|
||||||
assertEquals(25, spend18.getOutputs().size());
|
assertEquals(25, spend18.getOutputs().size());
|
||||||
// We optimize for priority, so the output selected should be the largest one
|
// We optimize for priority, so the output selected should be the largest one
|
||||||
BigInteger outValue18 = BigInteger.ZERO;
|
Coin outValue18 = Coin.ZERO;
|
||||||
for (TransactionOutput out : spend18.getOutputs())
|
for (TransactionOutput out : spend18.getOutputs())
|
||||||
outValue18 = outValue18.add(out.getValue());
|
outValue18 = outValue18.add(out.getValue());
|
||||||
assertEquals(outValue18, Utils.COIN.subtract(BigInteger.valueOf(2)));
|
assertEquals(outValue18, Utils.COIN.subtract(Coin.valueOf(2)));
|
||||||
|
|
||||||
// Now create a transaction that will spend COIN + fee, which makes it require both inputs
|
// Now create a transaction that will spend COIN + fee, which makes it require both inputs
|
||||||
assertEquals(wallet.getBalance(), CENT.add(Utils.COIN));
|
assertEquals(wallet.getBalance(), CENT.add(Utils.COIN));
|
||||||
SendRequest request19 = SendRequest.to(notMyAddr, CENT);
|
SendRequest request19 = SendRequest.to(notMyAddr, CENT);
|
||||||
request19.feePerKb = BigInteger.ZERO;
|
request19.feePerKb = Coin.ZERO;
|
||||||
for (int i = 0; i < 99; i++)
|
for (int i = 0; i < 99; i++)
|
||||||
request19.tx.addOutput(CENT, notMyAddr);
|
request19.tx.addOutput(CENT, notMyAddr);
|
||||||
// If we send now, we shouldn't need a fee and should only have to spend our COIN
|
// If we send now, we shouldn't need a fee and should only have to spend our COIN
|
||||||
wallet.completeTx(request19);
|
wallet.completeTx(request19);
|
||||||
assertEquals(BigInteger.ZERO, request19.fee);
|
assertEquals(Coin.ZERO, request19.fee);
|
||||||
assertEquals(1, request19.tx.getInputs().size());
|
assertEquals(1, request19.tx.getInputs().size());
|
||||||
assertEquals(100, request19.tx.getOutputs().size());
|
assertEquals(100, request19.tx.getOutputs().size());
|
||||||
// Now reset request19 and give it a fee per kb
|
// Now reset request19 and give it a fee per kb
|
||||||
request19.tx.clearInputs();
|
request19.tx.clearInputs();
|
||||||
request19 = SendRequest.forTx(request19.tx);
|
request19 = SendRequest.forTx(request19.tx);
|
||||||
request19.feePerKb = BigInteger.ONE;
|
request19.feePerKb = Coin.ONE;
|
||||||
request19.shuffleOutputs = false;
|
request19.shuffleOutputs = false;
|
||||||
wallet.completeTx(request19);
|
wallet.completeTx(request19);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request19.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request19.fee);
|
||||||
assertEquals(2, request19.tx.getInputs().size());
|
assertEquals(2, request19.tx.getInputs().size());
|
||||||
BigInteger outValue19 = BigInteger.ZERO;
|
Coin outValue19 = Coin.ZERO;
|
||||||
for (TransactionOutput out : request19.tx.getOutputs())
|
for (TransactionOutput out : request19.tx.getOutputs())
|
||||||
outValue19 = outValue19.add(out.getValue());
|
outValue19 = outValue19.add(out.getValue());
|
||||||
// But now our change output is CENT-minfee, so we have to pay min fee
|
// But now our change output is CENT-minfee, so we have to pay min fee
|
||||||
@ -1768,12 +1768,12 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
// Create another transaction that will spend COIN + fee, which makes it require both inputs
|
// Create another transaction that will spend COIN + fee, which makes it require both inputs
|
||||||
SendRequest request20 = SendRequest.to(notMyAddr, CENT);
|
SendRequest request20 = SendRequest.to(notMyAddr, CENT);
|
||||||
request20.feePerKb = BigInteger.ZERO;
|
request20.feePerKb = Coin.ZERO;
|
||||||
for (int i = 0; i < 99; i++)
|
for (int i = 0; i < 99; i++)
|
||||||
request20.tx.addOutput(CENT, notMyAddr);
|
request20.tx.addOutput(CENT, notMyAddr);
|
||||||
// If we send now, we shouldn't have a fee and should only have to spend our COIN
|
// If we send now, we shouldn't have a fee and should only have to spend our COIN
|
||||||
wallet.completeTx(request20);
|
wallet.completeTx(request20);
|
||||||
assertEquals(BigInteger.ZERO, request20.fee);
|
assertEquals(Coin.ZERO, request20.fee);
|
||||||
assertEquals(1, request20.tx.getInputs().size());
|
assertEquals(1, request20.tx.getInputs().size());
|
||||||
assertEquals(100, request20.tx.getOutputs().size());
|
assertEquals(100, request20.tx.getOutputs().size());
|
||||||
// Now reset request19 and give it a fee per kb
|
// Now reset request19 and give it a fee per kb
|
||||||
@ -1782,18 +1782,18 @@ public class WalletTest extends TestWithWallet {
|
|||||||
request20.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
request20.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||||
wallet.completeTx(request20);
|
wallet.completeTx(request20);
|
||||||
// 4kb tx.
|
// 4kb tx.
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(4)), request20.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(4)), request20.fee);
|
||||||
assertEquals(2, request20.tx.getInputs().size());
|
assertEquals(2, request20.tx.getInputs().size());
|
||||||
BigInteger outValue20 = BigInteger.ZERO;
|
Coin outValue20 = Coin.ZERO;
|
||||||
for (TransactionOutput out : request20.tx.getOutputs())
|
for (TransactionOutput out : request20.tx.getOutputs())
|
||||||
outValue20 = outValue20.add(out.getValue());
|
outValue20 = outValue20.add(out.getValue());
|
||||||
// This time the fee we wanted to pay was more, so that should be what we paid
|
// This time the fee we wanted to pay was more, so that should be what we paid
|
||||||
assertEquals(outValue20, Utils.COIN.add(CENT).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(4))));
|
assertEquals(outValue20, Utils.COIN.add(CENT).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(4))));
|
||||||
|
|
||||||
// Same as request 19, but make the change 0 (so it doesnt force fee) and make us require min fee as a
|
// Same as request 19, but make the change 0 (so it doesnt force fee) and make us require min fee as a
|
||||||
// result of an output < CENT.
|
// result of an output < CENT.
|
||||||
SendRequest request21 = SendRequest.to(notMyAddr, CENT);
|
SendRequest request21 = SendRequest.to(notMyAddr, CENT);
|
||||||
request21.feePerKb = BigInteger.ZERO;
|
request21.feePerKb = Coin.ZERO;
|
||||||
for (int i = 0; i < 99; i++)
|
for (int i = 0; i < 99; i++)
|
||||||
request21.tx.addOutput(CENT, notMyAddr);
|
request21.tx.addOutput(CENT, notMyAddr);
|
||||||
request21.tx.addOutput(CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), notMyAddr);
|
request21.tx.addOutput(CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), notMyAddr);
|
||||||
@ -1801,7 +1801,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
wallet.completeTx(request21);
|
wallet.completeTx(request21);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request21.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request21.fee);
|
||||||
assertEquals(2, request21.tx.getInputs().size());
|
assertEquals(2, request21.tx.getInputs().size());
|
||||||
BigInteger outValue21 = BigInteger.ZERO;
|
Coin outValue21 = Coin.ZERO;
|
||||||
for (TransactionOutput out : request21.tx.getOutputs())
|
for (TransactionOutput out : request21.tx.getOutputs())
|
||||||
outValue21 = outValue21.add(out.getValue());
|
outValue21 = outValue21.add(out.getValue());
|
||||||
assertEquals(outValue21, Utils.COIN.add(CENT).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
assertEquals(outValue21, Utils.COIN.add(CENT).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||||
@ -1809,30 +1809,30 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Test feePerKb when we aren't using ensureMinRequiredFee
|
// Test feePerKb when we aren't using ensureMinRequiredFee
|
||||||
// Same as request 19
|
// Same as request 19
|
||||||
SendRequest request25 = SendRequest.to(notMyAddr, CENT);
|
SendRequest request25 = SendRequest.to(notMyAddr, CENT);
|
||||||
request25.feePerKb = BigInteger.ZERO;
|
request25.feePerKb = Coin.ZERO;
|
||||||
for (int i = 0; i < 70; i++)
|
for (int i = 0; i < 70; i++)
|
||||||
request25.tx.addOutput(CENT, notMyAddr);
|
request25.tx.addOutput(CENT, notMyAddr);
|
||||||
// If we send now, we shouldn't need a fee and should only have to spend our COIN
|
// If we send now, we shouldn't need a fee and should only have to spend our COIN
|
||||||
wallet.completeTx(request25);
|
wallet.completeTx(request25);
|
||||||
assertEquals(BigInteger.ZERO, request25.fee);
|
assertEquals(Coin.ZERO, request25.fee);
|
||||||
assertEquals(1, request25.tx.getInputs().size());
|
assertEquals(1, request25.tx.getInputs().size());
|
||||||
assertEquals(72, request25.tx.getOutputs().size());
|
assertEquals(72, request25.tx.getOutputs().size());
|
||||||
// Now reset request19 and give it a fee per kb
|
// Now reset request19 and give it a fee per kb
|
||||||
request25.tx.clearInputs();
|
request25.tx.clearInputs();
|
||||||
request25 = SendRequest.forTx(request25.tx);
|
request25 = SendRequest.forTx(request25.tx);
|
||||||
request25.feePerKb = CENT.divide(BigInteger.valueOf(3));
|
request25.feePerKb = CENT.divide(Coin.valueOf(3));
|
||||||
request25.ensureMinRequiredFee = false;
|
request25.ensureMinRequiredFee = false;
|
||||||
request25.shuffleOutputs = false;
|
request25.shuffleOutputs = false;
|
||||||
wallet.completeTx(request25);
|
wallet.completeTx(request25);
|
||||||
assertEquals(CENT.subtract(BigInteger.ONE), request25.fee);
|
assertEquals(CENT.subtract(Coin.ONE), request25.fee);
|
||||||
assertEquals(2, request25.tx.getInputs().size());
|
assertEquals(2, request25.tx.getInputs().size());
|
||||||
BigInteger outValue25 = BigInteger.ZERO;
|
Coin outValue25 = Coin.ZERO;
|
||||||
for (TransactionOutput out : request25.tx.getOutputs())
|
for (TransactionOutput out : request25.tx.getOutputs())
|
||||||
outValue25 = outValue25.add(out.getValue());
|
outValue25 = outValue25.add(out.getValue());
|
||||||
// Our change output should be one satoshi
|
// Our change output should be one satoshi
|
||||||
assertEquals(BigInteger.ONE, request25.tx.getOutput(request25.tx.getOutputs().size() - 1).getValue());
|
assertEquals(Coin.ONE, request25.tx.getOutput(request25.tx.getOutputs().size() - 1).getValue());
|
||||||
// and our fee should be CENT-1 satoshi
|
// and our fee should be CENT-1 satoshi
|
||||||
assertEquals(outValue25, Utils.COIN.add(BigInteger.ONE));
|
assertEquals(outValue25, Utils.COIN.add(Coin.ONE));
|
||||||
|
|
||||||
// Spend our CENT output.
|
// Spend our CENT output.
|
||||||
Transaction spendTx5 = new Transaction(params);
|
Transaction spendTx5 = new Transaction(params);
|
||||||
@ -1849,14 +1849,14 @@ public class WalletTest extends TestWithWallet {
|
|||||||
request26.tx.addOutput(CENT.subtract(
|
request26.tx.addOutput(CENT.subtract(
|
||||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)), notMyAddr);
|
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)), notMyAddr);
|
||||||
assertTrue(request26.tx.bitcoinSerialize().length > 1000);
|
assertTrue(request26.tx.bitcoinSerialize().length > 1000);
|
||||||
request26.feePerKb = BigInteger.ONE;
|
request26.feePerKb = Coin.ONE;
|
||||||
wallet.completeTx(request26);
|
wallet.completeTx(request26);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT), request26.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT), request26.fee);
|
||||||
Transaction spend26 = request26.tx;
|
Transaction spend26 = request26.tx;
|
||||||
// If a transaction is over 1kb, the set fee should be added
|
// If a transaction is over 1kb, the set fee should be added
|
||||||
assertEquals(100, spend26.getOutputs().size());
|
assertEquals(100, spend26.getOutputs().size());
|
||||||
// We optimize for priority, so the output selected should be the largest one
|
// We optimize for priority, so the output selected should be the largest one
|
||||||
BigInteger outValue26 = BigInteger.ZERO;
|
Coin outValue26 = Coin.ZERO;
|
||||||
for (TransactionOutput out : spend26.getOutputs())
|
for (TransactionOutput out : spend26.getOutputs())
|
||||||
outValue26 = outValue26.add(out.getValue());
|
outValue26 = outValue26.add(out.getValue());
|
||||||
assertEquals(outValue26, Utils.COIN.subtract(
|
assertEquals(outValue26, Utils.COIN.subtract(
|
||||||
@ -1866,7 +1866,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
@Test
|
@Test
|
||||||
public void basicCategoryStepTest() throws Exception {
|
public void basicCategoryStepTest() throws Exception {
|
||||||
// Creates spends that step through the possible fee solver categories
|
// Creates spends that step through the possible fee solver categories
|
||||||
SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
|
SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||||
// Make sure TestWithWallet isnt doing anything crazy.
|
// Make sure TestWithWallet isnt doing anything crazy.
|
||||||
assertEquals(0, wallet.getTransactions(true).size());
|
assertEquals(0, wallet.getTransactions(true).size());
|
||||||
|
|
||||||
@ -1882,9 +1882,9 @@ public class WalletTest extends TestWithWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Create a spend that will throw away change (category 3 type 2 in which the change causes fee which is worth more than change)
|
// Create a spend that will throw away change (category 3 type 2 in which the change causes fee which is worth more than change)
|
||||||
SendRequest request1 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
SendRequest request1 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||||
wallet.completeTx(request1);
|
wallet.completeTx(request1);
|
||||||
assertEquals(BigInteger.ONE, request1.fee);
|
assertEquals(Coin.ONE, request1.fee);
|
||||||
assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs
|
assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs
|
||||||
|
|
||||||
// Give us one more input...
|
// Give us one more input...
|
||||||
@ -1893,9 +1893,9 @@ public class WalletTest extends TestWithWallet {
|
|||||||
wallet.receiveFromBlock(tx1, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
wallet.receiveFromBlock(tx1, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
||||||
|
|
||||||
// ... and create a spend that will throw away change (category 3 type 1 in which the change causes dust output)
|
// ... and create a spend that will throw away change (category 3 type 1 in which the change causes dust output)
|
||||||
SendRequest request2 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
SendRequest request2 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||||
wallet.completeTx(request2);
|
wallet.completeTx(request2);
|
||||||
assertEquals(BigInteger.ONE, request2.fee);
|
assertEquals(Coin.ONE, request2.fee);
|
||||||
assertEquals(request2.tx.getInputs().size(), i - 1); // We should have spent all inputs - 1
|
assertEquals(request2.tx.getInputs().size(), i - 1); // We should have spent all inputs - 1
|
||||||
|
|
||||||
// Give us one more input...
|
// Give us one more input...
|
||||||
@ -1905,16 +1905,16 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
// ... and create a spend that will throw away change (category 3 type 1 in which the change causes dust output)
|
// ... and create a spend that will throw away change (category 3 type 1 in which the change causes dust output)
|
||||||
// but that also could have been category 2 if it wanted
|
// but that also could have been category 2 if it wanted
|
||||||
SendRequest request3 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
SendRequest request3 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||||
wallet.completeTx(request3);
|
wallet.completeTx(request3);
|
||||||
assertEquals(BigInteger.ONE, request3.fee);
|
assertEquals(Coin.ONE, request3.fee);
|
||||||
assertEquals(request3.tx.getInputs().size(), i - 2); // We should have spent all inputs - 2
|
assertEquals(request3.tx.getInputs().size(), i - 2); // We should have spent all inputs - 2
|
||||||
|
|
||||||
//
|
//
|
||||||
SendRequest request4 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
SendRequest request4 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||||
request4.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.divide(BigInteger.valueOf(request3.tx.bitcoinSerialize().length));
|
request4.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.divide(Coin.valueOf(request3.tx.bitcoinSerialize().length));
|
||||||
wallet.completeTx(request4);
|
wallet.completeTx(request4);
|
||||||
assertEquals(BigInteger.ONE, request4.fee);
|
assertEquals(Coin.ONE, request4.fee);
|
||||||
assertEquals(request4.tx.getInputs().size(), i - 2); // We should have spent all inputs - 2
|
assertEquals(request4.tx.getInputs().size(), i - 2); // We should have spent all inputs - 2
|
||||||
|
|
||||||
// Give us a few more inputs...
|
// Give us a few more inputs...
|
||||||
@ -1925,9 +1925,9 @@ public class WalletTest extends TestWithWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ...that is just slightly less than is needed for category 1
|
// ...that is just slightly less than is needed for category 1
|
||||||
SendRequest request5 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
SendRequest request5 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||||
wallet.completeTx(request5);
|
wallet.completeTx(request5);
|
||||||
assertEquals(BigInteger.ONE, request5.fee);
|
assertEquals(Coin.ONE, request5.fee);
|
||||||
assertEquals(1, request5.tx.getOutputs().size()); // We should have no change output
|
assertEquals(1, request5.tx.getOutputs().size()); // We should have no change output
|
||||||
|
|
||||||
// Give us one more input...
|
// Give us one more input...
|
||||||
@ -1936,9 +1936,9 @@ public class WalletTest extends TestWithWallet {
|
|||||||
wallet.receiveFromBlock(tx4, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
wallet.receiveFromBlock(tx4, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
||||||
|
|
||||||
// ... that puts us in category 1 (no fee!)
|
// ... that puts us in category 1 (no fee!)
|
||||||
SendRequest request6 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE));
|
SendRequest request6 = SendRequest.to(notMyAddr, CENT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE));
|
||||||
wallet.completeTx(request6);
|
wallet.completeTx(request6);
|
||||||
assertEquals(BigInteger.ZERO, request6.fee);
|
assertEquals(Coin.ZERO, request6.fee);
|
||||||
assertEquals(2, request6.tx.getOutputs().size()); // We should have a change output
|
assertEquals(2, request6.tx.getOutputs().size()); // We should have a change output
|
||||||
|
|
||||||
SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||||
@ -1956,14 +1956,14 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Generate a ton of small outputs
|
// Generate a ton of small outputs
|
||||||
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
|
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
while (i <= CENT.divide(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.TEN)).longValue()) {
|
while (i <= CENT.divide(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.TEN)).longValue()) {
|
||||||
Transaction tx = createFakeTxWithChangeAddress(params, Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.TEN), myAddress, notMyAddr);
|
Transaction tx = createFakeTxWithChangeAddress(params, Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.TEN), myAddress, notMyAddr);
|
||||||
tx.getInput(0).setSequenceNumber(i++); // Keep every transaction unique
|
tx.getInput(0).setSequenceNumber(i++); // Keep every transaction unique
|
||||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The selector will choose 2 with MIN_TX_FEE fee
|
// The selector will choose 2 with MIN_TX_FEE fee
|
||||||
SendRequest request1 = SendRequest.to(notMyAddr, CENT.add(BigInteger.ONE));
|
SendRequest request1 = SendRequest.to(notMyAddr, CENT.add(Coin.ONE));
|
||||||
wallet.completeTx(request1);
|
wallet.completeTx(request1);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request1.fee);
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request1.fee);
|
||||||
assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs
|
assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs
|
||||||
@ -2002,16 +2002,16 @@ public class WalletTest extends TestWithWallet {
|
|||||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
Transaction tx2 = createFakeTx(params, CENT, myAddress);
|
Transaction tx2 = createFakeTx(params, CENT, myAddress);
|
||||||
wallet.receiveFromBlock(tx2, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 1);
|
wallet.receiveFromBlock(tx2, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 1);
|
||||||
Transaction tx3 = createFakeTx(params, BigInteger.ONE, myAddress);
|
Transaction tx3 = createFakeTx(params, Coin.ONE, myAddress);
|
||||||
wallet.receiveFromBlock(tx3, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 2);
|
wallet.receiveFromBlock(tx3, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 2);
|
||||||
|
|
||||||
// Create a transaction who's max size could be up to 1000 (if signatures were maximum size)
|
// Create a transaction who's max size could be up to 1000 (if signatures were maximum size)
|
||||||
SendRequest request1 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.multiply(BigInteger.valueOf(17))));
|
SendRequest request1 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.multiply(Coin.valueOf(17))));
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
request1.tx.addOutput(CENT, notMyAddr);
|
request1.tx.addOutput(CENT, notMyAddr);
|
||||||
request1.tx.addOutput(new TransactionOutput(params, request1.tx, CENT, new byte[16]));
|
request1.tx.addOutput(new TransactionOutput(params, request1.tx, CENT, new byte[16]));
|
||||||
request1.fee = BigInteger.ONE;
|
request1.fee = Coin.ONE;
|
||||||
request1.feePerKb = BigInteger.ONE;
|
request1.feePerKb = Coin.ONE;
|
||||||
// We get a category 2 using COIN+CENT
|
// We get a category 2 using COIN+CENT
|
||||||
// It spends COIN + 1(fee) and because its output is thus < CENT, we have to pay MIN_TX_FEE
|
// It spends COIN + 1(fee) and because its output is thus < CENT, we have to pay MIN_TX_FEE
|
||||||
// When it tries category 1, its too large and requires COIN + 2 (fee)
|
// When it tries category 1, its too large and requires COIN + 2 (fee)
|
||||||
@ -2021,18 +2021,18 @@ public class WalletTest extends TestWithWallet {
|
|||||||
assertEquals(2, request1.tx.getInputs().size());
|
assertEquals(2, request1.tx.getInputs().size());
|
||||||
|
|
||||||
// We then add one more satoshi output to the wallet
|
// We then add one more satoshi output to the wallet
|
||||||
Transaction tx4 = createFakeTx(params, BigInteger.ONE, myAddress);
|
Transaction tx4 = createFakeTx(params, Coin.ONE, myAddress);
|
||||||
wallet.receiveFromBlock(tx4, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 3);
|
wallet.receiveFromBlock(tx4, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 3);
|
||||||
|
|
||||||
// Create a transaction who's max size could be up to 1000 (if signatures were maximum size)
|
// Create a transaction who's max size could be up to 1000 (if signatures were maximum size)
|
||||||
SendRequest request2 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.multiply(BigInteger.valueOf(17))));
|
SendRequest request2 = SendRequest.to(notMyAddr, Utils.COIN.subtract(CENT.multiply(Coin.valueOf(17))));
|
||||||
for (int i = 0; i < 16; i++)
|
for (int i = 0; i < 16; i++)
|
||||||
request2.tx.addOutput(CENT, notMyAddr);
|
request2.tx.addOutput(CENT, notMyAddr);
|
||||||
request2.tx.addOutput(new TransactionOutput(params, request2.tx, CENT, new byte[16]));
|
request2.tx.addOutput(new TransactionOutput(params, request2.tx, CENT, new byte[16]));
|
||||||
request2.feePerKb = BigInteger.ONE;
|
request2.feePerKb = Coin.ONE;
|
||||||
// The process is the same as above, but now we can complete category 1 with one more input, and pay a fee of 2
|
// The process is the same as above, but now we can complete category 1 with one more input, and pay a fee of 2
|
||||||
wallet.completeTx(request2);
|
wallet.completeTx(request2);
|
||||||
assertEquals(BigInteger.valueOf(2), request2.fee);
|
assertEquals(Coin.valueOf(2), request2.fee);
|
||||||
assertEquals(4, request2.tx.getInputs().size());
|
assertEquals(4, request2.tx.getInputs().size());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2107,7 +2107,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Check that if a wallet listener throws an exception, the others still run.
|
// Check that if a wallet listener throws an exception, the others still run.
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
log.info("onCoinsReceived 1");
|
log.info("onCoinsReceived 1");
|
||||||
throw new RuntimeException("barf");
|
throw new RuntimeException("barf");
|
||||||
}
|
}
|
||||||
@ -2115,7 +2115,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
final AtomicInteger flag = new AtomicInteger();
|
final AtomicInteger flag = new AtomicInteger();
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
log.info("onCoinsReceived 2");
|
log.info("onCoinsReceived 2");
|
||||||
flag.incrementAndGet();
|
flag.incrementAndGet();
|
||||||
}
|
}
|
||||||
@ -2134,13 +2134,13 @@ public class WalletTest extends TestWithWallet {
|
|||||||
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, new ECKey().toAddress(params)), BigInteger.ONE, 1);
|
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, new ECKey().toAddress(params)), BigInteger.ONE, 1);
|
||||||
Random rng = new Random();
|
Random rng = new Random();
|
||||||
for (int i = 0; i < rng.nextInt(100) + 1; i++) {
|
for (int i = 0; i < rng.nextInt(100) + 1; i++) {
|
||||||
Transaction tx = createFakeTx(params, BigInteger.valueOf(rng.nextInt((int) Utils.COIN.longValue())), myAddress);
|
Transaction tx = createFakeTx(params, Coin.valueOf(rng.nextInt((int) Utils.COIN.longValue())), myAddress);
|
||||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, i);
|
||||||
}
|
}
|
||||||
SendRequest request = SendRequest.emptyWallet(new ECKey().toAddress(params));
|
SendRequest request = SendRequest.emptyWallet(new ECKey().toAddress(params));
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
wallet.commitTx(request.tx);
|
wallet.commitTx(request.tx);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -2153,7 +2153,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
SendRequest request = SendRequest.emptyWallet(outputKey);
|
SendRequest request = SendRequest.emptyWallet(outputKey);
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
wallet.commitTx(request.tx);
|
wallet.commitTx(request.tx);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(CENT, request.tx.getOutput(0).getValue());
|
assertEquals(CENT, request.tx.getOutput(0).getValue());
|
||||||
|
|
||||||
// Add 1 confirmed cent and 1 unconfirmed cent. Verify only one cent is emptied because of the coin selection
|
// Add 1 confirmed cent and 1 unconfirmed cent. Verify only one cent is emptied because of the coin selection
|
||||||
@ -2166,22 +2166,22 @@ public class WalletTest extends TestWithWallet {
|
|||||||
request = SendRequest.emptyWallet(outputKey);
|
request = SendRequest.emptyWallet(outputKey);
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
wallet.commitTx(request.tx);
|
wallet.commitTx(request.tx);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(CENT, request.tx.getOutput(0).getValue());
|
assertEquals(CENT, request.tx.getOutput(0).getValue());
|
||||||
|
|
||||||
// Add just under 0.01
|
// Add just under 0.01
|
||||||
StoredBlock block2 = new StoredBlock(block.getHeader().createNextBlock(outputKey), BigInteger.ONE, 2);
|
StoredBlock block2 = new StoredBlock(block.getHeader().createNextBlock(outputKey), BigInteger.ONE, 2);
|
||||||
tx = createFakeTx(params, CENT.subtract(BigInteger.ONE), myAddress);
|
tx = createFakeTx(params, CENT.subtract(Coin.ONE), myAddress);
|
||||||
wallet.receiveFromBlock(tx, block2, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(tx, block2, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
request = SendRequest.emptyWallet(outputKey);
|
request = SendRequest.emptyWallet(outputKey);
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
wallet.commitTx(request.tx);
|
wallet.commitTx(request.tx);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(CENT.subtract(BigInteger.ONE).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), request.tx.getOutput(0).getValue());
|
assertEquals(CENT.subtract(Coin.ONE).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), request.tx.getOutput(0).getValue());
|
||||||
|
|
||||||
// Add an unsendable value
|
// Add an unsendable value
|
||||||
StoredBlock block3 = new StoredBlock(block2.getHeader().createNextBlock(outputKey), BigInteger.ONE, 3);
|
StoredBlock block3 = new StoredBlock(block2.getHeader().createNextBlock(outputKey), BigInteger.ONE, 3);
|
||||||
BigInteger outputValue = Transaction.MIN_NONDUST_OUTPUT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(BigInteger.ONE);
|
Coin outputValue = Transaction.MIN_NONDUST_OUTPUT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(Coin.ONE);
|
||||||
tx = createFakeTx(params, outputValue, myAddress);
|
tx = createFakeTx(params, outputValue, myAddress);
|
||||||
wallet.receiveFromBlock(tx, block3, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(tx, block3, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
request = SendRequest.emptyWallet(outputKey);
|
request = SendRequest.emptyWallet(outputKey);
|
||||||
@ -2192,7 +2192,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
request.ensureMinRequiredFee = false;
|
request.ensureMinRequiredFee = false;
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
wallet.commitTx(request.tx);
|
wallet.commitTx(request.tx);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(outputValue, request.tx.getOutput(0).getValue());
|
assertEquals(outputValue, request.tx.getOutput(0).getValue());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2220,7 +2220,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
wallet.setKeyRotationTime(compromiseTime);
|
wallet.setKeyRotationTime(compromiseTime);
|
||||||
assertTrue(wallet.isKeyRotating(key1));
|
assertTrue(wallet.isKeyRotating(key1));
|
||||||
Transaction tx = broadcaster.waitForTransaction();
|
Transaction tx = broadcaster.waitForTransaction();
|
||||||
final BigInteger THREE_CENTS = CENT.add(CENT).add(CENT);
|
final Coin THREE_CENTS = CENT.add(CENT).add(CENT);
|
||||||
assertEquals(THREE_CENTS, tx.getValueSentFromMe(wallet));
|
assertEquals(THREE_CENTS, tx.getValueSentFromMe(wallet));
|
||||||
assertEquals(THREE_CENTS.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), tx.getValueSentToMe(wallet));
|
assertEquals(THREE_CENTS.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), tx.getValueSentToMe(wallet));
|
||||||
// TX is a raw pay to pubkey.
|
// TX is a raw pay to pubkey.
|
||||||
@ -2281,11 +2281,11 @@ public class WalletTest extends TestWithWallet {
|
|||||||
wallet.setKeyRotationTime(compromise);
|
wallet.setKeyRotationTime(compromise);
|
||||||
|
|
||||||
Transaction tx = broadcaster.waitForTransaction();
|
Transaction tx = broadcaster.waitForTransaction();
|
||||||
final BigInteger valueSentToMe = tx.getValueSentToMe(wallet);
|
final Coin valueSentToMe = tx.getValueSentToMe(wallet);
|
||||||
BigInteger fee = tx.getValueSentFromMe(wallet).subtract(valueSentToMe);
|
Coin fee = tx.getValueSentFromMe(wallet).subtract(valueSentToMe);
|
||||||
assertEquals(BigInteger.valueOf(900000), fee);
|
assertEquals(Coin.valueOf(900000), fee);
|
||||||
assertEquals(KeyTimeCoinSelector.MAX_SIMULTANEOUS_INPUTS, tx.getInputs().size());
|
assertEquals(KeyTimeCoinSelector.MAX_SIMULTANEOUS_INPUTS, tx.getInputs().size());
|
||||||
assertEquals(BigInteger.valueOf(599100000), valueSentToMe);
|
assertEquals(Coin.valueOf(599100000), valueSentToMe);
|
||||||
|
|
||||||
tx = broadcaster.waitForTransaction();
|
tx = broadcaster.waitForTransaction();
|
||||||
assertNotNull(tx);
|
assertNotNull(tx);
|
||||||
@ -2347,11 +2347,11 @@ public class WalletTest extends TestWithWallet {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
assertTrue(wallet.isPendingTransactionRelevant(tx));
|
assertTrue(wallet.isPendingTransactionRelevant(tx));
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
assertEquals(Coin.ZERO, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||||
wallet.receivePending(tx, null);
|
wallet.receivePending(tx, null);
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
assertEquals(Coin.ZERO, wallet.getBalance(Wallet.BalanceType.ESTIMATED));
|
||||||
assertTrue(bool.get());
|
assertTrue(bool.get());
|
||||||
// Confirm it in the same manner as how Bloom filtered blocks do. Verify it shows up.
|
// Confirm it in the same manner as how Bloom filtered blocks do. Verify it shows up.
|
||||||
StoredBlock block = createFakeBlock(blockStore, tx).storedBlock;
|
StoredBlock block = createFakeBlock(blockStore, tx).storedBlock;
|
||||||
|
@ -33,7 +33,6 @@ import javax.annotation.Nullable;
|
|||||||
import java.io.ByteArrayInputStream;
|
import java.io.ByteArrayInputStream;
|
||||||
import java.io.ByteArrayOutputStream;
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
@ -116,7 +115,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
// Test with network code and without any issues. We'll broadcast two txns: multisig contract and settle transaction.
|
// Test with network code and without any issues. We'll broadcast two txns: multisig contract and settle transaction.
|
||||||
final SettableFuture<ListenableFuture<PaymentChannelServerState>> serverCloseFuture = SettableFuture.create();
|
final SettableFuture<ListenableFuture<PaymentChannelServerState>> serverCloseFuture = SettableFuture.create();
|
||||||
final SettableFuture<Sha256Hash> channelOpenFuture = SettableFuture.create();
|
final SettableFuture<Sha256Hash> channelOpenFuture = SettableFuture.create();
|
||||||
final BlockingQueue<BigInteger> q = new LinkedBlockingQueue<BigInteger>();
|
final BlockingQueue<Coin> q = new LinkedBlockingQueue<Coin>();
|
||||||
final PaymentChannelServerListener server = new PaymentChannelServerListener(mockBroadcaster, serverWallet, 30, Utils.COIN,
|
final PaymentChannelServerListener server = new PaymentChannelServerListener(mockBroadcaster, serverWallet, 30, Utils.COIN,
|
||||||
new PaymentChannelServerListener.HandlerFactory() {
|
new PaymentChannelServerListener.HandlerFactory() {
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -129,7 +128,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paymentIncrease(BigInteger by, BigInteger to) {
|
public void paymentIncrease(Coin by, Coin to) {
|
||||||
q.add(to);
|
q.add(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -169,7 +168,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
});
|
});
|
||||||
|
|
||||||
Thread.sleep(1250); // No timeouts once the channel is open
|
Thread.sleep(1250); // No timeouts once the channel is open
|
||||||
BigInteger amount = client.state().getValueSpent();
|
Coin amount = client.state().getValueSpent();
|
||||||
assertEquals(amount, q.take());
|
assertEquals(amount, q.take());
|
||||||
client.incrementPayment(Utils.CENT).get();
|
client.incrementPayment(Utils.CENT).get();
|
||||||
amount = amount.add(Utils.CENT);
|
amount = amount.add(Utils.CENT);
|
||||||
@ -193,7 +192,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
broadcastTxPause.release();
|
broadcastTxPause.release();
|
||||||
Transaction settleTx = broadcasts.take();
|
Transaction settleTx = broadcasts.take();
|
||||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||||
if (!serverState.getBestValueToMe().equals(amount) || !serverState.getFeePaid().equals(BigInteger.ZERO))
|
if (!serverState.getBestValueToMe().equals(amount) || !serverState.getFeePaid().equals(Coin.ZERO))
|
||||||
fail();
|
fail();
|
||||||
assertTrue(channels.mapChannels.isEmpty());
|
assertTrue(channels.mapChannels.isEmpty());
|
||||||
|
|
||||||
@ -282,7 +281,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
|
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.CLIENT_VERSION));
|
||||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
||||||
final Protos.TwoWayChannelMessage initiateMsg = pair.serverRecorder.checkNextMsg(MessageType.INITIATE);
|
final Protos.TwoWayChannelMessage initiateMsg = pair.serverRecorder.checkNextMsg(MessageType.INITIATE);
|
||||||
BigInteger minPayment = BigInteger.valueOf(initiateMsg.getInitiate().getMinPayment());
|
Coin minPayment = Coin.valueOf(initiateMsg.getInitiate().getMinPayment());
|
||||||
client.receiveMessage(initiateMsg);
|
client.receiveMessage(initiateMsg);
|
||||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_REFUND));
|
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.PROVIDE_REFUND));
|
||||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.RETURN_REFUND));
|
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.RETURN_REFUND));
|
||||||
@ -297,7 +296,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
assertNull(pair.clientRecorder.q.poll());
|
assertNull(pair.clientRecorder.q.poll());
|
||||||
assertEquals(minPayment, client.state().getValueSpent());
|
assertEquals(minPayment, client.state().getValueSpent());
|
||||||
// Send a bitcent.
|
// Send a bitcent.
|
||||||
BigInteger amount = minPayment.add(Utils.CENT);
|
Coin amount = minPayment.add(Utils.CENT);
|
||||||
client.incrementPayment(Utils.CENT);
|
client.incrementPayment(Utils.CENT);
|
||||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||||
assertEquals(amount, pair.serverRecorder.q.take());
|
assertEquals(amount, pair.serverRecorder.q.take());
|
||||||
@ -463,7 +462,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
assertEquals(CloseReason.NO_ACCEPTABLE_VERSION, pair.clientRecorder.q.take());
|
assertEquals(CloseReason.NO_ACCEPTABLE_VERSION, pair.clientRecorder.q.take());
|
||||||
// Double-check that we cant do anything that requires an open channel
|
// Double-check that we cant do anything that requires an open channel
|
||||||
try {
|
try {
|
||||||
client.incrementPayment(BigInteger.ONE);
|
client.incrementPayment(Coin.ONE);
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalStateException e) { }
|
} catch (IllegalStateException e) { }
|
||||||
}
|
}
|
||||||
@ -489,7 +488,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
assertEquals(CloseReason.TIME_WINDOW_TOO_LARGE, pair.clientRecorder.q.take());
|
assertEquals(CloseReason.TIME_WINDOW_TOO_LARGE, pair.clientRecorder.q.take());
|
||||||
// Double-check that we cant do anything that requires an open channel
|
// Double-check that we cant do anything that requires an open channel
|
||||||
try {
|
try {
|
||||||
client.incrementPayment(BigInteger.ONE);
|
client.incrementPayment(Coin.ONE);
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalStateException e) { }
|
} catch (IllegalStateException e) { }
|
||||||
}
|
}
|
||||||
@ -505,7 +504,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
||||||
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
|
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
|
||||||
.setInitiate(Protos.Initiate.newBuilder().setExpireTimeSecs(Utils.currentTimeSeconds())
|
.setInitiate(Protos.Initiate.newBuilder().setExpireTimeSecs(Utils.currentTimeSeconds())
|
||||||
.setMinAcceptedChannelSize(Utils.COIN.add(BigInteger.ONE).longValue())
|
.setMinAcceptedChannelSize(Utils.COIN.add(Coin.ONE).longValue())
|
||||||
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey()))
|
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey()))
|
||||||
.setMinPayment(Transaction.MIN_NONDUST_OUTPUT.longValue()))
|
.setMinPayment(Transaction.MIN_NONDUST_OUTPUT.longValue()))
|
||||||
.setType(MessageType.INITIATE).build());
|
.setType(MessageType.INITIATE).build());
|
||||||
@ -513,17 +512,17 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
assertEquals(CloseReason.SERVER_REQUESTED_TOO_MUCH_VALUE, pair.clientRecorder.q.take());
|
assertEquals(CloseReason.SERVER_REQUESTED_TOO_MUCH_VALUE, pair.clientRecorder.q.take());
|
||||||
// Double-check that we cant do anything that requires an open channel
|
// Double-check that we cant do anything that requires an open channel
|
||||||
try {
|
try {
|
||||||
client.incrementPayment(BigInteger.ONE);
|
client.incrementPayment(Coin.ONE);
|
||||||
fail();
|
fail();
|
||||||
} catch (IllegalStateException e) { }
|
} catch (IllegalStateException e) { }
|
||||||
|
|
||||||
// Now check that if the server has a lower min size than what we are willing to spend, we do actually open
|
// 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.
|
// a channel of that size.
|
||||||
sendMoneyToWallet(Utils.COIN.multiply(BigInteger.TEN), AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(Utils.COIN.multiply(Coin.TEN), AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
|
|
||||||
pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
|
pair = ChannelTestUtils.makeRecorders(serverWallet, mockBroadcaster);
|
||||||
server = pair.server;
|
server = pair.server;
|
||||||
final BigInteger myValue = Utils.COIN.multiply(BigInteger.TEN);
|
final Coin myValue = Utils.COIN.multiply(Coin.TEN);
|
||||||
client = new PaymentChannelClient(wallet, myKey, myValue, Sha256Hash.ZERO_HASH, pair.clientRecorder);
|
client = new PaymentChannelClient(wallet, myKey, myValue, Sha256Hash.ZERO_HASH, pair.clientRecorder);
|
||||||
client.connectionOpen();
|
client.connectionOpen();
|
||||||
server.connectionOpen();
|
server.connectionOpen();
|
||||||
@ -531,7 +530,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.SERVER_VERSION));
|
||||||
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
|
client.receiveMessage(Protos.TwoWayChannelMessage.newBuilder()
|
||||||
.setInitiate(Protos.Initiate.newBuilder().setExpireTimeSecs(Utils.currentTimeSeconds())
|
.setInitiate(Protos.Initiate.newBuilder().setExpireTimeSecs(Utils.currentTimeSeconds())
|
||||||
.setMinAcceptedChannelSize(Utils.COIN.add(BigInteger.ONE).longValue())
|
.setMinAcceptedChannelSize(Utils.COIN.add(Coin.ONE).longValue())
|
||||||
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey()))
|
.setMultisigKey(ByteString.copyFrom(new ECKey().getPubKey()))
|
||||||
.setMinPayment(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.longValue()))
|
.setMinPayment(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.longValue()))
|
||||||
.setType(MessageType.INITIATE).build());
|
.setType(MessageType.INITIATE).build());
|
||||||
@ -644,8 +643,8 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||||
broadcasts.take();
|
broadcasts.take();
|
||||||
// The channel is now empty.
|
// The channel is now empty.
|
||||||
assertEquals(BigInteger.ZERO, client.state().getValueRefunded());
|
assertEquals(Coin.ZERO, client.state().getValueRefunded());
|
||||||
pair.serverRecorder.q.take(); // Take the BigInteger.
|
pair.serverRecorder.q.take(); // Take the Coin.
|
||||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
|
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
|
||||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CLOSE));
|
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.CLOSE));
|
||||||
assertEquals(CloseReason.SERVER_REQUESTED_CLOSE, pair.clientRecorder.q.take());
|
assertEquals(CloseReason.SERVER_REQUESTED_CLOSE, pair.clientRecorder.q.take());
|
||||||
@ -684,7 +683,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
pair.clientRecorder.checkInitiated();
|
pair.clientRecorder.checkInitiated();
|
||||||
assertNull(pair.serverRecorder.q.poll());
|
assertNull(pair.serverRecorder.q.poll());
|
||||||
assertNull(pair.clientRecorder.q.poll());
|
assertNull(pair.clientRecorder.q.poll());
|
||||||
ListenableFuture<BigInteger> future = client.incrementPayment(Utils.CENT);
|
ListenableFuture<Coin> future = client.incrementPayment(Utils.CENT);
|
||||||
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
server.receiveMessage(pair.clientRecorder.checkNextMsg(MessageType.UPDATE_PAYMENT));
|
||||||
pair.serverRecorder.q.take();
|
pair.serverRecorder.q.take();
|
||||||
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
|
client.receiveMessage(pair.serverRecorder.checkNextMsg(MessageType.PAYMENT_ACK));
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
package com.google.bitcoin.protocols.channels;
|
package com.google.bitcoin.protocols.channels;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.Sha256Hash;
|
import com.google.bitcoin.core.Sha256Hash;
|
||||||
import com.google.bitcoin.core.TransactionBroadcaster;
|
import com.google.bitcoin.core.TransactionBroadcaster;
|
||||||
import com.google.bitcoin.core.Utils;
|
import com.google.bitcoin.core.Utils;
|
||||||
import com.google.bitcoin.core.Wallet;
|
import com.google.bitcoin.core.Wallet;
|
||||||
|
|
||||||
import org.bitcoin.paymentchannel.Protos;
|
import org.bitcoin.paymentchannel.Protos;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
import java.util.concurrent.LinkedBlockingQueue;
|
import java.util.concurrent.LinkedBlockingQueue;
|
||||||
|
|
||||||
@ -35,7 +36,7 @@ public class ChannelTestUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paymentIncrease(BigInteger by, BigInteger to) {
|
public void paymentIncrease(Coin by, Coin to) {
|
||||||
q.add(to);
|
q.add(to);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,8 +50,8 @@ public class ChannelTestUtils {
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void checkTotalPayment(BigInteger valueSoFar) throws InterruptedException {
|
public void checkTotalPayment(Coin valueSoFar) throws InterruptedException {
|
||||||
BigInteger lastSeen = (BigInteger) q.take();
|
Coin lastSeen = (Coin) q.take();
|
||||||
assertEquals(lastSeen, valueSoFar);
|
assertEquals(lastSeen, valueSoFar);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,7 +40,7 @@ import static org.junit.Assert.*;
|
|||||||
|
|
||||||
public class PaymentChannelStateTest extends TestWithWallet {
|
public class PaymentChannelStateTest extends TestWithWallet {
|
||||||
private ECKey serverKey;
|
private ECKey serverKey;
|
||||||
private BigInteger halfCoin;
|
private Coin halfCoin;
|
||||||
private Wallet serverWallet;
|
private Wallet serverWallet;
|
||||||
private PaymentChannelServerState serverState;
|
private PaymentChannelServerState serverState;
|
||||||
private PaymentChannelClientState clientState;
|
private PaymentChannelClientState clientState;
|
||||||
@ -94,7 +94,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
@Test
|
@Test
|
||||||
public void stateErrors() throws Exception {
|
public void stateErrors() throws Exception {
|
||||||
PaymentChannelClientState channelState = new PaymentChannelClientState(wallet, myKey, serverKey,
|
PaymentChannelClientState channelState = new PaymentChannelClientState(wallet, myKey, serverKey,
|
||||||
Utils.COIN.multiply(BigInteger.TEN), 20);
|
Utils.COIN.multiply(Coin.TEN), 20);
|
||||||
assertEquals(PaymentChannelClientState.State.NEW, channelState.getState());
|
assertEquals(PaymentChannelClientState.State.NEW, channelState.getState());
|
||||||
try {
|
try {
|
||||||
channelState.getMultisigContract();
|
channelState.getMultisigContract();
|
||||||
@ -164,8 +164,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertFalse(clientWalletMultisigContract.getInput(0).getConnectedOutput().getSpentBy().getParentTransaction().getHash().equals(refund.getHash()));
|
assertFalse(clientWalletMultisigContract.getInput(0).getConnectedOutput().getSpentBy().getParentTransaction().getHash().equals(refund.getHash()));
|
||||||
|
|
||||||
// Both client and server are now in the ready state. Simulate a few micropayments of 0.005 bitcoins.
|
// Both client and server are now in the ready state. Simulate a few micropayments of 0.005 bitcoins.
|
||||||
BigInteger size = halfCoin.divide(BigInteger.TEN).divide(BigInteger.TEN);
|
Coin size = halfCoin.divide(Coin.TEN).divide(Coin.TEN);
|
||||||
BigInteger totalPayment = BigInteger.ZERO;
|
Coin totalPayment = Coin.ZERO;
|
||||||
for (int i = 0; i < 4; i++) {
|
for (int i = 0; i < 4; i++) {
|
||||||
byte[] signature = clientState.incrementPaymentBy(size).signature.encodeToBitcoin();
|
byte[] signature = clientState.incrementPaymentBy(size).signature.encodeToBitcoin();
|
||||||
totalPayment = totalPayment.add(size);
|
totalPayment = totalPayment.add(size);
|
||||||
@ -194,10 +194,10 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
// Create a block with the payment transaction in it and give it to both wallets
|
// Create a block with the payment transaction in it and give it to both wallets
|
||||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), reserializedCloseTx));
|
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), reserializedCloseTx));
|
||||||
|
|
||||||
assertEquals(size.multiply(BigInteger.valueOf(5)), serverWallet.getBalance());
|
assertEquals(size.multiply(Coin.valueOf(5)), serverWallet.getBalance());
|
||||||
assertEquals(0, serverWallet.getPendingTransactions().size());
|
assertEquals(0, serverWallet.getPendingTransactions().size());
|
||||||
|
|
||||||
assertEquals(Utils.COIN.subtract(size.multiply(BigInteger.valueOf(5))), wallet.getBalance());
|
assertEquals(Utils.COIN.subtract(size.multiply(Coin.valueOf(5))), wallet.getBalance());
|
||||||
assertEquals(0, wallet.getPendingTransactions().size());
|
assertEquals(0, wallet.getPendingTransactions().size());
|
||||||
assertEquals(3, wallet.getTransactions(false).size());
|
assertEquals(3, wallet.getTransactions(false).size());
|
||||||
|
|
||||||
@ -218,7 +218,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
|
|
||||||
// Spend the client wallet's one coin
|
// 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), Utils.COIN));
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), spendCoinTx, createFakeTx(params, Utils.CENT, myAddress)));
|
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), spendCoinTx, createFakeTx(params, Utils.CENT, myAddress)));
|
||||||
assertEquals(Utils.CENT, wallet.getBalance());
|
assertEquals(Utils.CENT, wallet.getBalance());
|
||||||
|
|
||||||
@ -233,12 +233,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
||||||
|
|
||||||
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()),
|
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()),
|
||||||
Utils.CENT.divide(BigInteger.valueOf(2)), EXPIRE_TIME);
|
Utils.CENT.divide(Coin.valueOf(2)), EXPIRE_TIME);
|
||||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||||
assertEquals(Utils.CENT.divide(BigInteger.valueOf(2)), clientState.getTotalValue());
|
assertEquals(Utils.CENT.divide(Coin.valueOf(2)), clientState.getTotalValue());
|
||||||
clientState.initiate();
|
clientState.initiate();
|
||||||
// We will have to pay min_tx_fee twice - both the multisig contract and the refund tx
|
// We will have to pay min_tx_fee twice - both the multisig contract and the refund tx
|
||||||
assertEquals(clientState.getRefundTxFees(), Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(2)));
|
assertEquals(clientState.getRefundTxFees(), Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(2)));
|
||||||
assertEquals(PaymentChannelClientState.State.INITIATED, clientState.getState());
|
assertEquals(PaymentChannelClientState.State.INITIATED, clientState.getState());
|
||||||
|
|
||||||
// Send the refund tx from client to server and get back the signature.
|
// Send the refund tx from client to server and get back the signature.
|
||||||
@ -269,8 +269,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||||
|
|
||||||
// Pay a tiny bit
|
// Pay a tiny bit
|
||||||
serverState.incrementPayment(Utils.CENT.divide(BigInteger.valueOf(2)).subtract(Utils.CENT.divide(BigInteger.TEN)),
|
serverState.incrementPayment(Utils.CENT.divide(Coin.valueOf(2)).subtract(Utils.CENT.divide(Coin.TEN)),
|
||||||
clientState.incrementPaymentBy(Utils.CENT.divide(BigInteger.TEN)).signature.encodeToBitcoin());
|
clientState.incrementPaymentBy(Utils.CENT.divide(Coin.TEN)).signature.encodeToBitcoin());
|
||||||
|
|
||||||
// Advance time until our we get close enough to lock time that server should rebroadcast
|
// Advance time until our we get close enough to lock time that server should rebroadcast
|
||||||
Utils.rollMockClock(60*60*22);
|
Utils.rollMockClock(60*60*22);
|
||||||
@ -313,7 +313,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), multisigContract,clientBroadcastedRefund));
|
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), multisigContract,clientBroadcastedRefund));
|
||||||
|
|
||||||
// Make sure we actually had to pay what initialize() told us we would
|
// Make sure we actually had to pay what initialize() told us we would
|
||||||
assertEquals(wallet.getBalance(), Utils.CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(2))));
|
assertEquals(wallet.getBalance(), Utils.CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(2))));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// After its expired, we cant still increment payment
|
// After its expired, we cant still increment payment
|
||||||
@ -341,7 +341,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
// Test refund transaction with any number of issues
|
// Test refund transaction with any number of issues
|
||||||
byte[] refundTxBytes = clientState.getIncompleteRefundTransaction().bitcoinSerialize();
|
byte[] refundTxBytes = clientState.getIncompleteRefundTransaction().bitcoinSerialize();
|
||||||
Transaction refund = new Transaction(params, refundTxBytes);
|
Transaction refund = new Transaction(params, refundTxBytes);
|
||||||
refund.addOutput(BigInteger.ZERO, new ECKey().toAddress(params));
|
refund.addOutput(Coin.ZERO, new ECKey().toAddress(params));
|
||||||
try {
|
try {
|
||||||
serverState.provideRefundTransaction(refund, myKey.getPubKey());
|
serverState.provideRefundTransaction(refund, myKey.getPubKey());
|
||||||
fail();
|
fail();
|
||||||
@ -408,7 +408,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
clientState.fakeSave();
|
clientState.fakeSave();
|
||||||
assertEquals(PaymentChannelClientState.State.PROVIDE_MULTISIG_CONTRACT_TO_SERVER, clientState.getState());
|
assertEquals(PaymentChannelClientState.State.PROVIDE_MULTISIG_CONTRACT_TO_SERVER, clientState.getState());
|
||||||
|
|
||||||
try { clientState.incrementPaymentBy(BigInteger.ONE); fail(); } catch (IllegalStateException e) {}
|
try { clientState.incrementPaymentBy(Coin.ONE); fail(); } catch (IllegalStateException e) {}
|
||||||
|
|
||||||
byte[] multisigContractSerialized = clientState.getMultisigContract().bitcoinSerialize();
|
byte[] multisigContractSerialized = clientState.getMultisigContract().bitcoinSerialize();
|
||||||
|
|
||||||
@ -424,7 +424,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
|
|
||||||
multisigContract = new Transaction(params, multisigContractSerialized);
|
multisigContract = new Transaction(params, multisigContractSerialized);
|
||||||
multisigContract.clearOutputs();
|
multisigContract.clearOutputs();
|
||||||
multisigContract.addOutput(BigInteger.ZERO, ScriptBuilder.createMultiSigOutputScript(2, Lists.newArrayList(myKey, serverKey)));
|
multisigContract.addOutput(Coin.ZERO, ScriptBuilder.createMultiSigOutputScript(2, Lists.newArrayList(myKey, serverKey)));
|
||||||
try {
|
try {
|
||||||
serverState.provideMultiSigContract(multisigContract);
|
serverState.provideMultiSigContract(multisigContract);
|
||||||
fail();
|
fail();
|
||||||
@ -451,8 +451,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||||
|
|
||||||
// Both client and server are now in the ready state. Simulate a few micropayments of 0.005 bitcoins.
|
// Both client and server are now in the ready state. Simulate a few micropayments of 0.005 bitcoins.
|
||||||
BigInteger size = halfCoin.divide(BigInteger.TEN).divide(BigInteger.TEN);
|
Coin size = halfCoin.divide(Coin.TEN).divide(Coin.TEN);
|
||||||
BigInteger totalPayment = BigInteger.ZERO;
|
Coin totalPayment = Coin.ZERO;
|
||||||
try {
|
try {
|
||||||
clientState.incrementPaymentBy(Utils.COIN);
|
clientState.incrementPaymentBy(Utils.COIN);
|
||||||
fail();
|
fail();
|
||||||
@ -510,12 +510,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertEquals(serverState.getBestValueToMe(), totalPayment);
|
assertEquals(serverState.getBestValueToMe(), totalPayment);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
clientState.incrementPaymentBy(BigInteger.ONE.negate());
|
clientState.incrementPaymentBy(Coin.ONE.negate());
|
||||||
fail();
|
fail();
|
||||||
} catch (ValueOutOfRangeException e) {}
|
} catch (ValueOutOfRangeException e) {}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
clientState.incrementPaymentBy(halfCoin.subtract(size).add(BigInteger.ONE));
|
clientState.incrementPaymentBy(halfCoin.subtract(size).add(Coin.ONE));
|
||||||
fail();
|
fail();
|
||||||
} catch (ValueOutOfRangeException e) {}
|
} catch (ValueOutOfRangeException e) {}
|
||||||
}
|
}
|
||||||
@ -526,7 +526,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
|
|
||||||
// Spend the client wallet's one coin
|
// 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), Utils.COIN));
|
||||||
assertEquals(BigInteger.ZERO, wallet.getBalance());
|
assertEquals(Coin.ZERO, wallet.getBalance());
|
||||||
|
|
||||||
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), createFakeTx(params, Utils.CENT, myAddress)));
|
chain.add(makeSolvedTestBlock(blockStore.getChainHead().getHeader(), createFakeTx(params, Utils.CENT, myAddress)));
|
||||||
assertEquals(Utils.CENT, wallet.getBalance());
|
assertEquals(Utils.CENT, wallet.getBalance());
|
||||||
@ -538,7 +538,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.WAITING_FOR_REFUND_TRANSACTION, serverState.getState());
|
||||||
|
|
||||||
// Clearly ONE is far too small to be useful
|
// Clearly ONE is far too small to be useful
|
||||||
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()), BigInteger.ONE, EXPIRE_TIME);
|
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()), Coin.ONE, EXPIRE_TIME);
|
||||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||||
try {
|
try {
|
||||||
clientState.initiate();
|
clientState.initiate();
|
||||||
@ -546,7 +546,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
} catch (ValueOutOfRangeException e) {}
|
} catch (ValueOutOfRangeException e) {}
|
||||||
|
|
||||||
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()),
|
clientState = new PaymentChannelClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()),
|
||||||
Transaction.MIN_NONDUST_OUTPUT.subtract(BigInteger.ONE).add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE),
|
Transaction.MIN_NONDUST_OUTPUT.subtract(Coin.ONE).add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE),
|
||||||
EXPIRE_TIME);
|
EXPIRE_TIME);
|
||||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||||
try {
|
try {
|
||||||
@ -560,14 +560,14 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||||
// We'll have to pay REFERENCE_DEFAULT_MIN_TX_FEE twice (multisig+refund), and we'll end up getting back nearly nothing...
|
// We'll have to pay REFERENCE_DEFAULT_MIN_TX_FEE twice (multisig+refund), and we'll end up getting back nearly nothing...
|
||||||
clientState.initiate();
|
clientState.initiate();
|
||||||
assertEquals(clientState.getRefundTxFees(), Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(2)));
|
assertEquals(clientState.getRefundTxFees(), Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(Coin.valueOf(2)));
|
||||||
assertEquals(PaymentChannelClientState.State.INITIATED, clientState.getState());
|
assertEquals(PaymentChannelClientState.State.INITIATED, clientState.getState());
|
||||||
|
|
||||||
// Now actually use a more useful CENT
|
// 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()), Utils.CENT, EXPIRE_TIME);
|
||||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||||
clientState.initiate();
|
clientState.initiate();
|
||||||
assertEquals(clientState.getRefundTxFees(), BigInteger.ZERO);
|
assertEquals(clientState.getRefundTxFees(), Coin.ZERO);
|
||||||
assertEquals(PaymentChannelClientState.State.INITIATED, clientState.getState());
|
assertEquals(PaymentChannelClientState.State.INITIATED, clientState.getState());
|
||||||
|
|
||||||
// Send the refund tx from client to server and get back the signature.
|
// Send the refund tx from client to server and get back the signature.
|
||||||
@ -592,16 +592,16 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||||
|
|
||||||
// Both client and server are now in the ready state. Simulate a few micropayments
|
// Both client and server are now in the ready state. Simulate a few micropayments
|
||||||
BigInteger totalPayment = BigInteger.ZERO;
|
Coin totalPayment = Coin.ZERO;
|
||||||
|
|
||||||
// We can send as little as we want - its up to the server to get the fees right
|
// We can send as little as we want - its up to the server to get the fees right
|
||||||
byte[] signature = clientState.incrementPaymentBy(BigInteger.ONE).signature.encodeToBitcoin();
|
byte[] signature = clientState.incrementPaymentBy(Coin.ONE).signature.encodeToBitcoin();
|
||||||
totalPayment = totalPayment.add(BigInteger.ONE);
|
totalPayment = totalPayment.add(Coin.ONE);
|
||||||
serverState.incrementPayment(Utils.CENT.subtract(totalPayment), signature);
|
serverState.incrementPayment(Utils.CENT.subtract(totalPayment), signature);
|
||||||
|
|
||||||
// We can't refund more than the contract is worth...
|
// We can't refund more than the contract is worth...
|
||||||
try {
|
try {
|
||||||
serverState.incrementPayment(Utils.CENT.add(BigInteger.ONE), signature);
|
serverState.incrementPayment(Utils.CENT.add(Coin.ONE), signature);
|
||||||
fail();
|
fail();
|
||||||
} catch (ValueOutOfRangeException e) {}
|
} catch (ValueOutOfRangeException e) {}
|
||||||
|
|
||||||
@ -609,12 +609,12 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
// will correct it for us to be larger than the requested amount, to make the change output zero.
|
// will correct it for us to be larger than the requested amount, to make the change output zero.
|
||||||
PaymentChannelClientState.IncrementedPayment payment =
|
PaymentChannelClientState.IncrementedPayment payment =
|
||||||
clientState.incrementPaymentBy(Utils.CENT.subtract(Transaction.MIN_NONDUST_OUTPUT));
|
clientState.incrementPaymentBy(Utils.CENT.subtract(Transaction.MIN_NONDUST_OUTPUT));
|
||||||
assertEquals(Utils.CENT.subtract(BigInteger.ONE), payment.amount);
|
assertEquals(Utils.CENT.subtract(Coin.ONE), payment.amount);
|
||||||
totalPayment = totalPayment.add(payment.amount);
|
totalPayment = totalPayment.add(payment.amount);
|
||||||
|
|
||||||
// The server also won't accept it if we do that.
|
// The server also won't accept it if we do that.
|
||||||
try {
|
try {
|
||||||
serverState.incrementPayment(Transaction.MIN_NONDUST_OUTPUT.subtract(BigInteger.ONE), signature);
|
serverState.incrementPayment(Transaction.MIN_NONDUST_OUTPUT.subtract(Coin.ONE), signature);
|
||||||
fail();
|
fail();
|
||||||
} catch (ValueOutOfRangeException e) {}
|
} catch (ValueOutOfRangeException e) {}
|
||||||
|
|
||||||
@ -678,9 +678,9 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.READY, serverState.getState());
|
||||||
|
|
||||||
// Both client and server are now in the ready state, split the channel in half
|
// Both client and server are now in the ready state, split the channel in half
|
||||||
byte[] signature = clientState.incrementPaymentBy(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(BigInteger.ONE))
|
byte[] signature = clientState.incrementPaymentBy(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(Coin.ONE))
|
||||||
.signature.encodeToBitcoin();
|
.signature.encodeToBitcoin();
|
||||||
BigInteger totalRefund = Utils.CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(BigInteger.ONE));
|
Coin totalRefund = Utils.CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(Coin.ONE));
|
||||||
serverState.incrementPayment(totalRefund, signature);
|
serverState.incrementPayment(totalRefund, signature);
|
||||||
|
|
||||||
// We need to pay MIN_TX_FEE, but we only have MIN_NONDUST_OUTPUT
|
// We need to pay MIN_TX_FEE, but we only have MIN_NONDUST_OUTPUT
|
||||||
@ -703,8 +703,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertTrue(e.getMessage().contains("more in fees"));
|
assertTrue(e.getMessage().contains("more in fees"));
|
||||||
}
|
}
|
||||||
|
|
||||||
signature = clientState.incrementPaymentBy(BigInteger.ONE.shiftLeft(1)).signature.encodeToBitcoin();
|
signature = clientState.incrementPaymentBy(Coin.ONE.shiftLeft(1)).signature.encodeToBitcoin();
|
||||||
totalRefund = totalRefund.subtract(BigInteger.ONE.shiftLeft(1));
|
totalRefund = totalRefund.subtract(Coin.ONE.shiftLeft(1));
|
||||||
serverState.incrementPayment(totalRefund, signature);
|
serverState.incrementPayment(totalRefund, signature);
|
||||||
|
|
||||||
// And settle the channel.
|
// And settle the channel.
|
||||||
@ -772,8 +772,8 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
assertFalse(clientWalletMultisigContract.getInput(0).getConnectedOutput().getSpentBy().getParentTransaction().getHash().equals(refund.getHash()));
|
assertFalse(clientWalletMultisigContract.getInput(0).getConnectedOutput().getSpentBy().getParentTransaction().getHash().equals(refund.getHash()));
|
||||||
|
|
||||||
// Both client and server are now in the ready state. Simulate a few micropayments of 0.005 bitcoins.
|
// Both client and server are now in the ready state. Simulate a few micropayments of 0.005 bitcoins.
|
||||||
BigInteger size = halfCoin.divide(BigInteger.TEN).divide(BigInteger.TEN);
|
Coin size = halfCoin.divide(Coin.TEN).divide(Coin.TEN);
|
||||||
BigInteger totalPayment = BigInteger.ZERO;
|
Coin totalPayment = Coin.ZERO;
|
||||||
for (int i = 0; i < 5; i++) {
|
for (int i = 0; i < 5; i++) {
|
||||||
byte[] signature = clientState.incrementPaymentBy(size).signature.encodeToBitcoin();
|
byte[] signature = clientState.incrementPaymentBy(size).signature.encodeToBitcoin();
|
||||||
totalPayment = totalPayment.add(size);
|
totalPayment = totalPayment.add(size);
|
||||||
|
@ -20,7 +20,6 @@ import static org.junit.Assert.assertArrayEquals;
|
|||||||
import static org.junit.Assert.assertEquals;
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertNotNull;
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.security.KeyStore;
|
import java.security.KeyStore;
|
||||||
import java.security.PrivateKey;
|
import java.security.PrivateKey;
|
||||||
import java.security.cert.X509Certificate;
|
import java.security.cert.X509Certificate;
|
||||||
@ -35,6 +34,7 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import com.google.bitcoin.core.Address;
|
import com.google.bitcoin.core.Address;
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.ECKey;
|
import com.google.bitcoin.core.ECKey;
|
||||||
import com.google.bitcoin.core.NetworkParameters;
|
import com.google.bitcoin.core.NetworkParameters;
|
||||||
import com.google.bitcoin.core.Transaction;
|
import com.google.bitcoin.core.Transaction;
|
||||||
@ -50,7 +50,7 @@ public class PaymentProtocolTest {
|
|||||||
|
|
||||||
// static test data
|
// static test data
|
||||||
private static final NetworkParameters NETWORK_PARAMS = UnitTestParams.get();
|
private static final NetworkParameters NETWORK_PARAMS = UnitTestParams.get();
|
||||||
private static final BigInteger AMOUNT = BigInteger.ONE;
|
private static final Coin AMOUNT = Coin.ONE;
|
||||||
private static final Address TO_ADDRESS = new ECKey().toAddress(NETWORK_PARAMS);
|
private static final Address TO_ADDRESS = new ECKey().toAddress(NETWORK_PARAMS);
|
||||||
private static final String MEMO = "memo";
|
private static final String MEMO = "memo";
|
||||||
private static final String PAYMENT_URL = "https://example.com";
|
private static final String PAYMENT_URL = "https://example.com";
|
||||||
@ -128,7 +128,7 @@ public class PaymentProtocolTest {
|
|||||||
// Create
|
// Create
|
||||||
List<Transaction> transactions = new LinkedList<Transaction>();
|
List<Transaction> transactions = new LinkedList<Transaction>();
|
||||||
transactions.add(FakeTxBuilder.createFakeTx(NETWORK_PARAMS, AMOUNT, TO_ADDRESS));
|
transactions.add(FakeTxBuilder.createFakeTx(NETWORK_PARAMS, AMOUNT, TO_ADDRESS));
|
||||||
BigInteger refundAmount = BigInteger.ONE;
|
Coin refundAmount = Coin.ONE;
|
||||||
Address refundAddress = new ECKey().toAddress(NETWORK_PARAMS);
|
Address refundAddress = new ECKey().toAddress(NETWORK_PARAMS);
|
||||||
Payment payment = PaymentProtocol.createPaymentMessage(transactions, refundAmount, refundAddress, MEMO,
|
Payment payment = PaymentProtocol.createPaymentMessage(transactions, refundAmount, refundAddress, MEMO,
|
||||||
MERCHANT_DATA);
|
MERCHANT_DATA);
|
||||||
|
@ -28,7 +28,6 @@ import org.junit.Before;
|
|||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
@ -45,7 +44,7 @@ public class PaymentSessionTest {
|
|||||||
private ECKey serverKey;
|
private ECKey serverKey;
|
||||||
private Transaction tx;
|
private Transaction tx;
|
||||||
private TransactionOutput outputToMe;
|
private TransactionOutput outputToMe;
|
||||||
BigInteger nanoCoins = Utils.toNanoCoins(1, 0);
|
Coin nanoCoins = Utils.toNanoCoins(1, 0);
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
@ -97,7 +96,7 @@ public class PaymentSessionTest {
|
|||||||
.setSerializedPaymentDetails(paymentDetails.toByteString())
|
.setSerializedPaymentDetails(paymentDetails.toByteString())
|
||||||
.build();
|
.build();
|
||||||
MockPaymentSession paymentSession = new MockPaymentSession(paymentRequest);
|
MockPaymentSession paymentSession = new MockPaymentSession(paymentRequest);
|
||||||
assertEquals(BigInteger.ZERO, paymentSession.getValue());
|
assertEquals(Coin.ZERO, paymentSession.getValue());
|
||||||
assertNull(paymentSession.getPaymentUrl());
|
assertNull(paymentSession.getPaymentUrl());
|
||||||
assertNull(paymentSession.getMemo());
|
assertNull(paymentSession.getMemo());
|
||||||
}
|
}
|
||||||
|
@ -74,7 +74,7 @@ public class WalletProtobufSerializerTest {
|
|||||||
// Check the base case of a wallet with one key and no transactions.
|
// Check the base case of a wallet with one key and no transactions.
|
||||||
Wallet wallet1 = roundTrip(myWallet);
|
Wallet wallet1 = roundTrip(myWallet);
|
||||||
assertEquals(0, wallet1.getTransactions(true).size());
|
assertEquals(0, wallet1.getTransactions(true).size());
|
||||||
assertEquals(BigInteger.ZERO, wallet1.getBalance());
|
assertEquals(Coin.ZERO, wallet1.getBalance());
|
||||||
assertArrayEquals(myKey.getPubKey(),
|
assertArrayEquals(myKey.getPubKey(),
|
||||||
wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getPubKey());
|
wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getPubKey());
|
||||||
assertArrayEquals(myKey.getPrivKeyBytes(),
|
assertArrayEquals(myKey.getPrivKeyBytes(),
|
||||||
@ -92,7 +92,7 @@ public class WalletProtobufSerializerTest {
|
|||||||
@Test
|
@Test
|
||||||
public void oneTx() throws Exception {
|
public void oneTx() throws Exception {
|
||||||
// Check basic tx serialization.
|
// Check basic tx serialization.
|
||||||
BigInteger v1 = Utils.toNanoCoins(1, 0);
|
Coin v1 = Utils.toNanoCoins(1, 0);
|
||||||
Transaction t1 = createFakeTx(params, v1, myAddress);
|
Transaction t1 = createFakeTx(params, v1, myAddress);
|
||||||
t1.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByName("1.2.3.4")));
|
t1.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByName("1.2.3.4")));
|
||||||
t1.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByName("5.6.7.8")));
|
t1.getConfidence().markBroadcastBy(new PeerAddress(InetAddress.getByName("5.6.7.8")));
|
||||||
@ -136,7 +136,7 @@ public class WalletProtobufSerializerTest {
|
|||||||
assertEquals(1, wallet1.getTransactions(true).size());
|
assertEquals(1, wallet1.getTransactions(true).size());
|
||||||
Transaction t1 = wallet1.getTransaction(doubleSpends.t1.getHash());
|
Transaction t1 = wallet1.getTransaction(doubleSpends.t1.getHash());
|
||||||
assertEquals(ConfidenceType.DEAD, t1.getConfidence().getConfidenceType());
|
assertEquals(ConfidenceType.DEAD, t1.getConfidence().getConfidenceType());
|
||||||
assertEquals(BigInteger.ZERO, wallet1.getBalance());
|
assertEquals(Coin.ZERO, wallet1.getBalance());
|
||||||
|
|
||||||
// TODO: Wallet should store overriding transactions even if they are not wallet-relevant.
|
// TODO: Wallet should store overriding transactions even if they are not wallet-relevant.
|
||||||
// assertEquals(doubleSpends.t2, t1.getConfidence().getOverridingTransaction());
|
// assertEquals(doubleSpends.t2, t1.getConfidence().getOverridingTransaction());
|
||||||
@ -192,7 +192,7 @@ public class WalletProtobufSerializerTest {
|
|||||||
final ArrayList<Transaction> txns = new ArrayList<Transaction>(2);
|
final ArrayList<Transaction> txns = new ArrayList<Transaction>(2);
|
||||||
myWallet.addEventListener(new AbstractWalletEventListener() {
|
myWallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
txns.add(tx);
|
txns.add(tx);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -275,7 +275,7 @@ public class WalletProtobufSerializerTest {
|
|||||||
public void testRoundTripNormalWallet() throws Exception {
|
public void testRoundTripNormalWallet() throws Exception {
|
||||||
Wallet wallet1 = roundTrip(myWallet);
|
Wallet wallet1 = roundTrip(myWallet);
|
||||||
assertEquals(0, wallet1.getTransactions(true).size());
|
assertEquals(0, wallet1.getTransactions(true).size());
|
||||||
assertEquals(BigInteger.ZERO, wallet1.getBalance());
|
assertEquals(Coin.ZERO, wallet1.getBalance());
|
||||||
assertArrayEquals(myKey.getPubKey(),
|
assertArrayEquals(myKey.getPubKey(),
|
||||||
wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getPubKey());
|
wallet1.findKeyFromPubHash(myKey.getPubKeyHash()).getPubKey());
|
||||||
assertArrayEquals(myKey.getPrivKeyBytes(),
|
assertArrayEquals(myKey.getPrivKeyBytes(),
|
||||||
|
@ -25,7 +25,6 @@ import org.junit.After;
|
|||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
@ -97,7 +96,7 @@ public class DefaultCoinSelectorTest extends TestWithWallet {
|
|||||||
Transaction t1 = checkNotNull(sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN));
|
Transaction t1 = checkNotNull(sendMoneyToWallet(Utils.COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN));
|
||||||
// Padding block.
|
// Padding block.
|
||||||
wallet.notifyNewBestBlock(FakeTxBuilder.createFakeBlock(blockStore).storedBlock);
|
wallet.notifyNewBestBlock(FakeTxBuilder.createFakeBlock(blockStore).storedBlock);
|
||||||
final BigInteger TWO_COINS = Utils.COIN.multiply(BigInteger.valueOf(2));
|
final Coin TWO_COINS = Utils.COIN.multiply(Coin.valueOf(2));
|
||||||
Transaction t2 = checkNotNull(sendMoneyToWallet(TWO_COINS, AbstractBlockChain.NewBlockType.BEST_CHAIN));
|
Transaction t2 = checkNotNull(sendMoneyToWallet(TWO_COINS, AbstractBlockChain.NewBlockType.BEST_CHAIN));
|
||||||
Transaction t3 = checkNotNull(sendMoneyToWallet(Utils.CENT, AbstractBlockChain.NewBlockType.BEST_CHAIN));
|
Transaction t3 = checkNotNull(sendMoneyToWallet(Utils.CENT, AbstractBlockChain.NewBlockType.BEST_CHAIN));
|
||||||
|
|
||||||
|
@ -17,8 +17,6 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.wallet;
|
package com.google.bitcoin.wallet;
|
||||||
|
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import com.google.bitcoin.core.*;
|
import com.google.bitcoin.core.*;
|
||||||
import com.google.bitcoin.params.MainNetParams;
|
import com.google.bitcoin.params.MainNetParams;
|
||||||
import com.google.bitcoin.script.ScriptBuilder;
|
import com.google.bitcoin.script.ScriptBuilder;
|
||||||
@ -136,7 +134,7 @@ public class DefaultRiskAnalysisTest {
|
|||||||
|
|
||||||
Transaction dustTx = new Transaction(params);
|
Transaction dustTx = new Transaction(params);
|
||||||
dustTx.addInput(params.getGenesisBlock().getTransactions().get(0).getOutput(0));
|
dustTx.addInput(params.getGenesisBlock().getTransactions().get(0).getOutput(0));
|
||||||
dustTx.addOutput(BigInteger.ONE, key1); // 1 Satoshi
|
dustTx.addOutput(Coin.ONE, key1); // 1 Satoshi
|
||||||
assertEquals(RiskAnalysis.Result.NON_STANDARD, DefaultRiskAnalysis.FACTORY.create(wallet, dustTx, NO_DEPS).analyze());
|
assertEquals(RiskAnalysis.Result.NON_STANDARD, DefaultRiskAnalysis.FACTORY.create(wallet, dustTx, NO_DEPS).analyze());
|
||||||
|
|
||||||
Transaction edgeCaseTx = new Transaction(params);
|
Transaction edgeCaseTx = new Transaction(params);
|
||||||
|
@ -7,7 +7,6 @@ import com.google.bitcoin.utils.BriefLogFormatter;
|
|||||||
import com.google.bitcoin.utils.Threading;
|
import com.google.bitcoin.utils.Threading;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a little test app that waits for a coin on a local regtest node, then generates two transactions that double
|
* This is a little test app that waits for a coin on a local regtest node, then generates two transactions that double
|
||||||
@ -28,7 +27,7 @@ public class DoubleSpend {
|
|||||||
|
|
||||||
kit.wallet().getBalanceFuture(Utils.COIN, Wallet.BalanceType.AVAILABLE).get();
|
kit.wallet().getBalanceFuture(Utils.COIN, Wallet.BalanceType.AVAILABLE).get();
|
||||||
Transaction tx1 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), Utils.CENT);
|
Transaction tx1 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), Utils.CENT);
|
||||||
Transaction tx2 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), Utils.CENT.add(BigInteger.TEN));
|
Transaction tx2 = kit.wallet().createSend(new Address(params, "muYPFNCv7KQEG2ZLM7Z3y96kJnNyXJ53wm"), Utils.CENT.add(Coin.TEN));
|
||||||
final Peer peer = kit.peerGroup().getConnectedPeers().get(0);
|
final Peer peer = kit.peerGroup().getConnectedPeers().get(0);
|
||||||
peer.addEventListener(new AbstractPeerEventListener() {
|
peer.addEventListener(new AbstractPeerEventListener() {
|
||||||
@Override
|
@Override
|
||||||
|
@ -34,14 +34,13 @@ import org.slf4j.LoggerFactory;
|
|||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetSocketAddress;
|
import java.net.InetSocketAddress;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.CountDownLatch;
|
import java.util.concurrent.CountDownLatch;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
|
||||||
|
import static com.google.bitcoin.core.Coin.TEN;
|
||||||
import static com.google.bitcoin.core.Utils.CENT;
|
import static com.google.bitcoin.core.Utils.CENT;
|
||||||
import static java.math.BigInteger.TEN;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Simple client that connects to the given host, opens a channel, and pays one cent.
|
* Simple client that connects to the given host, opens a channel, and pays one cent.
|
||||||
@ -49,7 +48,7 @@ import static java.math.BigInteger.TEN;
|
|||||||
public class ExamplePaymentChannelClient {
|
public class ExamplePaymentChannelClient {
|
||||||
private static final org.slf4j.Logger log = LoggerFactory.getLogger(ExamplePaymentChannelClient.class);
|
private static final org.slf4j.Logger log = LoggerFactory.getLogger(ExamplePaymentChannelClient.class);
|
||||||
private WalletAppKit appKit;
|
private WalletAppKit appKit;
|
||||||
private final BigInteger channelSize;
|
private final Coin channelSize;
|
||||||
private final ECKey myKey;
|
private final ECKey myKey;
|
||||||
private final NetworkParameters params;
|
private final NetworkParameters params;
|
||||||
|
|
||||||
@ -124,7 +123,7 @@ public class ExamplePaymentChannelClient {
|
|||||||
// we are not allowed to have payment channels that pay nothing at all.
|
// we are not allowed to have payment channels that pay nothing at all.
|
||||||
log.info("Success! Trying to make {} micropayments. Already paid {} satoshis on this channel",
|
log.info("Success! Trying to make {} micropayments. Already paid {} satoshis on this channel",
|
||||||
times, client.state().getValueSpent());
|
times, client.state().getValueSpent());
|
||||||
final BigInteger MICROPAYMENT_SIZE = CENT.divide(TEN);
|
final Coin MICROPAYMENT_SIZE = CENT.divide(TEN);
|
||||||
for (int i = 0; i < times; i++) {
|
for (int i = 0; i < times; i++) {
|
||||||
try {
|
try {
|
||||||
// Wait because the act of making a micropayment is async, and we're not allowed to overlap.
|
// Wait because the act of making a micropayment is async, and we're not allowed to overlap.
|
||||||
@ -164,11 +163,11 @@ public class ExamplePaymentChannelClient {
|
|||||||
latch.await();
|
latch.await();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void waitForSufficientBalance(BigInteger amount) {
|
private void waitForSufficientBalance(Coin amount) {
|
||||||
// Not enough money in the wallet.
|
// Not enough money in the wallet.
|
||||||
BigInteger amountPlusFee = amount.add(Wallet.SendRequest.DEFAULT_FEE_PER_KB);
|
Coin amountPlusFee = amount.add(Wallet.SendRequest.DEFAULT_FEE_PER_KB);
|
||||||
// ESTIMATED because we don't really need to wait for confirmation.
|
// ESTIMATED because we don't really need to wait for confirmation.
|
||||||
ListenableFuture<BigInteger> balanceFuture = appKit.wallet().getBalanceFuture(amountPlusFee, Wallet.BalanceType.ESTIMATED);
|
ListenableFuture<Coin> balanceFuture = appKit.wallet().getBalanceFuture(amountPlusFee, Wallet.BalanceType.ESTIMATED);
|
||||||
if (!balanceFuture.isDone()) {
|
if (!balanceFuture.isDone()) {
|
||||||
System.out.println("Please send " + Utils.bitcoinValueToFriendlyString(amountPlusFee) +
|
System.out.println("Please send " + Utils.bitcoinValueToFriendlyString(amountPlusFee) +
|
||||||
" BTC to " + myKey.toAddress(params));
|
" BTC to " + myKey.toAddress(params));
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
|
|
||||||
package com.google.bitcoin.examples;
|
package com.google.bitcoin.examples;
|
||||||
|
|
||||||
|
import com.google.bitcoin.core.Coin;
|
||||||
import com.google.bitcoin.core.NetworkParameters;
|
import com.google.bitcoin.core.NetworkParameters;
|
||||||
import com.google.bitcoin.core.Sha256Hash;
|
import com.google.bitcoin.core.Sha256Hash;
|
||||||
import com.google.bitcoin.core.VerificationException;
|
import com.google.bitcoin.core.VerificationException;
|
||||||
@ -26,10 +27,10 @@ import com.google.bitcoin.params.RegTestParams;
|
|||||||
import com.google.bitcoin.protocols.channels.*;
|
import com.google.bitcoin.protocols.channels.*;
|
||||||
import com.google.bitcoin.utils.BriefLogFormatter;
|
import com.google.bitcoin.utils.BriefLogFormatter;
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
|
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.SocketAddress;
|
import java.net.SocketAddress;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
@ -71,7 +72,7 @@ public class ExamplePaymentChannelServer implements PaymentChannelServerListener
|
|||||||
// We provide a peer group, a wallet, a timeout in seconds, the amount we require to start a channel and
|
// We provide a peer group, a wallet, a timeout in seconds, the amount we require to start a channel and
|
||||||
// an implementation of HandlerFactory, which we just implement ourselves.
|
// an implementation of HandlerFactory, which we just implement ourselves.
|
||||||
final int MILLI = 100000;
|
final int MILLI = 100000;
|
||||||
new PaymentChannelServerListener(appKit.peerGroup(), appKit.wallet(), 15, BigInteger.valueOf(MILLI), this).bindAndStart(4242);
|
new PaymentChannelServerListener(appKit.peerGroup(), appKit.wallet(), 15, Coin.valueOf(MILLI), this).bindAndStart(4242);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -101,7 +102,7 @@ public class ExamplePaymentChannelServer implements PaymentChannelServerListener
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void paymentIncrease(BigInteger by, BigInteger to) {
|
public void paymentIncrease(Coin by, Coin to) {
|
||||||
log.info("Client {} paid increased payment by {} for a total of " + to.toString(), clientAddress, by);
|
log.info("Client {} paid increased payment by {} for a total of " + to.toString(), clientAddress, by);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,6 @@ import com.google.common.util.concurrent.Futures;
|
|||||||
import com.google.common.util.concurrent.MoreExecutors;
|
import com.google.common.util.concurrent.MoreExecutors;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
@ -81,11 +80,11 @@ public class ForwardingService {
|
|||||||
// We want to know when we receive money.
|
// We want to know when we receive money.
|
||||||
kit.wallet().addEventListener(new AbstractWalletEventListener() {
|
kit.wallet().addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet w, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet w, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
// Runs in the dedicated "user thread" (see bitcoinj docs for more info on this).
|
// Runs in the dedicated "user thread" (see bitcoinj docs for more info on this).
|
||||||
//
|
//
|
||||||
// The transaction "tx" can either be pending, or included into a block (we didn't see the broadcast).
|
// The transaction "tx" can either be pending, or included into a block (we didn't see the broadcast).
|
||||||
BigInteger value = tx.getValueSentToMe(w);
|
Coin value = tx.getValueSentToMe(w);
|
||||||
System.out.println("Received tx for " + Utils.bitcoinValueToFriendlyString(value) + ": " + tx);
|
System.out.println("Received tx for " + Utils.bitcoinValueToFriendlyString(value) + ": " + tx);
|
||||||
System.out.println("Transaction will be forwarded after it confirms.");
|
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).
|
// Wait until it's made it into the block chain (may run immediately if it's already there).
|
||||||
@ -121,10 +120,10 @@ public class ForwardingService {
|
|||||||
|
|
||||||
private static void forwardCoins(Transaction tx) {
|
private static void forwardCoins(Transaction tx) {
|
||||||
try {
|
try {
|
||||||
BigInteger value = tx.getValueSentToMe(kit.wallet());
|
Coin value = tx.getValueSentToMe(kit.wallet());
|
||||||
System.out.println("Forwarding " + Utils.bitcoinValueToFriendlyString(value) + " BTC");
|
System.out.println("Forwarding " + Utils.bitcoinValueToFriendlyString(value) + " BTC");
|
||||||
// Now send the coins back! Send with a small fee attached to ensure rapid confirmation.
|
// Now send the coins back! Send with a small fee attached to ensure rapid confirmation.
|
||||||
final BigInteger amountToSend = value.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
final Coin amountToSend = value.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
||||||
final Wallet.SendResult sendResult = kit.wallet().sendCoins(kit.peerGroup(), forwardingAddress, amountToSend);
|
final Wallet.SendResult sendResult = kit.wallet().sendCoins(kit.peerGroup(), forwardingAddress, amountToSend);
|
||||||
checkNotNull(sendResult); // We should never try to send more coins than we have!
|
checkNotNull(sendResult); // We should never try to send more coins than we have!
|
||||||
System.out.println("Sending ...");
|
System.out.println("Sending ...");
|
||||||
|
@ -23,7 +23,6 @@ import com.google.bitcoin.store.BlockStore;
|
|||||||
import com.google.bitcoin.store.MemoryBlockStore;
|
import com.google.bitcoin.store.MemoryBlockStore;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.math.BigInteger;
|
|
||||||
import java.net.InetAddress;
|
import java.net.InetAddress;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,7 +45,7 @@ public class RefreshWallet {
|
|||||||
|
|
||||||
wallet.addEventListener(new AbstractWalletEventListener() {
|
wallet.addEventListener(new AbstractWalletEventListener() {
|
||||||
@Override
|
@Override
|
||||||
public synchronized void onCoinsReceived(Wallet w, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public synchronized void onCoinsReceived(Wallet w, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
System.out.println("\nReceived tx " + tx.getHashAsString());
|
System.out.println("\nReceived tx " + tx.getHashAsString());
|
||||||
System.out.println(tx.toString());
|
System.out.println(tx.toString());
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ import org.slf4j.Logger;
|
|||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.math.BigInteger;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A program that sends a transaction with the specified fee and measures how long it takes to confirm.
|
* A program that sends a transaction with the specified fee and measures how long it takes to confirm.
|
||||||
@ -26,7 +25,7 @@ public class TestFeeLevel {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BigInteger feeToTest = new BigInteger(args[0]);
|
Coin feeToTest = Coin.valueOf(Long.parseLong(args[0]));
|
||||||
|
|
||||||
kit = new WalletAppKit(PARAMS, new File("."), "testfeelevel");
|
kit = new WalletAppKit(PARAMS, new File("."), "testfeelevel");
|
||||||
kit.startAsync();
|
kit.startAsync();
|
||||||
@ -39,7 +38,7 @@ public class TestFeeLevel {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void go(BigInteger feeToTest) throws InterruptedException, java.util.concurrent.ExecutionException, InsufficientMoneyException {
|
private static void go(Coin feeToTest) throws InterruptedException, java.util.concurrent.ExecutionException, InsufficientMoneyException {
|
||||||
kit.peerGroup().setMaxConnections(50);
|
kit.peerGroup().setMaxConnections(50);
|
||||||
|
|
||||||
final Address address = kit.wallet().currentReceiveKey().toAddress(PARAMS);
|
final Address address = kit.wallet().currentReceiveKey().toAddress(PARAMS);
|
||||||
|
@ -124,9 +124,9 @@ public class WalletTool {
|
|||||||
value = s;
|
value = s;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean matchBitcoins(BigInteger comparison) {
|
public boolean matchBitcoins(Coin comparison) {
|
||||||
try {
|
try {
|
||||||
BigInteger units = Utils.toNanoCoins(value);
|
Coin units = Utils.toNanoCoins(value);
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case LT: return comparison.compareTo(units) < 0;
|
case LT: return comparison.compareTo(units) < 0;
|
||||||
case GT: return comparison.compareTo(units) > 0;
|
case GT: return comparison.compareTo(units) > 0;
|
||||||
@ -323,7 +323,7 @@ public class WalletTool {
|
|||||||
System.err.println("--payment-request and --output cannot be used together.");
|
System.err.println("--payment-request and --output cannot be used together.");
|
||||||
return;
|
return;
|
||||||
} else if (options.has(outputFlag)) {
|
} else if (options.has(outputFlag)) {
|
||||||
BigInteger fee = BigInteger.ZERO;
|
Coin fee = Coin.ZERO;
|
||||||
if (options.has("fee")) {
|
if (options.has("fee")) {
|
||||||
fee = Utils.toNanoCoins((String)options.valueOf("fee"));
|
fee = Utils.toNanoCoins((String)options.valueOf("fee"));
|
||||||
}
|
}
|
||||||
@ -413,7 +413,7 @@ public class WalletTool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void send(List<String> outputs, BigInteger fee, String lockTimeStr, boolean allowUnconfirmed) throws VerificationException {
|
private static void send(List<String> outputs, Coin fee, String lockTimeStr, boolean allowUnconfirmed) throws VerificationException {
|
||||||
try {
|
try {
|
||||||
// Convert the input strings to outputs.
|
// Convert the input strings to outputs.
|
||||||
Transaction t = new Transaction(params);
|
Transaction t = new Transaction(params);
|
||||||
@ -425,7 +425,7 @@ public class WalletTool {
|
|||||||
}
|
}
|
||||||
String destination = parts[0];
|
String destination = parts[0];
|
||||||
try {
|
try {
|
||||||
BigInteger value = Utils.toNanoCoins(parts[1]);
|
Coin value = Utils.toNanoCoins(parts[1]);
|
||||||
if (destination.startsWith("0")) {
|
if (destination.startsWith("0")) {
|
||||||
// Treat as a raw public key.
|
// Treat as a raw public key.
|
||||||
byte[] pubKey = new BigInteger(destination, 16).toByteArray();
|
byte[] pubKey = new BigInteger(destination, 16).toByteArray();
|
||||||
@ -567,7 +567,7 @@ public class WalletTool {
|
|||||||
private static void send(PaymentSession session) {
|
private static void send(PaymentSession session) {
|
||||||
try {
|
try {
|
||||||
System.out.println("Payment Request");
|
System.out.println("Payment Request");
|
||||||
System.out.println("Amount: " + session.getValue().doubleValue() / 100000 + "mBTC");
|
System.out.println("Coin: " + session.getValue().doubleValue() / 100000 + "mBTC");
|
||||||
System.out.println("Date: " + session.getDate());
|
System.out.println("Date: " + session.getDate());
|
||||||
System.out.println("Memo: " + session.getMemo());
|
System.out.println("Memo: " + session.getMemo());
|
||||||
if (session.pkiVerificationData != null) {
|
if (session.pkiVerificationData != null) {
|
||||||
@ -636,15 +636,15 @@ public class WalletTool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsReceived(Wallet wallet, Transaction tx, BigInteger prevBalance, BigInteger newBalance) {
|
public void onCoinsReceived(Wallet wallet, Transaction tx, Coin prevBalance, Coin newBalance) {
|
||||||
// Runs in a peer thread.
|
// Runs in a peer thread.
|
||||||
super.onCoinsReceived(wallet, tx, prevBalance, newBalance);
|
super.onCoinsReceived(wallet, tx, prevBalance, newBalance);
|
||||||
handleTx(tx);
|
handleTx(tx);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onCoinsSent(Wallet wallet, Transaction tx, BigInteger prevBalance,
|
public void onCoinsSent(Wallet wallet, Transaction tx, Coin prevBalance,
|
||||||
BigInteger newBalance) {
|
Coin newBalance) {
|
||||||
// Runs in a peer thread.
|
// Runs in a peer thread.
|
||||||
super.onCoinsSent(wallet, tx, prevBalance, newBalance);
|
super.onCoinsSent(wallet, tx, prevBalance, newBalance);
|
||||||
handleTx(tx);
|
handleTx(tx);
|
||||||
@ -677,7 +677,7 @@ public class WalletTool {
|
|||||||
public synchronized void onChange() {
|
public synchronized void onChange() {
|
||||||
super.onChange();
|
super.onChange();
|
||||||
saveWallet(walletFile);
|
saveWallet(walletFile);
|
||||||
BigInteger balance = wallet.getBalance(Wallet.BalanceType.ESTIMATED);
|
Coin balance = wallet.getBalance(Wallet.BalanceType.ESTIMATED);
|
||||||
if (condition.matchBitcoins(balance)) {
|
if (condition.matchBitcoins(balance)) {
|
||||||
System.out.println(Utils.bitcoinValueToFriendlyString(balance));
|
System.out.println(Utils.bitcoinValueToFriendlyString(balance));
|
||||||
latch.countDown();
|
latch.countDown();
|
||||||
|
Loading…
Reference in New Issue
Block a user