mirror of
https://github.com/bitcoin/bitcoin.git
synced 2025-12-11 13:13:49 +01:00
Merge #9602: Remove coin age priority and free transactions - implementation
b421e6dUpdate example bitcoin.conf (Alex Morcos)7d4e950Allow setting minrelaytxfee to 0 (Alex Morcos)359e8a0[cleanup] Remove coin age priority completely. (Alex Morcos)f9b9371[rpc] Remove priorityDelta from prioritisetransaction (Alex Morcos)49be7e1[rpc] Remove priority information from mempool RPC calls (Alex Morcos)0315888[test] Remove priority from tests (Alex Morcos)f838005No longer allow "free" transactions (Alex Morcos)ad727f4[rpc] sendrawtransaction no longer bypasses minRelayTxFee (Alex Morcos)fe282ac[cleanup] Remove estimatePriority and estimateSmartPriority (Alex Morcos)400b151[debug] Change -printpriority option (Alex Morcos)272b25a[mining] Remove -blockprioritysize. (Alex Morcos)12839cd[rpc] Remove estimatepriority and estimatesmartpriority. (Alex Morcos)ddf58c7wallet: Remove sendfree (MarcoFalke) Tree-SHA512: a9a4499405923ce794ef18f9e334dbbd59dfc73a3dc2df6f85cc9c62af6f353ec2eed9c2d5e58e904f918d0d7ab738f403dd4939d9bc2276136864fe63710782
This commit is contained in:
@@ -80,7 +80,6 @@ class AbandonConflictTest(BitcoinTestFramework):
|
||||
|
||||
# Restart the node with a higher min relay fee so the parent tx is no longer in mempool
|
||||
# TODO: redo with eviction
|
||||
# Note had to make sure tx did not have AllowFree priority
|
||||
stop_node(self.nodes[0],0)
|
||||
self.nodes[0]=start_node(0, self.options.tmpdir, ["-debug","-logtimemicros","-minrelaytxfee=0.0001"])
|
||||
|
||||
|
||||
@@ -24,8 +24,8 @@ class BIP68Test(BitcoinTestFramework):
|
||||
|
||||
def setup_network(self):
|
||||
self.nodes = []
|
||||
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug", "-blockprioritysize=0"]))
|
||||
self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-blockprioritysize=0", "-acceptnonstdtxn=0"]))
|
||||
self.nodes.append(start_node(0, self.options.tmpdir, ["-debug"]))
|
||||
self.nodes.append(start_node(1, self.options.tmpdir, ["-debug", "-acceptnonstdtxn=0"]))
|
||||
self.is_network_split = False
|
||||
self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]
|
||||
connect_nodes(self.nodes[0], 1)
|
||||
@@ -254,7 +254,7 @@ class BIP68Test(BitcoinTestFramework):
|
||||
|
||||
# Now mine some blocks, but make sure tx2 doesn't get mined.
|
||||
# Use prioritisetransaction to lower the effective feerate to 0
|
||||
self.nodes[0].prioritisetransaction(tx2.hash, -1e15, int(-self.relayfee*COIN))
|
||||
self.nodes[0].prioritisetransaction(tx2.hash, int(-self.relayfee*COIN))
|
||||
cur_time = int(time.time())
|
||||
for i in range(10):
|
||||
self.nodes[0].setmocktime(cur_time + 600)
|
||||
@@ -267,7 +267,7 @@ class BIP68Test(BitcoinTestFramework):
|
||||
test_nonzero_locks(tx2, self.nodes[0], self.relayfee, use_height_lock=False)
|
||||
|
||||
# Mine tx2, and then try again
|
||||
self.nodes[0].prioritisetransaction(tx2.hash, 1e15, int(self.relayfee*COIN))
|
||||
self.nodes[0].prioritisetransaction(tx2.hash, int(self.relayfee*COIN))
|
||||
|
||||
# Advance the time on the node so that we can test timelocks
|
||||
self.nodes[0].setmocktime(cur_time+600)
|
||||
|
||||
@@ -103,7 +103,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
|
||||
|
||||
# Check that descendant modified fees includes fee deltas from
|
||||
# prioritisetransaction
|
||||
self.nodes[0].prioritisetransaction(chain[-1], 0, 1000)
|
||||
self.nodes[0].prioritisetransaction(chain[-1], 1000)
|
||||
mempool = self.nodes[0].getrawmempool(True)
|
||||
|
||||
descendant_fees = 0
|
||||
@@ -124,7 +124,7 @@ class MempoolPackagesTest(BitcoinTestFramework):
|
||||
assert_equal(len(self.nodes[0].getrawmempool()), 0)
|
||||
# Prioritise a transaction that has been mined, then add it back to the
|
||||
# mempool by using invalidateblock.
|
||||
self.nodes[0].prioritisetransaction(chain[-1], 0, 2000)
|
||||
self.nodes[0].prioritisetransaction(chain[-1], 2000)
|
||||
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
|
||||
# Keep node1's tip synced with node0
|
||||
self.nodes[1].invalidateblock(self.nodes[1].getbestblockhash())
|
||||
|
||||
@@ -74,7 +74,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
|
||||
self.block_submit(self.nodes[0], test1txs, False, True)
|
||||
|
||||
print ("Test 2: Non-NULLDUMMY base multisig transaction should not be accepted to mempool before activation")
|
||||
test2tx = self.create_transaction(self.nodes[0], txid2, self.ms_address, 48)
|
||||
test2tx = self.create_transaction(self.nodes[0], txid2, self.ms_address, 47)
|
||||
trueDummy(test2tx)
|
||||
txid4 = self.tx_submit(self.nodes[0], test2tx, NULLDUMMY_ERROR)
|
||||
|
||||
@@ -82,7 +82,7 @@ class NULLDUMMYTest(BitcoinTestFramework):
|
||||
self.block_submit(self.nodes[0], [test2tx], False, True)
|
||||
|
||||
print ("Test 4: Non-NULLDUMMY base multisig transaction is invalid after activation")
|
||||
test4tx = self.create_transaction(self.nodes[0], txid4, self.address, 47)
|
||||
test4tx = self.create_transaction(self.nodes[0], txid4, self.address, 46)
|
||||
test6txs=[CTransaction(test4tx)]
|
||||
trueDummy(test4tx)
|
||||
self.tx_submit(self.nodes[0], test4tx, NULLDUMMY_ERROR)
|
||||
|
||||
@@ -50,10 +50,8 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
|
||||
assert(sizes[i] > MAX_BLOCK_BASE_SIZE) # Fail => raise utxo_count
|
||||
|
||||
# add a fee delta to something in the cheapest bucket and make sure it gets mined
|
||||
# also check that a different entry in the cheapest bucket is NOT mined (lower
|
||||
# the priority to ensure its not mined due to priority)
|
||||
self.nodes[0].prioritisetransaction(txids[0][0], 0, int(3*base_fee*COIN))
|
||||
self.nodes[0].prioritisetransaction(txids[0][1], -1e15, 0)
|
||||
# also check that a different entry in the cheapest bucket is NOT mined
|
||||
self.nodes[0].prioritisetransaction(txids[0][0], int(3*base_fee*COIN))
|
||||
|
||||
self.nodes[0].generate(1)
|
||||
|
||||
@@ -72,7 +70,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
|
||||
|
||||
# Add a prioritisation before a tx is in the mempool (de-prioritising a
|
||||
# high-fee transaction so that it's now low fee).
|
||||
self.nodes[0].prioritisetransaction(high_fee_tx, -1e15, -int(2*base_fee*COIN))
|
||||
self.nodes[0].prioritisetransaction(high_fee_tx, -int(2*base_fee*COIN))
|
||||
|
||||
# Add everything back to mempool
|
||||
self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash())
|
||||
@@ -96,7 +94,7 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
|
||||
if (x != high_fee_tx):
|
||||
assert(x not in mempool)
|
||||
|
||||
# Create a free, low priority transaction. Should be rejected.
|
||||
# Create a free transaction. Should be rejected.
|
||||
utxo_list = self.nodes[0].listunspent()
|
||||
assert(len(utxo_list) > 0)
|
||||
utxo = utxo_list[0]
|
||||
@@ -104,37 +102,27 @@ class PrioritiseTransactionTest(BitcoinTestFramework):
|
||||
inputs = []
|
||||
outputs = {}
|
||||
inputs.append({"txid" : utxo["txid"], "vout" : utxo["vout"]})
|
||||
outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee
|
||||
outputs[self.nodes[0].getnewaddress()] = utxo["amount"]
|
||||
raw_tx = self.nodes[0].createrawtransaction(inputs, outputs)
|
||||
tx_hex = self.nodes[0].signrawtransaction(raw_tx)["hex"]
|
||||
txid = self.nodes[0].sendrawtransaction(tx_hex)
|
||||
|
||||
# A tx that spends an in-mempool tx has 0 priority, so we can use it to
|
||||
# test the effect of using prioritise transaction for mempool acceptance
|
||||
inputs = []
|
||||
inputs.append({"txid": txid, "vout": 0})
|
||||
outputs = {}
|
||||
outputs[self.nodes[0].getnewaddress()] = utxo["amount"] - self.relayfee
|
||||
raw_tx2 = self.nodes[0].createrawtransaction(inputs, outputs)
|
||||
tx2_hex = self.nodes[0].signrawtransaction(raw_tx2)["hex"]
|
||||
tx2_id = self.nodes[0].decoderawtransaction(tx2_hex)["txid"]
|
||||
tx_id = self.nodes[0].decoderawtransaction(tx_hex)["txid"]
|
||||
|
||||
try:
|
||||
self.nodes[0].sendrawtransaction(tx2_hex)
|
||||
self.nodes[0].sendrawtransaction(tx_hex)
|
||||
except JSONRPCException as exp:
|
||||
assert_equal(exp.error['code'], -26) # insufficient fee
|
||||
assert(tx2_id not in self.nodes[0].getrawmempool())
|
||||
assert(tx_id not in self.nodes[0].getrawmempool())
|
||||
else:
|
||||
assert(False)
|
||||
|
||||
# This is a less than 1000-byte transaction, so just set the fee
|
||||
# to be the minimum for a 1000 byte transaction and check that it is
|
||||
# accepted.
|
||||
self.nodes[0].prioritisetransaction(tx2_id, 0, int(self.relayfee*COIN))
|
||||
self.nodes[0].prioritisetransaction(tx_id, int(self.relayfee*COIN))
|
||||
|
||||
print("Assert that prioritised free transaction is accepted to mempool")
|
||||
assert_equal(self.nodes[0].sendrawtransaction(tx2_hex), tx2_id)
|
||||
assert(tx2_id in self.nodes[0].getrawmempool())
|
||||
assert_equal(self.nodes[0].sendrawtransaction(tx_hex), tx_id)
|
||||
assert(tx_id in self.nodes[0].getrawmempool())
|
||||
|
||||
if __name__ == '__main__':
|
||||
PrioritiseTransactionTest().main()
|
||||
|
||||
@@ -543,7 +543,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
|
||||
assert(False)
|
||||
|
||||
# Use prioritisetransaction to set tx1a's fee to 0.
|
||||
self.nodes[0].prioritisetransaction(tx1a_txid, 0, int(-0.1*COIN))
|
||||
self.nodes[0].prioritisetransaction(tx1a_txid, int(-0.1*COIN))
|
||||
|
||||
# Now tx1b should be able to replace tx1a
|
||||
tx1b_txid = self.nodes[0].sendrawtransaction(tx1b_hex, True)
|
||||
@@ -575,7 +575,7 @@ class ReplaceByFeeTest(BitcoinTestFramework):
|
||||
assert(False)
|
||||
|
||||
# Now prioritise tx2b to have a higher modified fee
|
||||
self.nodes[0].prioritisetransaction(tx2b.hash, 0, int(0.1*COIN))
|
||||
self.nodes[0].prioritisetransaction(tx2b.hash, int(0.1*COIN))
|
||||
|
||||
# tx2b should now be accepted
|
||||
tx2b_txid = self.nodes[0].sendrawtransaction(tx2b_hex, True)
|
||||
|
||||
@@ -69,10 +69,11 @@ def small_txpuzzle_randfee(from_node, conflist, unconflist, amount, min_fee, fee
|
||||
|
||||
def split_inputs(from_node, txins, txouts, initial_split = False):
|
||||
"""
|
||||
We need to generate a lot of very small inputs so we can generate a ton of transactions
|
||||
and they will have low priority.
|
||||
We need to generate a lot of inputs so we can generate a ton of transactions.
|
||||
This function takes an input from txins, and creates and sends a transaction
|
||||
which splits the value into 2 outputs which are appended to txouts.
|
||||
Previously this was designed to be small inputs so they wouldn't have
|
||||
a high coin age when the notion of priority still existed.
|
||||
"""
|
||||
prevtxout = txins.pop()
|
||||
inputs = []
|
||||
@@ -150,7 +151,7 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||
def setup_network(self):
|
||||
"""
|
||||
We'll setup the network to have 3 nodes that all mine with different parameters.
|
||||
But first we need to use one node to create a lot of small low priority outputs
|
||||
But first we need to use one node to create a lot of outputs
|
||||
which we will use to generate our transactions.
|
||||
"""
|
||||
self.nodes = []
|
||||
@@ -159,7 +160,7 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||
"-whitelist=127.0.0.1"]))
|
||||
|
||||
print("This test is time consuming, please be patient")
|
||||
print("Splitting inputs to small size so we can generate low priority tx's")
|
||||
print("Splitting inputs so we can generate tx's")
|
||||
self.txouts = []
|
||||
self.txouts2 = []
|
||||
# Split a coinbase into two transaction puzzle outputs
|
||||
@@ -188,18 +189,17 @@ class EstimateFeeTest(BitcoinTestFramework):
|
||||
|
||||
# Now we can connect the other nodes, didn't want to connect them earlier
|
||||
# so the estimates would not be affected by the splitting transactions
|
||||
# Node1 mines small blocks but that are bigger than the expected transaction rate,
|
||||
# and allows free transactions.
|
||||
# Node1 mines small blocks but that are bigger than the expected transaction rate.
|
||||
# NOTE: the CreateNewBlock code starts counting block size at 1,000 bytes,
|
||||
# (17k is room enough for 110 or so transactions)
|
||||
self.nodes.append(start_node(1, self.options.tmpdir,
|
||||
["-blockprioritysize=1500", "-blockmaxsize=17000",
|
||||
["-blockmaxsize=17000",
|
||||
"-maxorphantx=1000", "-debug=estimatefee"]))
|
||||
connect_nodes(self.nodes[1], 0)
|
||||
|
||||
# Node2 is a stingy miner, that
|
||||
# produces too small blocks (room for only 55 or so transactions)
|
||||
node2args = ["-blockprioritysize=0", "-blockmaxsize=8000", "-maxorphantx=1000"]
|
||||
node2args = ["-blockmaxsize=8000", "-maxorphantx=1000"]
|
||||
|
||||
self.nodes.append(start_node(2, self.options.tmpdir, node2args))
|
||||
connect_nodes(self.nodes[0], 2)
|
||||
|
||||
@@ -442,47 +442,6 @@ def make_change(from_node, amount_in, amount_out, fee):
|
||||
outputs[from_node.getnewaddress()] = change
|
||||
return outputs
|
||||
|
||||
def send_zeropri_transaction(from_node, to_node, amount, fee):
|
||||
"""
|
||||
Create&broadcast a zero-priority transaction.
|
||||
Returns (txid, hex-encoded-txdata)
|
||||
Ensures transaction is zero-priority by first creating a send-to-self,
|
||||
then using its output
|
||||
"""
|
||||
|
||||
# Create a send-to-self with confirmed inputs:
|
||||
self_address = from_node.getnewaddress()
|
||||
(total_in, inputs) = gather_inputs(from_node, amount+fee*2)
|
||||
outputs = make_change(from_node, total_in, amount+fee, fee)
|
||||
outputs[self_address] = float(amount+fee)
|
||||
|
||||
self_rawtx = from_node.createrawtransaction(inputs, outputs)
|
||||
self_signresult = from_node.signrawtransaction(self_rawtx)
|
||||
self_txid = from_node.sendrawtransaction(self_signresult["hex"], True)
|
||||
|
||||
vout = find_output(from_node, self_txid, amount+fee)
|
||||
# Now immediately spend the output to create a 1-input, 1-output
|
||||
# zero-priority transaction:
|
||||
inputs = [ { "txid" : self_txid, "vout" : vout } ]
|
||||
outputs = { to_node.getnewaddress() : float(amount) }
|
||||
|
||||
rawtx = from_node.createrawtransaction(inputs, outputs)
|
||||
signresult = from_node.signrawtransaction(rawtx)
|
||||
txid = from_node.sendrawtransaction(signresult["hex"], True)
|
||||
|
||||
return (txid, signresult["hex"])
|
||||
|
||||
def random_zeropri_transaction(nodes, amount, min_fee, fee_increment, fee_variants):
|
||||
"""
|
||||
Create a random zero-priority transaction.
|
||||
Returns (txid, hex-encoded-transaction-data, fee)
|
||||
"""
|
||||
from_node = random.choice(nodes)
|
||||
to_node = random.choice(nodes)
|
||||
fee = min_fee + fee_increment*random.randint(0,fee_variants)
|
||||
(txid, txhex) = send_zeropri_transaction(from_node, to_node, amount, fee)
|
||||
return (txid, txhex, fee)
|
||||
|
||||
def random_transaction(nodes, amount, min_fee, fee_increment, fee_variants):
|
||||
"""
|
||||
Create a random transaction.
|
||||
|
||||
Reference in New Issue
Block a user