mirror of
https://github.com/Qortal/altcoinj.git
synced 2025-07-31 20:11:23 +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;
|
||||
|
||||
import org.bitcoinj.core.Wallet.SendRequest;
|
||||
import org.slf4j.*;
|
||||
|
||||
import static com.google.common.base.Preconditions.*;
|
||||
@@ -30,6 +31,8 @@ public class Context {
|
||||
private TxConfidenceTable confidenceTable;
|
||||
private NetworkParameters params;
|
||||
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
|
||||
@@ -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
|
||||
* expected to do this yourself in the same manner as fetching a NetworkParameters object (at the start of your app).
|
||||
* Creates a new custom context object. This is mainly meant for unit tests for now.
|
||||
*
|
||||
* @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 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.eventHorizon = eventHorizon;
|
||||
this.feePerKb = feePerKb;
|
||||
this.ensureMinRequiredFee = ensureMinRequiredFee;
|
||||
}
|
||||
|
||||
private static volatile Context lastConstructed;
|
||||
@@ -155,4 +161,18 @@ public class Context {
|
||||
public int getEventHorizon() {
|
||||
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
|
||||
* definition, a kilobyte is defined as 1000 bytes, not 1024.</p>
|
||||
*/
|
||||
public Coin feePerKb = DEFAULT_FEE_PER_KB;
|
||||
|
||||
/**
|
||||
* If you want to modify the default fee for your entire app without having to change each SendRequest you make,
|
||||
* you can do it here. This is primarily useful for unit tests.
|
||||
*/
|
||||
public static Coin DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
public Coin feePerKb = Context.get().getFeePerKb();
|
||||
|
||||
/**
|
||||
* <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
|
||||
* {@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.
|
||||
|
@@ -37,9 +37,6 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
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 org.junit.rules.ExpectedException;
|
||||
|
||||
@@ -60,12 +57,11 @@ public abstract class AbstractFullPrunedBlockChainTest {
|
||||
};
|
||||
protected FullPrunedBlockChain chain;
|
||||
protected FullPrunedBlockStore store;
|
||||
protected Context context;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
BriefLogFormatter.init();
|
||||
context = new Context(PARAMS);
|
||||
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, false));
|
||||
}
|
||||
|
||||
public abstract FullPrunedBlockStore createStore(NetworkParameters params, int blockCount)
|
||||
|
@@ -73,11 +73,10 @@ public class BlockChainTest {
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
BriefLogFormatter.initVerbose();
|
||||
Context testNetContext = new Context(testNet);
|
||||
testNetChain = new BlockChain(testNet, new Wallet(testNetContext), new MemoryBlockStore(testNet));
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||
Context context = new Context(PARAMS);
|
||||
wallet = new Wallet(context) {
|
||||
Context.propagate(new Context(testNet, 100, Coin.ZERO, false));
|
||||
testNetChain = new BlockChain(testNet, new Wallet(testNet), new MemoryBlockStore(testNet));
|
||||
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, false));
|
||||
wallet = new Wallet(PARAMS) {
|
||||
@Override
|
||||
public void receiveFromBlock(Transaction tx, StoredBlock block, BlockChain.NewBlockType blockType,
|
||||
int relativityOffset) throws VerificationException {
|
||||
@@ -96,11 +95,6 @@ public class BlockChainTest {
|
||||
coinbaseTo = wallet.currentReceiveKey().toAddress(PARAMS);
|
||||
}
|
||||
|
||||
@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.
|
||||
|
@@ -59,10 +59,9 @@ public class ChainSplitTest {
|
||||
public void setUp() throws Exception {
|
||||
BriefLogFormatter.init();
|
||||
Utils.setMockClock(); // Use mock clock
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||
Context context = new Context(PARAMS);
|
||||
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, false));
|
||||
MemoryBlockStore blockStore = new MemoryBlockStore(PARAMS);
|
||||
wallet = new Wallet(context);
|
||||
wallet = new Wallet(PARAMS);
|
||||
ECKey key1 = wallet.freshReceiveKey();
|
||||
ECKey key2 = wallet.freshReceiveKey();
|
||||
chain = new BlockChain(PARAMS, wallet, blockStore);
|
||||
|
@@ -244,7 +244,6 @@ public class TransactionBroadcastTest extends TestWithPeerGroup {
|
||||
// Do the same thing with an offline transaction.
|
||||
peerGroup.removeWallet(wallet);
|
||||
Wallet.SendRequest req = Wallet.SendRequest.to(dest, valueOf(2, 0));
|
||||
req.ensureMinRequiredFee = false;
|
||||
Transaction t3 = checkNotNull(wallet.sendCoinsOffline(req));
|
||||
assertNull(outbound(p1)); // Nothing sent.
|
||||
// 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 {
|
||||
req.ensureMinRequiredFee = false;
|
||||
wallet.completeTx(req);
|
||||
fail();
|
||||
} 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).
|
||||
req = Wallet.SendRequest.to(destination, v2);
|
||||
req.aesKey = wrongAesKey;
|
||||
req.ensureMinRequiredFee = false;
|
||||
|
||||
try {
|
||||
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).
|
||||
req = Wallet.SendRequest.to(destination, v2);
|
||||
req.aesKey = aesKey;
|
||||
req.ensureMinRequiredFee = false;
|
||||
}
|
||||
|
||||
// Complete the transaction successfully.
|
||||
@@ -438,7 +435,6 @@ public class WalletTest extends TestWithWallet {
|
||||
assertEquals(v3, wallet.getBalance());
|
||||
Wallet.SendRequest req = Wallet.SendRequest.to(new ECKey().toAddress(PARAMS), valueOf(0, 48));
|
||||
req.aesKey = aesKey;
|
||||
req.ensureMinRequiredFee = false;
|
||||
req.shuffleOutputs = false;
|
||||
wallet.completeTx(req);
|
||||
Transaction t3 = req.tx;
|
||||
@@ -478,7 +474,6 @@ public class WalletTest extends TestWithWallet {
|
||||
t2.addOutput(v3, a2);
|
||||
t2.addOutput(v4, a2);
|
||||
SendRequest req = SendRequest.forTx(t2);
|
||||
req.ensureMinRequiredFee = false;
|
||||
wallet.completeTx(req);
|
||||
|
||||
// Do some basic sanity checks.
|
||||
@@ -1901,7 +1896,6 @@ public class WalletTest extends TestWithWallet {
|
||||
TransactionOutput o2 = new TransactionOutput(PARAMS, t2, v2, k2.toAddress(PARAMS));
|
||||
t2.addOutput(o2);
|
||||
SendRequest req = SendRequest.forTx(t2);
|
||||
req.ensureMinRequiredFee = false;
|
||||
wallet.completeTx(req);
|
||||
|
||||
// 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());
|
||||
tx.addOutput(messagePrice, script);
|
||||
SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||
request.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request);
|
||||
}
|
||||
|
||||
@@ -2235,6 +2230,7 @@ public class WalletTest extends TestWithWallet {
|
||||
tx.addOutput(messagePrice, script1);
|
||||
tx.addOutput(messagePrice, script2);
|
||||
SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||
request.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request);
|
||||
}
|
||||
|
||||
@@ -2245,6 +2241,7 @@ public class WalletTest extends TestWithWallet {
|
||||
Address notMyAddr = new ECKey().toAddress(PARAMS);
|
||||
tx.addOutput(Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI), notMyAddr);
|
||||
SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||
request.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request);
|
||||
}
|
||||
|
||||
@@ -2271,6 +2268,7 @@ public class WalletTest extends TestWithWallet {
|
||||
tx.addOutput(Coin.ZERO, ScriptBuilder.createOpReturnScript("hello world!".getBytes()));
|
||||
tx.addOutput(Coin.SATOSHI, notMyAddr);
|
||||
SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||
request.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request);
|
||||
}
|
||||
|
||||
@@ -2283,6 +2281,7 @@ public class WalletTest extends TestWithWallet {
|
||||
tx.addOutput(Coin.CENT, ScriptBuilder.createOpReturnScript("hello world!".getBytes()));
|
||||
tx.addOutput(Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI), notMyAddr);
|
||||
SendRequest request = Wallet.SendRequest.forTx(tx);
|
||||
request.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request);
|
||||
}
|
||||
|
||||
@@ -2323,14 +2322,15 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
// Not allowed to send dust.
|
||||
try {
|
||||
wallet.createSend(notMyAddr, SATOSHI);
|
||||
SendRequest request = SendRequest.to(notMyAddr, SATOSHI);
|
||||
request.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request);
|
||||
fail();
|
||||
} catch (Wallet.DustySendRequested e) {
|
||||
// Expected.
|
||||
}
|
||||
// Spend it all without fee enforcement
|
||||
SendRequest req = SendRequest.to(notMyAddr, SATOSHI.multiply(12));
|
||||
req.ensureMinRequiredFee = false;
|
||||
assertNotNull(wallet.sendCoinsOffline(req));
|
||||
assertEquals(ZERO, wallet.getBalance());
|
||||
|
||||
@@ -2340,7 +2340,10 @@ public class WalletTest extends TestWithWallet {
|
||||
wallet.receiveFromBlock(tx4, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
|
||||
// Simple test to make sure if we have an ouput < 0.01 we get a fee
|
||||
Transaction spend1 = wallet.createSend(notMyAddr, CENT.subtract(SATOSHI));
|
||||
SendRequest request1 = SendRequest.to(notMyAddr, CENT.subtract(SATOSHI));
|
||||
request1.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request1);
|
||||
Transaction spend1 = request1.tx;
|
||||
assertEquals(2, spend1.getOutputs().size());
|
||||
// We optimize for priority, so the output selected should be the largest one.
|
||||
// We should have paid the default minfee.
|
||||
@@ -2348,7 +2351,10 @@ public class WalletTest extends TestWithWallet {
|
||||
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||
|
||||
// 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());
|
||||
// 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()));
|
||||
@@ -2356,6 +2362,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// ...but not more fee than what we request
|
||||
SendRequest request3 = SendRequest.to(notMyAddr, CENT.subtract(SATOSHI));
|
||||
request3.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI);
|
||||
request3.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request3);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI), request3.tx.getFee());
|
||||
Transaction spend3 = request3.tx;
|
||||
@@ -2367,6 +2374,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// ...unless we need it
|
||||
SendRequest request4 = SendRequest.to(notMyAddr, CENT.subtract(SATOSHI));
|
||||
request4.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.subtract(SATOSHI);
|
||||
request4.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request4);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request4.tx.getFee());
|
||||
Transaction spend4 = request4.tx;
|
||||
@@ -2376,6 +2384,7 @@ public class WalletTest extends TestWithWallet {
|
||||
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||
|
||||
SendRequest request5 = SendRequest.to(notMyAddr, Coin.COIN.subtract(CENT.subtract(SATOSHI)));
|
||||
request5.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request5);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request5.tx.getFee());
|
||||
Transaction spend5 = request5.tx;
|
||||
@@ -2386,6 +2395,7 @@ public class WalletTest extends TestWithWallet {
|
||||
Coin.COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||
|
||||
SendRequest request6 = SendRequest.to(notMyAddr, Coin.COIN.subtract(CENT));
|
||||
request6.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request6);
|
||||
assertEquals(ZERO, request6.tx.getFee());
|
||||
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()));
|
||||
|
||||
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);
|
||||
wallet.completeTx(request7);
|
||||
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));
|
||||
|
||||
SendRequest request8 = SendRequest.to(notMyAddr, COIN.subtract(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE));
|
||||
request8.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request8);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request8.tx.getFee());
|
||||
Transaction spend8 = request8.tx;
|
||||
@@ -2416,6 +2428,7 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
SendRequest request9 = SendRequest.to(notMyAddr, COIN.subtract(
|
||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).subtract(SATOSHI)));
|
||||
request9.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request9);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).subtract(SATOSHI), request9.tx.getFee());
|
||||
Transaction spend9 = request9.tx;
|
||||
@@ -2427,6 +2440,7 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
SendRequest request10 = SendRequest.to(notMyAddr, COIN.subtract(
|
||||
Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT)));
|
||||
request10.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request10);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request10.tx.getFee());
|
||||
Transaction spend10 = request10.tx;
|
||||
@@ -2439,6 +2453,7 @@ public class WalletTest extends TestWithWallet {
|
||||
SendRequest request11 = SendRequest.to(notMyAddr, COIN.subtract(
|
||||
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.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request11);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(SATOSHI), request11.tx.getFee());
|
||||
Transaction spend11 = request11.tx;
|
||||
@@ -2491,6 +2506,7 @@ public class WalletTest extends TestWithWallet {
|
||||
request15.tx.addOutput(CENT, notMyAddr);
|
||||
assertTrue(request15.tx.unsafeBitcoinSerialize().length > 1000);
|
||||
request15.feePerKb = SATOSHI;
|
||||
request15.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request15);
|
||||
assertEquals(SATOSHI.multiply(2), request15.tx.getFee());
|
||||
Transaction spend15 = request15.tx;
|
||||
@@ -2504,6 +2520,7 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
SendRequest request16 = SendRequest.to(notMyAddr, CENT);
|
||||
request16.feePerKb = ZERO;
|
||||
request16.ensureMinRequiredFee = true;
|
||||
for (int i = 0; i < 29; i++)
|
||||
request16.tx.addOutput(CENT, notMyAddr);
|
||||
assertTrue(request16.tx.unsafeBitcoinSerialize().length > 1000);
|
||||
@@ -2524,6 +2541,7 @@ public class WalletTest extends TestWithWallet {
|
||||
request17.tx.addOutput(CENT, notMyAddr);
|
||||
request17.tx.addOutput(new TransactionOutput(PARAMS, request17.tx, CENT, new byte[15]));
|
||||
request17.feePerKb = SATOSHI;
|
||||
request17.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request17);
|
||||
assertEquals(SATOSHI, request17.tx.getFee());
|
||||
assertEquals(1, request17.tx.getInputs().size());
|
||||
@@ -2552,6 +2570,7 @@ public class WalletTest extends TestWithWallet {
|
||||
request18.tx.addOutput(CENT, notMyAddr);
|
||||
request18.tx.addOutput(new TransactionOutput(PARAMS, request18.tx, CENT, new byte[17]));
|
||||
request18.feePerKb = SATOSHI;
|
||||
request18.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request18);
|
||||
assertEquals(SATOSHI.multiply(2), request18.tx.getFee());
|
||||
assertEquals(1, request18.tx.getInputs().size());
|
||||
@@ -2576,6 +2595,7 @@ public class WalletTest extends TestWithWallet {
|
||||
assertEquals(wallet.getBalance(), CENT.add(COIN));
|
||||
SendRequest request19 = SendRequest.to(notMyAddr, CENT);
|
||||
request19.feePerKb = ZERO;
|
||||
request19.ensureMinRequiredFee = true;
|
||||
for (int i = 0; i < 99; i++)
|
||||
request19.tx.addOutput(CENT, notMyAddr);
|
||||
// If we send now, we shouldn't need a fee and should only have to spend our COIN
|
||||
@@ -2586,6 +2606,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// Now reset request19 and give it a fee per kb
|
||||
request19.tx.clearInputs();
|
||||
request19 = SendRequest.forTx(request19.tx);
|
||||
request19.ensureMinRequiredFee = true;
|
||||
request19.feePerKb = SATOSHI;
|
||||
request19.shuffleOutputs = false;
|
||||
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
|
||||
SendRequest request20 = SendRequest.to(notMyAddr, CENT);
|
||||
request20.feePerKb = ZERO;
|
||||
request20.ensureMinRequiredFee = true;
|
||||
for (int i = 0; i < 99; i++)
|
||||
request20.tx.addOutput(CENT, notMyAddr);
|
||||
// If we send now, we shouldn't have a fee and should only have to spend our COIN
|
||||
@@ -2626,6 +2648,7 @@ public class WalletTest extends TestWithWallet {
|
||||
// result of an output < CENT.
|
||||
SendRequest request21 = SendRequest.to(notMyAddr, CENT);
|
||||
request21.feePerKb = ZERO;
|
||||
request21.ensureMinRequiredFee = true;
|
||||
for (int i = 0; i < 99; i++)
|
||||
request21.tx.addOutput(CENT, 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
|
||||
SendRequest request25 = SendRequest.to(notMyAddr, CENT);
|
||||
request25.feePerKb = ZERO;
|
||||
request25.ensureMinRequiredFee = true;
|
||||
for (int i = 0; i < 70; i++)
|
||||
request25.tx.addOutput(CENT, notMyAddr);
|
||||
// If we send now, we shouldn't need a fee and should only have to spend our COIN
|
||||
@@ -2653,7 +2677,6 @@ public class WalletTest extends TestWithWallet {
|
||||
request25.tx.clearInputs();
|
||||
request25 = SendRequest.forTx(request25.tx);
|
||||
request25.feePerKb = CENT.divide(3);
|
||||
request25.ensureMinRequiredFee = false;
|
||||
request25.shuffleOutputs = false;
|
||||
wallet.completeTx(request25);
|
||||
assertEquals(CENT.subtract(SATOSHI), request25.tx.getFee());
|
||||
@@ -2684,6 +2707,7 @@ public class WalletTest extends TestWithWallet {
|
||||
notMyAddr);
|
||||
assertTrue(request26.tx.unsafeBitcoinSerialize().length > 1000);
|
||||
request26.feePerKb = SATOSHI;
|
||||
request26.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request26);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.add(Transaction.MIN_NONDUST_OUTPUT).subtract(SATOSHI),
|
||||
request26.tx.getFee());
|
||||
@@ -2701,7 +2725,6 @@ 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 = ZERO;
|
||||
// Make sure TestWithWallet isnt doing anything crazy.
|
||||
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)
|
||||
SendRequest request1 = SendRequest.to(notMyAddr, balance.subtract(SATOSHI));
|
||||
request1.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request1);
|
||||
assertEquals(SATOSHI, request1.tx.getFee());
|
||||
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)
|
||||
SendRequest request2 = SendRequest.to(notMyAddr, balance.subtract(SATOSHI));
|
||||
request2.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request2);
|
||||
assertEquals(SATOSHI, request2.tx.getFee());
|
||||
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)
|
||||
// but that also could have been category 2 if it wanted
|
||||
SendRequest request3 = SendRequest.to(notMyAddr, CENT.add(tenThousand).subtract(SATOSHI));
|
||||
request3.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request3);
|
||||
assertEquals(SATOSHI, request3.tx.getFee());
|
||||
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));
|
||||
request4.feePerKb = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE.divide(request3.tx.unsafeBitcoinSerialize().length);
|
||||
request4.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request4);
|
||||
assertEquals(SATOSHI, request4.tx.getFee());
|
||||
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
|
||||
SendRequest request5 = SendRequest.to(notMyAddr, CENT.add(tenThousand).subtract(SATOSHI));
|
||||
request5.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request5);
|
||||
assertEquals(SATOSHI, request5.tx.getFee());
|
||||
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!)
|
||||
SendRequest request6 = SendRequest.to(notMyAddr, CENT.add(tenThousand).subtract(SATOSHI));
|
||||
request6.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request6);
|
||||
assertEquals(ZERO, request6.tx.getFee());
|
||||
assertEquals(2, request6.tx.getOutputs().size()); // We should have a change output
|
||||
|
||||
SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -2801,6 +2828,7 @@ public class WalletTest extends TestWithWallet {
|
||||
|
||||
// The selector will choose 2 with MIN_TX_FEE fee
|
||||
SendRequest request1 = SendRequest.to(notMyAddr, CENT.add(SATOSHI));
|
||||
request1.ensureMinRequiredFee = true;
|
||||
wallet.completeTx(request1);
|
||||
assertEquals(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE, request1.tx.getFee());
|
||||
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);
|
||||
SendRequest emptyReq = SendRequest.emptyWallet(myAddress);
|
||||
emptyReq.feePerKb = fee;
|
||||
emptyReq.ensureMinRequiredFee = true;
|
||||
emptyReq.emptyWallet = true;
|
||||
emptyReq.coinSelector = AllowUnconfirmedCoinSelector.get();
|
||||
wallet.completeTx(emptyReq);
|
||||
@@ -2883,6 +2912,7 @@ public class WalletTest extends TestWithWallet {
|
||||
request1.tx.addOutput(CENT, notMyAddr);
|
||||
request1.tx.addOutput(new TransactionOutput(PARAMS, request1.tx, CENT, new byte[16]));
|
||||
request1.feePerKb = SATOSHI;
|
||||
request1.ensureMinRequiredFee = true;
|
||||
// We get a category 2 using COIN+CENT
|
||||
// It spends COIN + 1(fee) and because its output is thus < CENT, we have to pay MIN_TX_FEE
|
||||
// When it tries category 1, its too large and requires COIN + 2 (fee)
|
||||
@@ -2901,6 +2931,7 @@ public class WalletTest extends TestWithWallet {
|
||||
request2.tx.addOutput(CENT, notMyAddr);
|
||||
request2.tx.addOutput(new TransactionOutput(PARAMS, request2.tx, CENT, new byte[16]));
|
||||
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
|
||||
wallet.completeTx(request2);
|
||||
assertEquals(SATOSHI.multiply(2), request2.tx.getFee());
|
||||
@@ -3022,45 +3053,37 @@ public class WalletTest extends TestWithWallet {
|
||||
Transaction tx = createFakeTx(PARAMS, CENT, myAddress);
|
||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
SendRequest request = SendRequest.emptyWallet(outputKey);
|
||||
request.ensureMinRequiredFee = false;
|
||||
wallet.completeTx(request);
|
||||
assertEquals(Wallet.SendRequest.DEFAULT_FEE_PER_KB, request.tx.getFee());
|
||||
assertEquals(ZERO, request.tx.getFee());
|
||||
wallet.commitTx(request.tx);
|
||||
assertEquals(ZERO, wallet.getBalance());
|
||||
assertEquals(CENT, request.tx.getOutput(0).getValue());
|
||||
|
||||
// Add 1 confirmed cent and 1 unconfirmed cent. Verify only one cent is emptied because of the coin selection
|
||||
// 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);
|
||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
tx = createFakeTx(PARAMS, CENT, myAddress);
|
||||
wallet.receivePending(tx, null);
|
||||
request = SendRequest.emptyWallet(outputKey);
|
||||
request.ensureMinRequiredFee = false;
|
||||
wallet.completeTx(request);
|
||||
assertEquals(Wallet.SendRequest.DEFAULT_FEE_PER_KB, request.tx.getFee());
|
||||
assertEquals(ZERO, request.tx.getFee());
|
||||
wallet.commitTx(request.tx);
|
||||
assertEquals(ZERO, wallet.getBalance());
|
||||
assertEquals(CENT, request.tx.getOutput(0).getValue());
|
||||
|
||||
// Add an unsendable value
|
||||
StoredBlock block2 = new StoredBlock(block.getHeader().createNextBlock(outputKey), BigInteger.ONE, 3);
|
||||
Coin outputValue = Transaction.MIN_NONDUST_OUTPUT.add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE).subtract(SATOSHI);
|
||||
block = new StoredBlock(block.getHeader().createNextBlock(outputKey), BigInteger.ONE, 3);
|
||||
Coin outputValue = Transaction.MIN_NONDUST_OUTPUT.subtract(SATOSHI);
|
||||
tx = createFakeTx(PARAMS, outputValue, myAddress);
|
||||
wallet.receiveFromBlock(tx, block2, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
wallet.receiveFromBlock(tx, block, AbstractBlockChain.NewBlockType.BEST_CHAIN, 0);
|
||||
try {
|
||||
request = SendRequest.emptyWallet(outputKey);
|
||||
assertEquals(ZERO, request.tx.getFee());
|
||||
wallet.completeTx(request);
|
||||
fail();
|
||||
} 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
|
||||
|
@@ -102,11 +102,11 @@ public class ChannelConnectionTest extends TestWithWallet {
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
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);
|
||||
wallet.addExtension(new StoredPaymentChannelClientStates(wallet, failBroadcaster));
|
||||
Context context = new Context(PARAMS, 3); // Shorter event horizon for unit tests.
|
||||
serverWallet = new Wallet(context);
|
||||
serverWallet = new Wallet(PARAMS);
|
||||
serverWallet.addExtension(new StoredPaymentChannelServerStates(serverWallet, failBroadcaster));
|
||||
serverWallet.freshReceiveKey();
|
||||
// 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);
|
||||
}
|
||||
|
||||
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.
|
||||
final SettableFuture<ListenableFuture<PaymentChannelV1ServerState>> serverCloseFuture = 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
|
||||
serverState.close().get();
|
||||
assertEquals(PaymentChannelServerState.State.CLOSED, serverState.getState());
|
||||
if (!serverState.getBestValueToMe().equals(amount) || !serverState.getFeePaid().equals(Coin.ZERO))
|
||||
fail();
|
||||
assertEquals(amount, serverState.getBestValueToMe());
|
||||
assertEquals(ZERO, serverState.getFeePaid());
|
||||
assertTrue(channels.mapChannels.isEmpty());
|
||||
|
||||
// Send the settle TX to the client wallet.
|
||||
|
@@ -88,6 +88,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
public void setUp() throws Exception {
|
||||
Utils.setMockClock(); // Use mock clock
|
||||
super.setUp();
|
||||
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, true));
|
||||
wallet.addExtension(new StoredPaymentChannelClientStates(wallet, new TransactionBroadcaster() {
|
||||
@Override
|
||||
public TransactionBroadcast broadcastTransaction(Transaction tx) {
|
||||
@@ -710,7 +711,7 @@ public class PaymentChannelStateTest extends TestWithWallet {
|
||||
} catch (ValueOutOfRangeException e) {}
|
||||
|
||||
clientState = makeClientState(wallet, myKey, ECKey.fromPublicOnly(serverKey.getPubKey()),
|
||||
Transaction.MIN_NONDUST_OUTPUT.subtract(Coin.SATOSHI).add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE),
|
||||
Transaction.MIN_NONDUST_OUTPUT.subtract(Coin.SATOSHI).add(Transaction.REFERENCE_DEFAULT_MIN_TX_FEE),
|
||||
EXPIRE_TIME);
|
||||
assertEquals(PaymentChannelClientState.State.NEW, clientState.getState());
|
||||
try {
|
||||
|
@@ -82,9 +82,7 @@ public class TestWithNetworkConnections {
|
||||
|
||||
public void setUp(BlockStore blockStore) throws Exception {
|
||||
BriefLogFormatter.init();
|
||||
|
||||
context = new Context(PARAMS);
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, false));
|
||||
this.blockStore = blockStore;
|
||||
// Allow subclasses to override the wallet object with their own.
|
||||
if (wallet == null) {
|
||||
@@ -131,7 +129,6 @@ public class TestWithNetworkConnections {
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
stopPeerServers();
|
||||
}
|
||||
|
||||
|
@@ -47,8 +47,7 @@ public class TestWithWallet {
|
||||
|
||||
public void setUp() throws Exception {
|
||||
BriefLogFormatter.init();
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Coin.ZERO;
|
||||
Context ctx = new Context(PARAMS);
|
||||
Context.propagate(new Context(PARAMS, 100, Coin.ZERO, false));
|
||||
wallet = new Wallet(PARAMS);
|
||||
myKey = wallet.currentReceiveKey();
|
||||
myAddress = myKey.toAddress(PARAMS);
|
||||
@@ -57,7 +56,6 @@ public class TestWithWallet {
|
||||
}
|
||||
|
||||
public void tearDown() throws Exception {
|
||||
Wallet.SendRequest.DEFAULT_FEE_PER_KB = Transaction.REFERENCE_DEFAULT_MIN_TX_FEE;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
|
@@ -198,7 +198,7 @@ public class ExamplePaymentChannelClient {
|
||||
|
||||
private void waitForSufficientBalance(Coin amount) {
|
||||
// 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.
|
||||
ListenableFuture<Coin> balanceFuture = appKit.wallet().getBalanceFuture(amountPlusFee, Wallet.BalanceType.ESTIMATED);
|
||||
if (!balanceFuture.isDone()) {
|
||||
|
Reference in New Issue
Block a user