diff --git a/core/src/main/java/com/google/bitcoin/core/Wallet.java b/core/src/main/java/com/google/bitcoin/core/Wallet.java
index c89db878..8dddd186 100644
--- a/core/src/main/java/com/google/bitcoin/core/Wallet.java
+++ b/core/src/main/java/com/google/bitcoin/core/Wallet.java
@@ -1689,7 +1689,7 @@ public class Wallet implements Serializable, BlockChainListener {
*
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.
*/
- public BigInteger fee = BigInteger.ZERO;
+ public BigInteger fee = null;
/**
* A transaction can have a fee attached, which is defined as the difference between the input values
@@ -1705,7 +1705,13 @@ public class Wallet implements Serializable, BlockChainListener {
*
*
You might also consider using a {@link SendRequest#fee} to set the fee added for the first kb of size.
*/
- public BigInteger feePerKb = BigInteger.ZERO;
+ public BigInteger feePerKb = DEFAULT_FEE_PER_KB;
+
+ /**
+ * If you want to modify the default fee for your entire app without having to change each SendRequest you make,
+ * you can do it here. This is primarily useful for unit tests.
+ */
+ public static BigInteger DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
/**
* Requires that there be enough fee for a default reference client to at least relay the transaction.
@@ -1954,13 +1960,10 @@ public class Wallet implements Serializable, BlockChainListener {
// Note that output.isMine(this) needs to test the keychain which is currently an array, so it's
// O(candidate outputs ^ keychain.size())! There's lots of low hanging fruit here.
LinkedList candidates = calculateSpendCandidates(true);
- Address changeAddress = req.changeAddress;
- int minSize = 0;
// This can throw InsufficientMoneyException.
- FeeCalculation feeCalculation = null;
+ FeeCalculation feeCalculation;
try {
- feeCalculation = new FeeCalculation(req, value, originalInputs, needAtLeastReferenceFee,
- candidates, changeAddress, minSize);
+ feeCalculation = new FeeCalculation(req, value, originalInputs, needAtLeastReferenceFee, candidates);
} catch (InsufficientMoneyException e) {
// TODO: Propagate this after 0.9 is released and stop returning a boolean.
return false;
@@ -1979,6 +1982,9 @@ public class Wallet implements Serializable, BlockChainListener {
log.info(" with {} coins change", bitcoinValueToFriendlyString(bestChangeOutput.getValue()));
}
final BigInteger calculatedFee = totalInput.subtract(totalOutput);
+ if (calculatedFee.compareTo(BigInteger.ZERO) > 0) {
+ log.info(" with a fee of {}", bitcoinValueToFriendlyString(calculatedFee));
+ }
// Now sign the inputs, thus proving that we are entitled to redeem the connected outputs.
try {
@@ -3084,8 +3090,7 @@ public class Wallet implements Serializable, BlockChainListener {
private TransactionOutput bestChangeOutput;
public FeeCalculation(SendRequest req, BigInteger value, List originalInputs,
- boolean needAtLeastReferenceFee, LinkedList candidates,
- Address changeAddress, int minSize) throws InsufficientMoneyException {
+ boolean needAtLeastReferenceFee, LinkedList candidates) throws InsufficientMoneyException {
// There are 3 possibilities for what adding change might do:
// 1) No effect
// 2) Causes increase in fee (change < 0.01 COINS)
@@ -3099,14 +3104,22 @@ public class Wallet implements Serializable, BlockChainListener {
TransactionOutput selection2Change = null;
CoinSelection selection1 = null;
TransactionOutput selection1Change = null;
+ // We keep track of the last size of the transaction we calculated but only if the act of adding inputs and
+ // change resulted in the size crossing a 1000 byte boundary. Otherwise it stays at zero.
+ int lastCalculatedSize = 0;
+ BigInteger valueNeeded;
while (true) {
resetTxInputs(req, originalInputs);
- BigInteger fees = req.fee.add(BigInteger.valueOf(minSize/1000).multiply(req.feePerKb));
+ BigInteger fees = req.fee == null ? BigInteger.ZERO : req.fee;
+ if (lastCalculatedSize > 0)
+ fees = fees.add(BigInteger.valueOf((lastCalculatedSize / 1000) + 1).multiply(req.feePerKb));
+ else
+ fees = fees.add(req.feePerKb); // First time around the loop.
if (needAtLeastReferenceFee && fees.compareTo(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE) < 0)
fees = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
- BigInteger valueNeeded = value.add(fees);
+ valueNeeded = value.add(fees);
if (additionalValueForNextCategory != null)
valueNeeded = valueNeeded.add(additionalValueForNextCategory);
BigInteger additionalValueSelected = additionalValueForNextCategory;
@@ -3146,7 +3159,8 @@ public class Wallet implements Serializable, BlockChainListener {
if (change.compareTo(BigInteger.ZERO) > 0) {
// The value of the inputs is greater than what we want to send. Just like in real life then,
// we need to take back some coins ... this is called "change". Add another output that sends the change
- // back to us. The address comes either from the request or getChangeAddress() as a default..
+ // back to us. The address comes either from the request or getChangeAddress() as a default.
+ Address changeAddress = req.changeAddress;
if (changeAddress == null)
changeAddress = getChangeAddress();
changeOutput = new TransactionOutput(params, req.tx, change, changeAddress);
@@ -3177,11 +3191,12 @@ public class Wallet implements Serializable, BlockChainListener {
checkState(input.getScriptBytes().length == 0);
}
- // Estimate transaction size and loop again if we need more fee per kb
- size += estimateBytesForSpending(selection);
+ // Estimate transaction size and loop again if we need more fee per kb. The serialized tx doesn't
+ // include things we haven't added yet like input signatures/scripts or the change output.
size += req.tx.bitcoinSerialize().length;
- if (size/1000 > minSize/1000 && req.feePerKb.compareTo(BigInteger.ZERO) > 0) {
- minSize = size;
+ size += estimateBytesForSigning(selection);
+ if (size/1000 > lastCalculatedSize/1000 && req.feePerKb.compareTo(BigInteger.ZERO) > 0) {
+ lastCalculatedSize = size;
// We need more fees anyway, just try again with the same additional value
additionalValueForNextCategory = additionalValueSelected;
continue;
@@ -3216,7 +3231,7 @@ public class Wallet implements Serializable, BlockChainListener {
resetTxInputs(req, originalInputs);
if (selection3 == null && selection2 == null && selection1 == null) {
- log.warn("Insufficient value in wallet for send");
+ log.warn("Insufficient value in wallet for send: needed {}", bitcoinValueToFriendlyString(valueNeeded));
throw new InsufficientMoneyException();
}
@@ -3249,7 +3264,7 @@ public class Wallet implements Serializable, BlockChainListener {
}
}
- private int estimateBytesForSpending(CoinSelection selection) {
+ private int estimateBytesForSigning(CoinSelection selection) {
int size = 0;
for (TransactionOutput output : selection.gathered) {
try {
diff --git a/core/src/test/java/com/google/bitcoin/core/BlockChainTest.java b/core/src/test/java/com/google/bitcoin/core/BlockChainTest.java
index 9bf9cc29..f530ea5b 100644
--- a/core/src/test/java/com/google/bitcoin/core/BlockChainTest.java
+++ b/core/src/test/java/com/google/bitcoin/core/BlockChainTest.java
@@ -24,6 +24,7 @@ import com.google.bitcoin.store.BlockStore;
import com.google.bitcoin.store.MemoryBlockStore;
import com.google.bitcoin.utils.BriefLogFormatter;
import com.google.common.util.concurrent.ListenableFuture;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
@@ -63,6 +64,7 @@ public class BlockChainTest {
public void setUp() throws Exception {
BriefLogFormatter.initVerbose();
testNetChain = new BlockChain(testNet, new Wallet(testNet), new MemoryBlockStore(testNet));
+ Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
unitTestParams = UnitTestParams.get();
wallet = new Wallet(unitTestParams) {
@@ -83,6 +85,11 @@ public class BlockChainTest {
coinbaseTo = wallet.getKeys().get(0).toAddress(unitTestParams);
}
+ @After
+ public void tearDown() {
+ Wallet.SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
+ }
+
@Test
public void testBasicChaining() throws Exception {
// Check that we can plug a few blocks together and the futures work.
@@ -323,11 +330,8 @@ public class BlockChainTest {
assertNull(coinbaseSpend);
}
- // Give it one more block - should now be able to spend coinbase transaction.
- // Non relevant tx.
- Transaction tx3 = createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0),
- new ECKey().toAddress(unitTestParams));
-
+ // Give it one more block - should now be able to spend coinbase transaction. Non relevant tx.
+ Transaction tx3 = createFakeTx(unitTestParams, Utils.toNanoCoins(1, 0), new ECKey().toAddress(unitTestParams));
Block b3 = createFakeBlock(blockStore, tx3).block;
chain.add(b3);
diff --git a/core/src/test/java/com/google/bitcoin/core/ChainSplitTest.java b/core/src/test/java/com/google/bitcoin/core/ChainSplitTest.java
index 652ef171..4e5934a7 100644
--- a/core/src/test/java/com/google/bitcoin/core/ChainSplitTest.java
+++ b/core/src/test/java/com/google/bitcoin/core/ChainSplitTest.java
@@ -44,6 +44,7 @@ public class ChainSplitTest {
@Before
public void setUp() throws Exception {
BriefLogFormatter.init();
+ Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
unitTestParams = UnitTestParams.get();
wallet = new Wallet(unitTestParams);
wallet.addKey(new ECKey());
diff --git a/core/src/test/java/com/google/bitcoin/core/PeerGroupTest.java b/core/src/test/java/com/google/bitcoin/core/PeerGroupTest.java
index 0ae7e96b..e6bda429 100644
--- a/core/src/test/java/com/google/bitcoin/core/PeerGroupTest.java
+++ b/core/src/test/java/com/google/bitcoin/core/PeerGroupTest.java
@@ -46,7 +46,8 @@ public class PeerGroupTest extends TestWithPeerGroup {
}
@After
- public void shutDown() throws Exception {
+ public void tearDown() throws Exception {
+ super.tearDown();
peerGroup.stopAndWait();
}
diff --git a/core/src/test/java/com/google/bitcoin/core/TestWithNetworkConnections.java b/core/src/test/java/com/google/bitcoin/core/TestWithNetworkConnections.java
index 9ada4f9e..01c90c97 100644
--- a/core/src/test/java/com/google/bitcoin/core/TestWithNetworkConnections.java
+++ b/core/src/test/java/com/google/bitcoin/core/TestWithNetworkConnections.java
@@ -24,6 +24,7 @@ import org.easymock.EasyMock;
import org.easymock.IMocksControl;
import org.jboss.netty.channel.*;
+import java.math.BigInteger;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.SocketAddress;
@@ -60,6 +61,7 @@ public class TestWithNetworkConnections {
control.checkOrder(false);
unitTestParams = UnitTestParams.get();
+ Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
this.blockStore = blockStore;
wallet = new Wallet(unitTestParams);
key = new ECKey();
@@ -74,6 +76,10 @@ public class TestWithNetworkConnections {
pipeline = createPipeline(channel);
}
+ public void tearDown() throws Exception {
+ Wallet.SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
+ }
+
protected ChannelPipeline createPipeline(Channel channel) {
ChannelPipeline pipeline = control.createMock(ChannelPipeline.class);
expect(channel.getPipeline()).andStubReturn(pipeline);
diff --git a/core/src/test/java/com/google/bitcoin/core/TestWithWallet.java b/core/src/test/java/com/google/bitcoin/core/TestWithWallet.java
index d9e552ba..8bed75eb 100644
--- a/core/src/test/java/com/google/bitcoin/core/TestWithWallet.java
+++ b/core/src/test/java/com/google/bitcoin/core/TestWithWallet.java
@@ -20,6 +20,7 @@ import com.google.bitcoin.params.UnitTestParams;
import com.google.bitcoin.store.BlockStore;
import com.google.bitcoin.store.MemoryBlockStore;
import com.google.bitcoin.utils.BriefLogFormatter;
+import org.junit.After;
import org.junit.Before;
import java.io.IOException;
@@ -40,6 +41,7 @@ public class TestWithWallet {
@Before
public void setUp() throws Exception {
BriefLogFormatter.init();
+ Wallet.SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
myKey = new ECKey();
myAddress = myKey.toAddress(params);
wallet = new Wallet(params);
@@ -48,6 +50,11 @@ public class TestWithWallet {
chain = new BlockChain(params, wallet, blockStore);
}
+ @After
+ public void tearDown() throws Exception {
+ Wallet.SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
+ }
+
protected Transaction sendMoneyToWallet(Wallet wallet, Transaction tx, AbstractBlockChain.NewBlockType type)
throws IOException, ProtocolException, VerificationException {
if (type == null) {
diff --git a/core/src/test/java/com/google/bitcoin/core/WalletTest.java b/core/src/test/java/com/google/bitcoin/core/WalletTest.java
index 46e35b03..3832f348 100644
--- a/core/src/test/java/com/google/bitcoin/core/WalletTest.java
+++ b/core/src/test/java/com/google/bitcoin/core/WalletTest.java
@@ -1193,7 +1193,8 @@ public class WalletTest extends TestWithWallet {
StoredBlock block = new StoredBlock(makeSolvedTestBlock(blockStore, notMyAddr), BigInteger.ONE, 1);
Transaction tx1 = createFakeTx(params, BigInteger.ONE, myAddress);
wallet.receiveFromBlock(tx1, block, AbstractBlockChain.NewBlockType.BEST_CHAIN);
- Transaction tx2 = createFakeTx(params, BigInteger.ONE, myAddress); assertTrue(!tx1.getHash().equals(tx2.getHash()));
+ Transaction tx2 = createFakeTx(params, BigInteger.ONE, myAddress);
+ assertTrue(!tx1.getHash().equals(tx2.getHash()));
wallet.receiveFromBlock(tx2, block, AbstractBlockChain.NewBlockType.BEST_CHAIN);
Transaction tx3 = createFakeTx(params, BigInteger.TEN, myAddress);
wallet.receiveFromBlock(tx3, block, AbstractBlockChain.NewBlockType.BEST_CHAIN);
@@ -1364,24 +1365,25 @@ public class WalletTest extends TestWithWallet {
assertTrue(request15.tx.bitcoinSerialize().length > 1000);
request15.feePerKb = BigInteger.ONE;
assertTrue(wallet.completeTx(request15));
- assertEquals(BigInteger.ONE, request15.fee);
+ assertEquals(BigInteger.valueOf(2), request15.fee);
Transaction spend15 = request15.tx;
- // If a transaction is over 1kb, the set fee should be added
+ // If a transaction is over 1kb, 2 satoshis should be added.
assertEquals(31, spend15.getOutputs().size());
// We optimize for priority, so the output selected should be the largest one
BigInteger outValue15 = BigInteger.ZERO;
for (TransactionOutput out : spend15.getOutputs())
outValue15 = outValue15.add(out.getValue());
- assertEquals(outValue15, Utils.COIN.subtract(BigInteger.ONE));
+ assertEquals(Utils.COIN.subtract(BigInteger.valueOf(2)), outValue15);
SendRequest request16 = SendRequest.to(notMyAddr, Utils.CENT);
+ request16.feePerKb = BigInteger.ZERO;
for (int i = 0; i < 29; i++)
request16.tx.addOutput(Utils.CENT, notMyAddr);
assertTrue(request16.tx.bitcoinSerialize().length > 1000);
assertTrue(wallet.completeTx(request16));
+ // Of course the fee shouldn't be added if feePerKb == 0
assertEquals(BigInteger.ZERO, request16.fee);
Transaction spend16 = request16.tx;
- // Of course the fee shouldn't be added if feePerKb == 0
assertEquals(31, spend16.getOutputs().size());
// We optimize for priority, so the output selected should be the largest one
BigInteger outValue16 = BigInteger.ZERO;
@@ -1389,14 +1391,14 @@ public class WalletTest extends TestWithWallet {
outValue16 = outValue16.add(out.getValue());
assertEquals(Utils.COIN, outValue16);
- // Create a transaction who's max size could be up to 999 (if signatures were maximum size)
+ // Create a transaction whose max size could be up to 999 (if signatures were maximum size)
SendRequest request17 = SendRequest.to(notMyAddr, Utils.CENT);
for (int i = 0; i < 22; i++)
request17.tx.addOutput(Utils.CENT, notMyAddr);
request17.tx.addOutput(new TransactionOutput(params, request17.tx, Utils.CENT, new byte[15]));
request17.feePerKb = BigInteger.ONE;
assertTrue(wallet.completeTx(request17));
- assertEquals(BigInteger.ZERO, request17.fee);
+ assertEquals(BigInteger.ONE, request17.fee);
assertEquals(1, request17.tx.getInputs().size());
// Calculate its max length to make sure it is indeed 999
int theoreticalMaxLength17 = request17.tx.bitcoinSerialize().length + myKey.getPubKey().length + 75;
@@ -1404,54 +1406,59 @@ public class WalletTest extends TestWithWallet {
theoreticalMaxLength17 -= in.getScriptBytes().length;
assertEquals(999, theoreticalMaxLength17);
Transaction spend17 = request17.tx;
- // Its actual size must be between 997 and 999 (inclusive) as signatures have a 3-byte size range (almost always)
- assertTrue(spend17.bitcoinSerialize().length >= 997 && spend17.bitcoinSerialize().length <= 999);
- // Now check that it didn't get a fee since its max size is 999
+ {
+ // Its actual size must be between 997 and 999 (inclusive) as signatures have a 3-byte size range (almost always)
+ final int length = spend17.bitcoinSerialize().length;
+ assertTrue(Integer.toString(length), length >= 997 && length <= 999);
+ }
+ // Now check that it got a fee of 1 since its max size is 999 (1kb).
assertEquals(25, spend17.getOutputs().size());
// We optimize for priority, so the output selected should be the largest one
BigInteger outValue17 = BigInteger.ZERO;
for (TransactionOutput out : spend17.getOutputs())
outValue17 = outValue17.add(out.getValue());
- assertEquals(Utils.COIN, outValue17);
+ assertEquals(Utils.COIN.subtract(BigInteger.ONE), outValue17);
- // 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 1001 (if signatures were maximum size)
SendRequest request18 = SendRequest.to(notMyAddr, Utils.CENT);
for (int i = 0; i < 22; i++)
request18.tx.addOutput(Utils.CENT, notMyAddr);
- request18.tx.addOutput(new TransactionOutput(params, request18.tx, Utils.CENT, new byte[16]));
+ request18.tx.addOutput(new TransactionOutput(params, request18.tx, Utils.CENT, new byte[17]));
request18.feePerKb = BigInteger.ONE;
assertTrue(wallet.completeTx(request18));
- assertEquals(BigInteger.ONE, request18.fee);
+ assertEquals(BigInteger.valueOf(2), request18.fee);
assertEquals(1, request18.tx.getInputs().size());
- // Calculate its max length to make sure it is indeed 1000
+ // Calculate its max length to make sure it is indeed 1001
Transaction spend18 = request18.tx;
int theoreticalMaxLength18 = spend18.bitcoinSerialize().length + myKey.getPubKey().length + 75;
for (TransactionInput in : spend18.getInputs())
theoreticalMaxLength18 -= in.getScriptBytes().length;
- assertEquals(1000, theoreticalMaxLength18);
+ assertEquals(1001, theoreticalMaxLength18);
// Its actual size must be between 998 and 1000 (inclusive) as signatures have a 3-byte size range (almost always)
assertTrue(spend18.bitcoinSerialize().length >= 998);
- assertTrue(spend18.bitcoinSerialize().length <= 1000);
+ assertTrue(spend18.bitcoinSerialize().length <= 1001);
// Now check that it did get a fee since its max size is 1000
assertEquals(25, spend18.getOutputs().size());
// We optimize for priority, so the output selected should be the largest one
BigInteger outValue18 = BigInteger.ZERO;
for (TransactionOutput out : spend18.getOutputs())
outValue18 = outValue18.add(out.getValue());
- assertEquals(outValue18, Utils.COIN.subtract(BigInteger.ONE));
+ assertEquals(outValue18, Utils.COIN.subtract(BigInteger.valueOf(2)));
// Now create a transaction that will spend COIN + fee, which makes it require both inputs
assertEquals(wallet.getBalance(), Utils.CENT.add(Utils.COIN));
SendRequest request19 = SendRequest.to(notMyAddr, Utils.CENT);
+ request19.feePerKb = BigInteger.ZERO;
for (int i = 0; i < 99; i++)
request19.tx.addOutput(Utils.CENT, notMyAddr);
- // If we send now, we shouldnt 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
assertTrue(wallet.completeTx(request19));
assertEquals(BigInteger.ZERO, request19.fee);
assertEquals(1, request19.tx.getInputs().size());
assertEquals(100, request19.tx.getOutputs().size());
// Now reset request19 and give it a fee per kb
- request19.completed = false; request19.tx.clearInputs();
+ request19.completed = false;
+ request19.tx.clearInputs();
request19.feePerKb = BigInteger.ONE;
assertTrue(wallet.completeTx(request19));
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request19.fee);
@@ -1466,9 +1473,10 @@ public class WalletTest extends TestWithWallet {
// Create another transaction that will spend COIN + fee, which makes it require both inputs
SendRequest request20 = SendRequest.to(notMyAddr, Utils.CENT);
+ request20.feePerKb = BigInteger.ZERO;
for (int i = 0; i < 99; i++)
request20.tx.addOutput(Utils.CENT, notMyAddr);
- // If we send now, we shouldnt need 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
assertTrue(wallet.completeTx(request20));
assertEquals(BigInteger.ZERO, request20.fee);
assertEquals(1, request20.tx.getInputs().size());
@@ -1477,16 +1485,19 @@ public class WalletTest extends TestWithWallet {
request20.completed = false; request20.tx.clearInputs();
request20.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
assertTrue(wallet.completeTx(request20));
- assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(3)), request20.fee);
+ // 4kb tx.
+ assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(4)), request20.fee);
assertEquals(2, request20.tx.getInputs().size());
BigInteger outValue20 = BigInteger.ZERO;
for (TransactionOutput out : request20.tx.getOutputs())
outValue20 = outValue20.add(out.getValue());
// This time the fee we wanted to pay was more, so that should be what we paid
- assertEquals(outValue20, Utils.COIN.add(Utils.CENT).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(3))));
+ assertEquals(outValue20, Utils.COIN.add(Utils.CENT).subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.multiply(BigInteger.valueOf(4))));
- // Same as request 19, but make the change 0 (so it doesnt force fee) and make us require min fee as a result of an output < CENT
+ // Same as request 19, but make the change 0 (so it doesnt force fee) and make us require min fee as a
+ // result of an output < CENT.
SendRequest request21 = SendRequest.to(notMyAddr, Utils.CENT);
+ request21.feePerKb = BigInteger.ZERO;
for (int i = 0; i < 99; i++)
request21.tx.addOutput(Utils.CENT, notMyAddr);
request21.tx.addOutput(Utils.CENT.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE), notMyAddr);
@@ -1502,15 +1513,18 @@ public class WalletTest extends TestWithWallet {
// Test feePerKb when we aren't using ensureMinRequiredFee
// Same as request 19
SendRequest request25 = SendRequest.to(notMyAddr, Utils.CENT);
- for (int i = 0; i < 99; i++)
+ request25.feePerKb = BigInteger.ZERO;
+ for (int i = 0; i < 70; i++)
request25.tx.addOutput(Utils.CENT, notMyAddr);
- // If we send now, we shouldnt 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
assertTrue(wallet.completeTx(request25));
assertEquals(BigInteger.ZERO, request25.fee);
assertEquals(1, request25.tx.getInputs().size());
- assertEquals(100, request25.tx.getOutputs().size());
+ assertEquals(72, request25.tx.getOutputs().size());
+ System.out.println(request25.tx.bitcoinSerialize().length);
// Now reset request19 and give it a fee per kb
- request25.completed = false; request25.tx.clearInputs();
+ request25.tx.clearInputs();
+ request25 = SendRequest.forTx(request25.tx);
request25.feePerKb = Utils.CENT.divide(BigInteger.valueOf(3));
request25.ensureMinRequiredFee = false;
assertTrue(wallet.completeTx(request25));
@@ -1519,13 +1533,13 @@ public class WalletTest extends TestWithWallet {
BigInteger outValue25 = BigInteger.ZERO;
for (TransactionOutput out : request25.tx.getOutputs())
outValue25 = outValue25.add(out.getValue());
- // Our change output should be one nanocoin
+ // Our change output should be one satoshi
// Change this assert when we eventually randomize output order
assertEquals(BigInteger.ONE, request25.tx.getOutput(request25.tx.getOutputs().size() - 1).getValue());
- // and our fee should be CENT-1 nanocoin
+ // and our fee should be CENT-1 satoshi
assertEquals(outValue25, Utils.COIN.add(BigInteger.ONE));
- //Spend our CENT output
+ // Spend our CENT output.
Transaction spendTx5 = new Transaction(params);
spendTx5.addOutput(Utils.CENT, notMyAddr);
spendTx5.addInput(tx5.getOutput(0));
@@ -1557,7 +1571,7 @@ public class WalletTest extends TestWithWallet {
@Test
public void basicCategoryStepTest() throws Exception {
// Creates spends that step through the possible fee solver categories
-
+ SendRequest.DEFAULT_FEE_PER_KB = BigInteger.ZERO;
// Make sure TestWithWallet isnt doing anything crazy.
assertEquals(0, wallet.getTransactions(true).size());
@@ -1631,6 +1645,8 @@ public class WalletTest extends TestWithWallet {
assertTrue(wallet.completeTx(request6));
assertEquals(BigInteger.ZERO, request6.fee);
assertEquals(2, request6.tx.getOutputs().size()); // We should have a change output
+
+ SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
}
@Test
@@ -1701,11 +1717,10 @@ public class WalletTest extends TestWithWallet {
for (int i = 0; i < 16; i++)
request2.tx.addOutput(Utils.CENT, notMyAddr);
request2.tx.addOutput(new TransactionOutput(params, request2.tx, Utils.CENT, new byte[16]));
- request2.fee = BigInteger.ONE;
request2.feePerKb = BigInteger.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
assertTrue(wallet.completeTx(request2));
- assertEquals(BigInteger.ONE.shiftLeft(1), request2.fee);
+ assertEquals(BigInteger.valueOf(2), request2.fee);
assertEquals(4, request2.tx.getInputs().size());
}