mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-11-13 02:48:34 +00:00
Get rid of SendRequest.DEFAULT_FEE_PER_KB "constant".
If you have been reading that field, you probably want to use Transaction.REFERENCE_DEFAULT_MIN_TX_FEE. If you have been writing to that field to change the SendRequest.feePerKb default, use a Context.feePerKb instead. There is also a new Context.ensureMinRequiredFee.
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
package org.bitcoinj.core;
|
package org.bitcoinj.core;
|
||||||
|
|
||||||
|
import org.bitcoinj.core.Wallet.SendRequest;
|
||||||
import org.slf4j.*;
|
import org.slf4j.*;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.*;
|
import static com.google.common.base.Preconditions.*;
|
||||||
@@ -30,6 +31,8 @@ public class Context {
|
|||||||
private TxConfidenceTable confidenceTable;
|
private TxConfidenceTable confidenceTable;
|
||||||
private NetworkParameters params;
|
private NetworkParameters params;
|
||||||
private int eventHorizon = 100;
|
private int eventHorizon = 100;
|
||||||
|
private boolean ensureMinRequiredFee = true;
|
||||||
|
private Coin feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new context object. For now, this will be done for you by the framework. Eventually you will be
|
* Creates a new context object. For now, this will be done for you by the framework. Eventually you will be
|
||||||
@@ -46,15 +49,18 @@ public class Context {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new context object. For now, this will be done for you by the framework. Eventually you will be
|
* Creates a new custom context object. This is mainly meant for unit tests for now.
|
||||||
* expected to do this yourself in the same manner as fetching a NetworkParameters object (at the start of your app).
|
|
||||||
*
|
*
|
||||||
* @param params The network parameters that will be associated with this context.
|
* @param params The network parameters that will be associated with this context.
|
||||||
* @param eventHorizon Number of blocks after which the library will delete data and be unable to always process reorgs (see {@link #getEventHorizon()}.
|
* @param eventHorizon Number of blocks after which the library will delete data and be unable to always process reorgs (see {@link #getEventHorizon()}.
|
||||||
|
* @param feePerKb The default fee per 1000 bytes of transaction data to pay when completing transactions. For details, see {@link SendRequest#feePerKb}.
|
||||||
|
* @param ensureMinRequiredFee Whether to ensure the minimum required fee by default when completing transactions. For details, see {@link SendRequest#ensureMinRequiredFee}.
|
||||||
*/
|
*/
|
||||||
public Context(NetworkParameters params, int eventHorizon) {
|
public Context(NetworkParameters params, int eventHorizon, Coin feePerKb, boolean ensureMinRequiredFee) {
|
||||||
this(params);
|
this(params);
|
||||||
this.eventHorizon = eventHorizon;
|
this.eventHorizon = eventHorizon;
|
||||||
|
this.feePerKb = feePerKb;
|
||||||
|
this.ensureMinRequiredFee = ensureMinRequiredFee;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static volatile Context lastConstructed;
|
private static volatile Context lastConstructed;
|
||||||
@@ -155,4 +161,18 @@ public class Context {
|
|||||||
public int getEventHorizon() {
|
public int getEventHorizon() {
|
||||||
return eventHorizon;
|
return eventHorizon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The default fee per 1000 bytes of transaction data to pay when completing transactions. For details, see {@link SendRequest#feePerKb}.
|
||||||
|
*/
|
||||||
|
public Coin getFeePerKb() {
|
||||||
|
return feePerKb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether to ensure the minimum required fee by default when completing transactions. For details, see {@link SendRequest#ensureMinRequiredFee}.
|
||||||
|
*/
|
||||||
|
public boolean isEnsureMinRequiredFee() {
|
||||||
|
return ensureMinRequiredFee;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3721,13 +3721,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* when choosing which transactions to add to a block. Note that, to keep this equivalent to Bitcoin Core
|
* when choosing which transactions to add to a block. Note that, to keep this equivalent to Bitcoin Core
|
||||||
* definition, a kilobyte is defined as 1000 bytes, not 1024.</p>
|
* definition, a kilobyte is defined as 1000 bytes, not 1024.</p>
|
||||||
*/
|
*/
|
||||||
public Coin feePerKb = DEFAULT_FEE_PER_KB;
|
public Coin feePerKb = Context.get().getFeePerKb();
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 Coin DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <p>Requires that there be enough fee for a default Bitcoin Core to at least relay the transaction.
|
* <p>Requires that there be enough fee for a default Bitcoin Core to at least relay the transaction.
|
||||||
@@ -3738,7 +3732,7 @@ public class Wallet extends BaseTaggableObject
|
|||||||
* 26,000 bytes. If you get a transaction which is that large, you should set a feePerKb of at least
|
* 26,000 bytes. If you get a transaction which is that large, you should set a feePerKb of at least
|
||||||
* {@link Transaction#REFERENCE_DEFAULT_MIN_TX_FEE}.</p>
|
* {@link Transaction#REFERENCE_DEFAULT_MIN_TX_FEE}.</p>
|
||||||
*/
|
*/
|
||||||
public boolean ensureMinRequiredFee = true;
|
public boolean ensureMinRequiredFee = Context.get().isEnsureMinRequiredFee();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If true (the default), the inputs will be signed.
|
* If true (the default), the inputs will be signed.
|
||||||
|
|||||||
@@ -37,9 +37,6 @@ import java.util.Arrays;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import static org.bitcoinj.core.Coin.FIFTY_COINS;
|
import static org.bitcoinj.core.Coin.FIFTY_COINS;
|
||||||
import org.bitcoinj.store.BlockStore;
|
|
||||||
import org.bitcoinj.store.MemoryBlockStore;
|
|
||||||
import org.bitcoinj.testing.FakeTxBuilder;
|
|
||||||
import static org.junit.Assert.*;
|
import static org.junit.Assert.*;
|
||||||
import org.junit.rules.ExpectedException;
|
import org.junit.rules.ExpectedException;
|
||||||
|
|
||||||
@@ -60,12 +57,11 @@ public abstract class AbstractFullPrunedBlockChainTest {
|
|||||||
};
|
};
|
||||||
protected FullPrunedBlockChain chain;
|
protected FullPrunedBlockChain chain;
|
||||||
protected FullPrunedBlockStore store;
|
protected FullPrunedBlockStore store;
|
||||||
protected Context context;
|
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
BriefLogFormatter.init();
|
BriefLogFormatter.init();
|
||||||
context = new Context(PARAMS);
|
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract FullPrunedBlockStore createStore(NetworkParameters params, int blockCount)
|
public abstract FullPrunedBlockStore createStore(NetworkParameters params, int blockCount)
|
||||||
|
|||||||
@@ -73,11 +73,10 @@ public class BlockChainTest {
|
|||||||
@Before
|
@Before
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
BriefLogFormatter.initVerbose();
|
BriefLogFormatter.initVerbose();
|
||||||
Context testNetContext = new Context(testNet);
|
Context.propagate(new Context(testNet, 100, Coin.ZERO, false));
|
||||||
testNetChain = new BlockChain(testNet, new Wallet(testNetContext), new MemoryBlockStore(testNet));
|
testNetChain = new BlockChain(testNet, new Wallet(testNet), new MemoryBlockStore(testNet));
|
||||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, false));
|
||||||
Context context = new Context(PARAMS);
|
wallet = new Wallet(PARAMS) {
|
||||||
wallet = new Wallet(context) {
|
|
||||||
@Override
|
@Override
|
||||||
public void receiveFromBlock(Transaction tx, StoredBlock block, BlockChain.NewBlockType blockType,
|
public void receiveFromBlock(Transaction tx, StoredBlock block, BlockChain.NewBlockType blockType,
|
||||||
int relativityOffset) throws VerificationException {
|
int relativityOffset) throws VerificationException {
|
||||||
@@ -96,11 +95,6 @@ public class BlockChainTest {
|
|||||||
coinbaseTo = wallet.currentReceiveKey().toAddress(PARAMS);
|
coinbaseTo = wallet.currentReceiveKey().toAddress(PARAMS);
|
||||||
}
|
}
|
||||||
|
|
||||||
@After
|
|
||||||
public void tearDown() {
|
|
||||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testBasicChaining() throws Exception {
|
public void testBasicChaining() throws Exception {
|
||||||
// Check that we can plug a few blocks together and the futures work.
|
// Check that we can plug a few blocks together and the futures work.
|
||||||
|
|||||||
@@ -59,10 +59,9 @@ 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 = Coin.ZERO;
|
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, false));
|
||||||
Context context = new Context(PARAMS);
|
|
||||||
MemoryBlockStore blockStore = new MemoryBlockStore(PARAMS);
|
MemoryBlockStore blockStore = new MemoryBlockStore(PARAMS);
|
||||||
wallet = new Wallet(context);
|
wallet = new Wallet(PARAMS);
|
||||||
ECKey key1 = wallet.freshReceiveKey();
|
ECKey key1 = wallet.freshReceiveKey();
|
||||||
ECKey key2 = wallet.freshReceiveKey();
|
ECKey key2 = wallet.freshReceiveKey();
|
||||||
chain = new BlockChain(PARAMS, wallet, blockStore);
|
chain = new BlockChain(PARAMS, wallet, blockStore);
|
||||||
|
|||||||
@@ -244,7 +244,6 @@ public class TransactionBroadcastTest extends TestWithPeerGroup {
|
|||||||
// Do the same thing with an offline transaction.
|
// Do the same thing with an offline transaction.
|
||||||
peerGroup.removeWallet(wallet);
|
peerGroup.removeWallet(wallet);
|
||||||
Wallet.SendRequest req = Wallet.SendRequest.to(dest, valueOf(2, 0));
|
Wallet.SendRequest req = Wallet.SendRequest.to(dest, valueOf(2, 0));
|
||||||
req.ensureMinRequiredFee = false;
|
|
||||||
Transaction t3 = checkNotNull(wallet.sendCoinsOffline(req));
|
Transaction t3 = checkNotNull(wallet.sendCoinsOffline(req));
|
||||||
assertNull(outbound(p1)); // Nothing sent.
|
assertNull(outbound(p1)); // Nothing sent.
|
||||||
// Add the wallet to the peer group (simulate initialization). Transactions should be announced.
|
// Add the wallet to the peer group (simulate initialization). Transactions should be announced.
|
||||||
|
|||||||
@@ -313,7 +313,6 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
// Try to create a send with a fee but no password (this should fail).
|
// Try to create a send with a fee but no password (this should fail).
|
||||||
try {
|
try {
|
||||||
req.ensureMinRequiredFee = false;
|
|
||||||
wallet.completeTx(req);
|
wallet.completeTx(req);
|
||||||
fail();
|
fail();
|
||||||
} catch (ECKey.MissingPrivateKeyException kce) {
|
} catch (ECKey.MissingPrivateKeyException kce) {
|
||||||
@@ -324,7 +323,6 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Try to create a send with a fee but the wrong password (this should fail).
|
// Try to create a send with a fee but the wrong password (this should fail).
|
||||||
req = Wallet.SendRequest.to(destination, v2);
|
req = Wallet.SendRequest.to(destination, v2);
|
||||||
req.aesKey = wrongAesKey;
|
req.aesKey = wrongAesKey;
|
||||||
req.ensureMinRequiredFee = false;
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
wallet.completeTx(req);
|
wallet.completeTx(req);
|
||||||
@@ -339,7 +337,6 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Create a send with a fee with the correct password (this should succeed).
|
// Create a send with a fee with the correct password (this should succeed).
|
||||||
req = Wallet.SendRequest.to(destination, v2);
|
req = Wallet.SendRequest.to(destination, v2);
|
||||||
req.aesKey = aesKey;
|
req.aesKey = aesKey;
|
||||||
req.ensureMinRequiredFee = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Complete the transaction successfully.
|
// Complete the transaction successfully.
|
||||||
@@ -438,7 +435,6 @@ public class WalletTest extends TestWithWallet {
|
|||||||
assertEquals(v3, wallet.getBalance());
|
assertEquals(v3, wallet.getBalance());
|
||||||
Wallet.SendRequest req = Wallet.SendRequest.to(new ECKey().toAddress(PARAMS), valueOf(0, 48));
|
Wallet.SendRequest req = Wallet.SendRequest.to(new ECKey().toAddress(PARAMS), valueOf(0, 48));
|
||||||
req.aesKey = aesKey;
|
req.aesKey = aesKey;
|
||||||
req.ensureMinRequiredFee = false;
|
|
||||||
req.shuffleOutputs = false;
|
req.shuffleOutputs = false;
|
||||||
wallet.completeTx(req);
|
wallet.completeTx(req);
|
||||||
Transaction t3 = req.tx;
|
Transaction t3 = req.tx;
|
||||||
@@ -478,7 +474,6 @@ public class WalletTest extends TestWithWallet {
|
|||||||
t2.addOutput(v3, a2);
|
t2.addOutput(v3, a2);
|
||||||
t2.addOutput(v4, a2);
|
t2.addOutput(v4, a2);
|
||||||
SendRequest req = SendRequest.forTx(t2);
|
SendRequest req = SendRequest.forTx(t2);
|
||||||
req.ensureMinRequiredFee = false;
|
|
||||||
wallet.completeTx(req);
|
wallet.completeTx(req);
|
||||||
|
|
||||||
// Do some basic sanity checks.
|
// Do some basic sanity checks.
|
||||||
@@ -1901,7 +1896,6 @@ public class WalletTest extends TestWithWallet {
|
|||||||
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);
|
||||||
SendRequest req = SendRequest.forTx(t2);
|
SendRequest req = SendRequest.forTx(t2);
|
||||||
req.ensureMinRequiredFee = false;
|
|
||||||
wallet.completeTx(req);
|
wallet.completeTx(req);
|
||||||
|
|
||||||
// Commit t2, so it is placed in the pending pool
|
// Commit t2, so it is placed in the pending pool
|
||||||
@@ -2195,6 +2189,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Script script = ScriptBuilder.createOpReturnScript("hello world!".getBytes());
|
Script script = ScriptBuilder.createOpReturnScript("hello world!".getBytes());
|
||||||
tx.addOutput(messagePrice, script);
|
tx.addOutput(messagePrice, script);
|
||||||
SendRequest request = Wallet.SendRequest.forTx(tx);
|
SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||||
|
request.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2235,6 +2230,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
tx.addOutput(messagePrice, script1);
|
tx.addOutput(messagePrice, script1);
|
||||||
tx.addOutput(messagePrice, script2);
|
tx.addOutput(messagePrice, script2);
|
||||||
SendRequest request = Wallet.SendRequest.forTx(tx);
|
SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||||
|
request.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2245,6 +2241,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Address notMyAddr = new ECKey().toAddress(PARAMS);
|
Address notMyAddr = new ECKey().toAddress(PARAMS);
|
||||||
tx.addOutput(Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI), notMyAddr);
|
tx.addOutput(Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI), notMyAddr);
|
||||||
SendRequest request = Wallet.SendRequest.forTx(tx);
|
SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||||
|
request.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2271,6 +2268,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
tx.addOutput(Coin.ZERO, ScriptBuilder.createOpReturnScript("hello world!".getBytes()));
|
tx.addOutput(Coin.ZERO, ScriptBuilder.createOpReturnScript("hello world!".getBytes()));
|
||||||
tx.addOutput(Coin.SATOSHI, notMyAddr);
|
tx.addOutput(Coin.SATOSHI, notMyAddr);
|
||||||
SendRequest request = Wallet.SendRequest.forTx(tx);
|
SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||||
|
request.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2283,6 +2281,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
tx.addOutput(Coin.CENT, ScriptBuilder.createOpReturnScript("hello world!".getBytes()));
|
tx.addOutput(Coin.CENT, ScriptBuilder.createOpReturnScript("hello world!".getBytes()));
|
||||||
tx.addOutput(Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI), notMyAddr);
|
tx.addOutput(Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI), notMyAddr);
|
||||||
SendRequest request = Wallet.SendRequest.forTx(tx);
|
SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||||
|
request.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2323,14 +2322,15 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
// Not allowed to send dust.
|
// Not allowed to send dust.
|
||||||
try {
|
try {
|
||||||
wallet.createSend(notMyAddr, SATOSHI);
|
SendRequest request = SendRequest.to(notMyAddr, SATOSHI);
|
||||||
|
request.ensureMinRequiredFee = true;
|
||||||
|
wallet.completeTx(request);
|
||||||
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, SATOSHI.multiply(12));
|
SendRequest req = SendRequest.to(notMyAddr, SATOSHI.multiply(12));
|
||||||
req.ensureMinRequiredFee = false;
|
|
||||||
assertNotNull(wallet.sendCoinsOffline(req));
|
assertNotNull(wallet.sendCoinsOffline(req));
|
||||||
assertEquals(ZERO, wallet.getBalance());
|
assertEquals(ZERO, wallet.getBalance());
|
||||||
|
|
||||||
@@ -2340,7 +2340,10 @@ 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(SATOSHI));
|
SendRequest request1 = SendRequest.to(notMyAddr, CENT.subtract(SATOSHI));
|
||||||
|
request1.ensureMinRequiredFee = true;
|
||||||
|
wallet.completeTx(request1);
|
||||||
|
Transaction spend1 = request1.tx;
|
||||||
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.
|
||||||
@@ -2348,7 +2351,10 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||||
|
|
||||||
// But not at exactly 0.01
|
// But not at exactly 0.01
|
||||||
Transaction spend2 = wallet.createSend(notMyAddr, CENT);
|
SendRequest request2 = SendRequest.to(notMyAddr, CENT);
|
||||||
|
request2.ensureMinRequiredFee = true;
|
||||||
|
wallet.completeTx(request2);
|
||||||
|
Transaction spend2 = request2.tx;
|
||||||
assertEquals(2, spend2.getOutputs().size());
|
assertEquals(2, spend2.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(Coin.COIN, spend2.getOutput(0).getValue().add(spend2.getOutput(1).getValue()));
|
assertEquals(Coin.COIN, spend2.getOutput(0).getValue().add(spend2.getOutput(1).getValue()));
|
||||||
@@ -2356,6 +2362,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// ...but not more fee than what we request
|
// ...but not more fee than what we request
|
||||||
SendRequest request3 = SendRequest.to(notMyAddr, CENT.subtract(SATOSHI));
|
SendRequest request3 = SendRequest.to(notMyAddr, CENT.subtract(SATOSHI));
|
||||||
request3.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI);
|
request3.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI);
|
||||||
|
request3.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request3);
|
wallet.completeTx(request3);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI), request3.tx.getFee());
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI), request3.tx.getFee());
|
||||||
Transaction spend3 = request3.tx;
|
Transaction spend3 = request3.tx;
|
||||||
@@ -2367,6 +2374,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// ...unless we need it
|
// ...unless we need it
|
||||||
SendRequest request4 = SendRequest.to(notMyAddr, CENT.subtract(SATOSHI));
|
SendRequest request4 = SendRequest.to(notMyAddr, CENT.subtract(SATOSHI));
|
||||||
request4.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(SATOSHI);
|
request4.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(SATOSHI);
|
||||||
|
request4.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request4);
|
wallet.completeTx(request4);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request4.tx.getFee());
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request4.tx.getFee());
|
||||||
Transaction spend4 = request4.tx;
|
Transaction spend4 = request4.tx;
|
||||||
@@ -2376,6 +2384,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||||
|
|
||||||
SendRequest request5 = SendRequest.to(notMyAddr, Coin.COIN.subtract(CENT.subtract(SATOSHI)));
|
SendRequest request5 = SendRequest.to(notMyAddr, Coin.COIN.subtract(CENT.subtract(SATOSHI)));
|
||||||
|
request5.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request5);
|
wallet.completeTx(request5);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request5.tx.getFee());
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request5.tx.getFee());
|
||||||
Transaction spend5 = request5.tx;
|
Transaction spend5 = request5.tx;
|
||||||
@@ -2386,6 +2395,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||||
|
|
||||||
SendRequest request6 = SendRequest.to(notMyAddr, Coin.COIN.subtract(CENT));
|
SendRequest request6 = SendRequest.to(notMyAddr, Coin.COIN.subtract(CENT));
|
||||||
|
request6.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request6);
|
wallet.completeTx(request6);
|
||||||
assertEquals(ZERO, request6.tx.getFee());
|
assertEquals(ZERO, request6.tx.getFee());
|
||||||
Transaction spend6 = request6.tx;
|
Transaction spend6 = request6.tx;
|
||||||
@@ -2395,6 +2405,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
assertEquals(Coin.COIN, spend6.getOutput(0).getValue().add(spend6.getOutput(1).getValue()));
|
assertEquals(Coin.COIN, spend6.getOutput(0).getValue().add(spend6.getOutput(1).getValue()));
|
||||||
|
|
||||||
SendRequest request7 = SendRequest.to(notMyAddr, Coin.COIN.subtract(CENT.subtract(SATOSHI.multiply(2)).multiply(2)));
|
SendRequest request7 = SendRequest.to(notMyAddr, Coin.COIN.subtract(CENT.subtract(SATOSHI.multiply(2)).multiply(2)));
|
||||||
|
request7.ensureMinRequiredFee = true;
|
||||||
request7.tx.addOutput(CENT.subtract(SATOSHI), notMyAddr);
|
request7.tx.addOutput(CENT.subtract(SATOSHI), notMyAddr);
|
||||||
wallet.completeTx(request7);
|
wallet.completeTx(request7);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request7.tx.getFee());
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request7.tx.getFee());
|
||||||
@@ -2406,6 +2417,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||||
|
|
||||||
SendRequest request8 = SendRequest.to(notMyAddr, COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
SendRequest request8 = SendRequest.to(notMyAddr, COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||||
|
request8.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request8);
|
wallet.completeTx(request8);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request8.tx.getFee());
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request8.tx.getFee());
|
||||||
Transaction spend8 = request8.tx;
|
Transaction spend8 = request8.tx;
|
||||||
@@ -2416,6 +2428,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
SendRequest request9 = SendRequest.to(notMyAddr, COIN.subtract(
|
SendRequest request9 = SendRequest.to(notMyAddr, COIN.subtract(
|
||||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).subtract(SATOSHI)));
|
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).subtract(SATOSHI)));
|
||||||
|
request9.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request9);
|
wallet.completeTx(request9);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).subtract(SATOSHI), request9.tx.getFee());
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).subtract(SATOSHI), request9.tx.getFee());
|
||||||
Transaction spend9 = request9.tx;
|
Transaction spend9 = request9.tx;
|
||||||
@@ -2427,6 +2440,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
SendRequest request10 = SendRequest.to(notMyAddr, COIN.subtract(
|
SendRequest request10 = SendRequest.to(notMyAddr, COIN.subtract(
|
||||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)));
|
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)));
|
||||||
|
request10.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request10);
|
wallet.completeTx(request10);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request10.tx.getFee());
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request10.tx.getFee());
|
||||||
Transaction spend10 = request10.tx;
|
Transaction spend10 = request10.tx;
|
||||||
@@ -2439,6 +2453,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
SendRequest request11 = SendRequest.to(notMyAddr, COIN.subtract(
|
SendRequest request11 = SendRequest.to(notMyAddr, COIN.subtract(
|
||||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(SATOSHI.multiply(2))));
|
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).add(SATOSHI.multiply(2))));
|
||||||
request11.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI);
|
request11.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI);
|
||||||
|
request11.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request11);
|
wallet.completeTx(request11);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI), request11.tx.getFee());
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI), request11.tx.getFee());
|
||||||
Transaction spend11 = request11.tx;
|
Transaction spend11 = request11.tx;
|
||||||
@@ -2491,6 +2506,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
request15.tx.addOutput(CENT, notMyAddr);
|
request15.tx.addOutput(CENT, notMyAddr);
|
||||||
assertTrue(request15.tx.unsafeBitcoinSerialize().length > 1000);
|
assertTrue(request15.tx.unsafeBitcoinSerialize().length > 1000);
|
||||||
request15.feePerKb = SATOSHI;
|
request15.feePerKb = SATOSHI;
|
||||||
|
request15.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request15);
|
wallet.completeTx(request15);
|
||||||
assertEquals(SATOSHI.multiply(2), request15.tx.getFee());
|
assertEquals(SATOSHI.multiply(2), request15.tx.getFee());
|
||||||
Transaction spend15 = request15.tx;
|
Transaction spend15 = request15.tx;
|
||||||
@@ -2504,6 +2520,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
SendRequest request16 = SendRequest.to(notMyAddr, CENT);
|
SendRequest request16 = SendRequest.to(notMyAddr, CENT);
|
||||||
request16.feePerKb = ZERO;
|
request16.feePerKb = ZERO;
|
||||||
|
request16.ensureMinRequiredFee = true;
|
||||||
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.unsafeBitcoinSerialize().length > 1000);
|
assertTrue(request16.tx.unsafeBitcoinSerialize().length > 1000);
|
||||||
@@ -2524,6 +2541,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
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 = SATOSHI;
|
request17.feePerKb = SATOSHI;
|
||||||
|
request17.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request17);
|
wallet.completeTx(request17);
|
||||||
assertEquals(SATOSHI, request17.tx.getFee());
|
assertEquals(SATOSHI, request17.tx.getFee());
|
||||||
assertEquals(1, request17.tx.getInputs().size());
|
assertEquals(1, request17.tx.getInputs().size());
|
||||||
@@ -2552,6 +2570,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
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 = SATOSHI;
|
request18.feePerKb = SATOSHI;
|
||||||
|
request18.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request18);
|
wallet.completeTx(request18);
|
||||||
assertEquals(SATOSHI.multiply(2), request18.tx.getFee());
|
assertEquals(SATOSHI.multiply(2), request18.tx.getFee());
|
||||||
assertEquals(1, request18.tx.getInputs().size());
|
assertEquals(1, request18.tx.getInputs().size());
|
||||||
@@ -2576,6 +2595,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
assertEquals(wallet.getBalance(), CENT.add(COIN));
|
assertEquals(wallet.getBalance(), CENT.add(COIN));
|
||||||
SendRequest request19 = SendRequest.to(notMyAddr, CENT);
|
SendRequest request19 = SendRequest.to(notMyAddr, CENT);
|
||||||
request19.feePerKb = ZERO;
|
request19.feePerKb = ZERO;
|
||||||
|
request19.ensureMinRequiredFee = true;
|
||||||
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
|
||||||
@@ -2586,6 +2606,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// 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.ensureMinRequiredFee = true;
|
||||||
request19.feePerKb = SATOSHI;
|
request19.feePerKb = SATOSHI;
|
||||||
request19.shuffleOutputs = false;
|
request19.shuffleOutputs = false;
|
||||||
wallet.completeTx(request19);
|
wallet.completeTx(request19);
|
||||||
@@ -2601,6 +2622,7 @@ 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 = ZERO;
|
request20.feePerKb = ZERO;
|
||||||
|
request20.ensureMinRequiredFee = true;
|
||||||
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
|
||||||
@@ -2626,6 +2648,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// result of an output < CENT.
|
// result of an output < CENT.
|
||||||
SendRequest request21 = SendRequest.to(notMyAddr, CENT);
|
SendRequest request21 = SendRequest.to(notMyAddr, CENT);
|
||||||
request21.feePerKb = ZERO;
|
request21.feePerKb = ZERO;
|
||||||
|
request21.ensureMinRequiredFee = true;
|
||||||
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);
|
||||||
@@ -2642,6 +2665,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
// Same as request 19
|
// Same as request 19
|
||||||
SendRequest request25 = SendRequest.to(notMyAddr, CENT);
|
SendRequest request25 = SendRequest.to(notMyAddr, CENT);
|
||||||
request25.feePerKb = ZERO;
|
request25.feePerKb = ZERO;
|
||||||
|
request25.ensureMinRequiredFee = true;
|
||||||
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
|
||||||
@@ -2653,7 +2677,6 @@ public class WalletTest extends TestWithWallet {
|
|||||||
request25.tx.clearInputs();
|
request25.tx.clearInputs();
|
||||||
request25 = SendRequest.forTx(request25.tx);
|
request25 = SendRequest.forTx(request25.tx);
|
||||||
request25.feePerKb = CENT.divide(3);
|
request25.feePerKb = CENT.divide(3);
|
||||||
request25.ensureMinRequiredFee = false;
|
|
||||||
request25.shuffleOutputs = false;
|
request25.shuffleOutputs = false;
|
||||||
wallet.completeTx(request25);
|
wallet.completeTx(request25);
|
||||||
assertEquals(CENT.subtract(SATOSHI), request25.tx.getFee());
|
assertEquals(CENT.subtract(SATOSHI), request25.tx.getFee());
|
||||||
@@ -2684,6 +2707,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
notMyAddr);
|
notMyAddr);
|
||||||
assertTrue(request26.tx.unsafeBitcoinSerialize().length > 1000);
|
assertTrue(request26.tx.unsafeBitcoinSerialize().length > 1000);
|
||||||
request26.feePerKb = SATOSHI;
|
request26.feePerKb = SATOSHI;
|
||||||
|
request26.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request26);
|
wallet.completeTx(request26);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).subtract(SATOSHI),
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).subtract(SATOSHI),
|
||||||
request26.tx.getFee());
|
request26.tx.getFee());
|
||||||
@@ -2701,7 +2725,6 @@ 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 = 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());
|
||||||
|
|
||||||
@@ -2720,6 +2743,7 @@ 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, balance.subtract(SATOSHI));
|
SendRequest request1 = SendRequest.to(notMyAddr, balance.subtract(SATOSHI));
|
||||||
|
request1.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request1);
|
wallet.completeTx(request1);
|
||||||
assertEquals(SATOSHI, request1.tx.getFee());
|
assertEquals(SATOSHI, request1.tx.getFee());
|
||||||
assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs
|
assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs
|
||||||
@@ -2731,6 +2755,7 @@ 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)
|
||||||
SendRequest request2 = SendRequest.to(notMyAddr, balance.subtract(SATOSHI));
|
SendRequest request2 = SendRequest.to(notMyAddr, balance.subtract(SATOSHI));
|
||||||
|
request2.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request2);
|
wallet.completeTx(request2);
|
||||||
assertEquals(SATOSHI, request2.tx.getFee());
|
assertEquals(SATOSHI, request2.tx.getFee());
|
||||||
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
|
||||||
@@ -2743,6 +2768,7 @@ 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(tenThousand).subtract(SATOSHI));
|
SendRequest request3 = SendRequest.to(notMyAddr, CENT.add(tenThousand).subtract(SATOSHI));
|
||||||
|
request3.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request3);
|
wallet.completeTx(request3);
|
||||||
assertEquals(SATOSHI, request3.tx.getFee());
|
assertEquals(SATOSHI, request3.tx.getFee());
|
||||||
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
|
||||||
@@ -2750,6 +2776,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
//
|
//
|
||||||
SendRequest request4 = SendRequest.to(notMyAddr, balance.subtract(SATOSHI));
|
SendRequest request4 = SendRequest.to(notMyAddr, balance.subtract(SATOSHI));
|
||||||
request4.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.divide(request3.tx.unsafeBitcoinSerialize().length);
|
request4.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.divide(request3.tx.unsafeBitcoinSerialize().length);
|
||||||
|
request4.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request4);
|
wallet.completeTx(request4);
|
||||||
assertEquals(SATOSHI, request4.tx.getFee());
|
assertEquals(SATOSHI, request4.tx.getFee());
|
||||||
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
|
||||||
@@ -2763,6 +2790,7 @@ 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(tenThousand).subtract(SATOSHI));
|
SendRequest request5 = SendRequest.to(notMyAddr, CENT.add(tenThousand).subtract(SATOSHI));
|
||||||
|
request5.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request5);
|
wallet.completeTx(request5);
|
||||||
assertEquals(SATOSHI, request5.tx.getFee());
|
assertEquals(SATOSHI, request5.tx.getFee());
|
||||||
assertEquals(1, request5.tx.getOutputs().size()); // We should have no change output
|
assertEquals(1, request5.tx.getOutputs().size()); // We should have no change output
|
||||||
@@ -2774,11 +2802,10 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
// ... that puts us in category 1 (no fee!)
|
// ... that puts us in category 1 (no fee!)
|
||||||
SendRequest request6 = SendRequest.to(notMyAddr, CENT.add(tenThousand).subtract(SATOSHI));
|
SendRequest request6 = SendRequest.to(notMyAddr, CENT.add(tenThousand).subtract(SATOSHI));
|
||||||
|
request6.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request6);
|
wallet.completeTx(request6);
|
||||||
assertEquals(ZERO, request6.tx.getFee());
|
assertEquals(ZERO, request6.tx.getFee());
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -2801,6 +2828,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
|
|
||||||
// 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(SATOSHI));
|
SendRequest request1 = SendRequest.to(notMyAddr, CENT.add(SATOSHI));
|
||||||
|
request1.ensureMinRequiredFee = true;
|
||||||
wallet.completeTx(request1);
|
wallet.completeTx(request1);
|
||||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request1.tx.getFee());
|
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request1.tx.getFee());
|
||||||
assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs
|
assertEquals(request1.tx.getInputs().size(), i); // We should have spent all inputs
|
||||||
@@ -2834,6 +2862,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
wallet.commitTx(req.tx);
|
wallet.commitTx(req.tx);
|
||||||
SendRequest emptyReq = SendRequest.emptyWallet(myAddress);
|
SendRequest emptyReq = SendRequest.emptyWallet(myAddress);
|
||||||
emptyReq.feePerKb = fee;
|
emptyReq.feePerKb = fee;
|
||||||
|
emptyReq.ensureMinRequiredFee = true;
|
||||||
emptyReq.emptyWallet = true;
|
emptyReq.emptyWallet = true;
|
||||||
emptyReq.coinSelector = AllowUnconfirmedCoinSelector.get();
|
emptyReq.coinSelector = AllowUnconfirmedCoinSelector.get();
|
||||||
wallet.completeTx(emptyReq);
|
wallet.completeTx(emptyReq);
|
||||||
@@ -2883,6 +2912,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
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.feePerKb = SATOSHI;
|
request1.feePerKb = SATOSHI;
|
||||||
|
request1.ensureMinRequiredFee = true;
|
||||||
// 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)
|
||||||
@@ -2901,6 +2931,7 @@ public class WalletTest extends TestWithWallet {
|
|||||||
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 = SATOSHI;
|
request2.feePerKb = SATOSHI;
|
||||||
|
request2.ensureMinRequiredFee = true;
|
||||||
// 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(SATOSHI.multiply(2), request2.tx.getFee());
|
assertEquals(SATOSHI.multiply(2), request2.tx.getFee());
|
||||||
@@ -3022,45 +3053,37 @@ public class WalletTest extends TestWithWallet {
|
|||||||
Transaction tx = createFakeTx(PARAMS, CENT, myAddress);
|
Transaction tx = createFakeTx(PARAMS, CENT, myAddress);
|
||||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
SendRequest request = SendRequest.emptyWallet(outputKey);
|
SendRequest request = SendRequest.emptyWallet(outputKey);
|
||||||
request.ensureMinRequiredFee = false;
|
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
assertEquals(Wallet.SendRequest.DEFAULT_FEE_PER_KB, request.tx.getFee());
|
assertEquals(ZERO, request.tx.getFee());
|
||||||
wallet.commitTx(request.tx);
|
wallet.commitTx(request.tx);
|
||||||
assertEquals(ZERO, wallet.getBalance());
|
assertEquals(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
|
||||||
// policies that are in use by default.
|
// policies that are in use by default.
|
||||||
block = new StoredBlock(makeSolvedTestBlock(blockStore, outputKey), BigInteger.ONE, 1);
|
block = new StoredBlock(makeSolvedTestBlock(blockStore, outputKey), BigInteger.ONE, 2);
|
||||||
tx = createFakeTx(PARAMS, CENT, myAddress);
|
tx = createFakeTx(PARAMS, CENT, myAddress);
|
||||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
tx = createFakeTx(PARAMS, CENT, myAddress);
|
tx = createFakeTx(PARAMS, CENT, myAddress);
|
||||||
wallet.receivePending(tx, null);
|
wallet.receivePending(tx, null);
|
||||||
request = SendRequest.emptyWallet(outputKey);
|
request = SendRequest.emptyWallet(outputKey);
|
||||||
request.ensureMinRequiredFee = false;
|
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
assertEquals(Wallet.SendRequest.DEFAULT_FEE_PER_KB, request.tx.getFee());
|
assertEquals(ZERO, request.tx.getFee());
|
||||||
wallet.commitTx(request.tx);
|
wallet.commitTx(request.tx);
|
||||||
assertEquals(ZERO, wallet.getBalance());
|
assertEquals(ZERO, wallet.getBalance());
|
||||||
assertEquals(CENT, request.tx.getOutput(0).getValue());
|
assertEquals(CENT, request.tx.getOutput(0).getValue());
|
||||||
|
|
||||||
// Add an unsendable value
|
// Add an unsendable value
|
||||||
StoredBlock block2 = new StoredBlock(block.getHeader().createNextBlock(outputKey), BigInteger.ONE, 3);
|
block = new StoredBlock(block.getHeader().createNextBlock(outputKey), BigInteger.ONE, 3);
|
||||||
Coin outputValue = Transaction.MIN_NONDUST_OUTPUT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(SATOSHI);
|
Coin outputValue = Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI);
|
||||||
tx = createFakeTx(PARAMS, outputValue, myAddress);
|
tx = createFakeTx(PARAMS, outputValue, myAddress);
|
||||||
wallet.receiveFromBlock(tx, block2, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||||
try {
|
try {
|
||||||
request = SendRequest.emptyWallet(outputKey);
|
request = SendRequest.emptyWallet(outputKey);
|
||||||
|
assertEquals(ZERO, request.tx.getFee());
|
||||||
wallet.completeTx(request);
|
wallet.completeTx(request);
|
||||||
fail();
|
fail();
|
||||||
} catch (Wallet.CouldNotAdjustDownwards e) {}
|
} catch (Wallet.CouldNotAdjustDownwards e) {}
|
||||||
request = SendRequest.emptyWallet(outputKey);
|
|
||||||
request.ensureMinRequiredFee = false;
|
|
||||||
wallet.completeTx(request);
|
|
||||||
assertEquals(ZERO, request.tx.getFee());
|
|
||||||
wallet.commitTx(request.tx);
|
|
||||||
assertEquals(ZERO, wallet.getBalance());
|
|
||||||
assertEquals(outputValue, request.tx.getOutput(0).getValue());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -102,11 +102,11 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
super.setUp();
|
super.setUp();
|
||||||
Utils.setMockClock(); // Use mock clock
|
Utils.setMockClock(); // Use mock clock
|
||||||
|
Context.propagate(new Context(PARAMS, 3, Coin.ZERO, false)); // Shorter event horizon for unit tests.
|
||||||
sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
sendMoneyToWallet(COIN, AbstractBlockChain.NewBlockType.BEST_CHAIN);
|
||||||
wallet.addExtension(new StoredPaymentChannelClientStates(wallet, failBroadcaster));
|
wallet.addExtension(new StoredPaymentChannelClientStates(wallet, failBroadcaster));
|
||||||
Context context = new Context(PARAMS, 3); // Shorter event horizon for unit tests.
|
serverWallet = new Wallet(PARAMS);
|
||||||
serverWallet = new Wallet(context);
|
|
||||||
serverWallet.addExtension(new StoredPaymentChannelServerStates(serverWallet, failBroadcaster));
|
serverWallet.addExtension(new StoredPaymentChannelServerStates(serverWallet, failBroadcaster));
|
||||||
serverWallet.freshReceiveKey();
|
serverWallet.freshReceiveKey();
|
||||||
// Use an atomic boolean to indicate failure because fail()/assert*() dont work in network threads
|
// Use an atomic boolean to indicate failure because fail()/assert*() dont work in network threads
|
||||||
@@ -163,7 +163,7 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
exectuteSimpleChannelTest(userKeySetup);
|
exectuteSimpleChannelTest(userKeySetup);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exectuteSimpleChannelTest(KeyParameter userKeySetup) throws Exception {
|
private void exectuteSimpleChannelTest(KeyParameter userKeySetup) throws Exception {
|
||||||
// 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<PaymentChannelV1ServerState>> serverCloseFuture = SettableFuture.create();
|
final SettableFuture<ListenableFuture<PaymentChannelV1ServerState>> serverCloseFuture = SettableFuture.create();
|
||||||
final SettableFuture<Sha256Hash> channelOpenFuture = SettableFuture.create();
|
final SettableFuture<Sha256Hash> channelOpenFuture = SettableFuture.create();
|
||||||
@@ -251,8 +251,8 @@ public class ChannelConnectionTest extends TestWithWallet {
|
|||||||
// Wait for the server thread to catch up with closing
|
// Wait for the server thread to catch up with closing
|
||||||
serverState.close().get();
|
serverState.close().get();
|
||||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||||
if (!serverState.getBestValueToMe().equals(amount) || !serverState.getFeePaid().equals(Coin.ZERO))
|
assertEquals(amount, serverState.getBestValueToMe());
|
||||||
fail();
|
assertEquals(ZERO, serverState.getFeePaid());
|
||||||
assertTrue(channels.mapChannels.isEmpty());
|
assertTrue(channels.mapChannels.isEmpty());
|
||||||
|
|
||||||
// Send the settle TX to the client wallet.
|
// Send the settle TX to the client wallet.
|
||||||
|
|||||||
@@ -88,6 +88,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
|||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
Utils.setMockClock(); // Use mock clock
|
Utils.setMockClock(); // Use mock clock
|
||||||
super.setUp();
|
super.setUp();
|
||||||
|
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, true));
|
||||||
wallet.addExtension(new StoredPaymentChannelClientStates(wallet, new TransactionBroadcaster() {
|
wallet.addExtension(new StoredPaymentChannelClientStates(wallet, new TransactionBroadcaster() {
|
||||||
@Override
|
@Override
|
||||||
public TransactionBroadcast broadcastTransaction(Transaction tx) {
|
public TransactionBroadcast broadcastTransaction(Transaction tx) {
|
||||||
|
|||||||
@@ -82,9 +82,7 @@ public class TestWithNetworkConnections {
|
|||||||
|
|
||||||
public void setUp(BlockStore blockStore) throws Exception {
|
public void setUp(BlockStore blockStore) throws Exception {
|
||||||
BriefLogFormatter.init();
|
BriefLogFormatter.init();
|
||||||
|
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, false));
|
||||||
context = new Context(PARAMS);
|
|
||||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
|
||||||
this.blockStore = blockStore;
|
this.blockStore = blockStore;
|
||||||
// Allow subclasses to override the wallet object with their own.
|
// Allow subclasses to override the wallet object with their own.
|
||||||
if (wallet == null) {
|
if (wallet == null) {
|
||||||
@@ -131,7 +129,6 @@ public class TestWithNetworkConnections {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
|
||||||
stopPeerServers();
|
stopPeerServers();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -47,8 +47,7 @@ public class TestWithWallet {
|
|||||||
|
|
||||||
public void setUp() throws Exception {
|
public void setUp() throws Exception {
|
||||||
BriefLogFormatter.init();
|
BriefLogFormatter.init();
|
||||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, false));
|
||||||
Context ctx = new Context(PARAMS);
|
|
||||||
wallet = new Wallet(PARAMS);
|
wallet = new Wallet(PARAMS);
|
||||||
myKey = wallet.currentReceiveKey();
|
myKey = wallet.currentReceiveKey();
|
||||||
myAddress = myKey.toAddress(PARAMS);
|
myAddress = myKey.toAddress(PARAMS);
|
||||||
@@ -57,7 +56,6 @@ public class TestWithWallet {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void tearDown() throws Exception {
|
public void tearDown() throws Exception {
|
||||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
|
|||||||
@@ -198,7 +198,7 @@ public class ExamplePaymentChannelClient {
|
|||||||
|
|
||||||
private void waitForSufficientBalance(Coin amount) {
|
private void waitForSufficientBalance(Coin amount) {
|
||||||
// Not enough money in the wallet.
|
// Not enough money in the wallet.
|
||||||
Coin amountPlusFee = amount.add(Wallet.SendRequest.DEFAULT_FEE_PER_KB);
|
Coin amountPlusFee = amount.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE);
|
||||||
// ESTIMATED because we don't really need to wait for confirmation.
|
// ESTIMATED because we don't really need to wait for confirmation.
|
||||||
ListenableFuture<Coin> balanceFuture = appKit.wallet().getBalanceFuture(amountPlusFee, Wallet.BalanceType.ESTIMATED);
|
ListenableFuture<Coin> balanceFuture = appKit.wallet().getBalanceFuture(amountPlusFee, Wallet.BalanceType.ESTIMATED);
|
||||||
if (!balanceFuture.isDone()) {
|
if (!balanceFuture.isDone()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user