Skip to content

Commit

Permalink
Merge bitcoin#9602: Remove coin age priority and free transactions - …
Browse files Browse the repository at this point in the history
…implementation (#2768)

b421e6d Update example bitcoin.conf (Alex Morcos)
7d4e950 Allow 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)
f838005 No 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)
ddf58c7 wallet: Remove sendfree (MarcoFalke)

Tree-SHA512: a9a4499405923ce794ef18f9e334dbbd59dfc73a3dc2df6f85cc9c62af6f353ec2eed9c2d5e58e904f918d0d7ab738f403dd4939d9bc2276136864fe63710782
Signed-off-by: Pasta <Pasta@dash.org>

Fix backport and fix dash specific priority code
  • Loading branch information
PastaPastaPasta authored and UdjinM6 committed Mar 14, 2019
1 parent 6350adf commit 6f90cf7
Show file tree
Hide file tree
Showing 38 changed files with 128 additions and 675 deletions.
9 changes: 2 additions & 7 deletions contrib/debian/examples/dash.conf
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@
# because the rpcpassword is transmitted over the network unencrypted.

# server=1 tells Dash-Qt to accept JSON-RPC commands.
# it is also read by dashd to determine if RPC should be enabled
# it is also read by dashd to determine if RPC should be enabled
#rpcallowip=10.1.1.34/255.255.255.0
#rpcallowip=1.2.3.4/24
#rpcallowip=2001:db8:85a3:0:0:8a2e:370:7334/96
Expand All @@ -116,12 +116,7 @@
# running on another host using this option:
#rpcconnect=127.0.0.1

# Transaction Fee Changes in 0.12.0

# Send transactions as zero-fee transactions if possible (default: 0)
#sendfreetransactions=0

# Create transactions that have enough fees (or priority) so they are likely to begin confirmation within n blocks (default: 1).
# Create transactions that have enough fees so they are likely to begin confirmation within n blocks (default: 6).
# This setting is over-ridden by the -paytxfee option.
#txconfirmtarget=n

Expand Down
2 changes: 1 addition & 1 deletion contrib/devtools/check-doc.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
REGEX_ARG = re.compile(r'(?:map(?:Multi)?Args(?:\.count\(|\[)|Get(?:Bool)?Arg\()\"(\-[^\"]+?)\"')
REGEX_DOC = re.compile(r'HelpMessageOpt\(\"(\-[^\"=]+?)(?:=|\")')
# list unsupported, deprecated and duplicate args as they need no documentation
SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-blockminsize'])
SET_DOC_OPTIONAL = set(['-rpcssl', '-benchmark', '-h', '-help', '-socks', '-tor', '-debugnet', '-whitelistalwaysrelay', '-blockminsize', '-sendfreetransactions'])

def main():
used = check_output(CMD_GREP_ARGS, shell=True, universal_newlines=True)
Expand Down
1 change: 0 additions & 1 deletion qa/rpc-tests/abandonconflict.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ def run_test(self):

# 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, ["-minrelaytxfee=0.0001"])

Expand Down
8 changes: 4 additions & 4 deletions qa/rpc-tests/bip68-sequence.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@ def __init__(self):

def setup_network(self):
self.nodes = []
self.nodes.append(start_node(0, self.options.tmpdir, ["-blockprioritysize=0"]))
self.nodes.append(start_node(1, self.options.tmpdir, ["-blockprioritysize=0", "-acceptnonstdtxn=0"]))
self.nodes.append(start_node(0, self.options.tmpdir, []))
self.nodes.append(start_node(1, self.options.tmpdir, ["-acceptnonstdtxn=0"]))
self.is_network_split = False
self.relayfee = self.nodes[0].getnetworkinfo()["relayfee"]
connect_nodes(self.nodes[0], 1)
Expand Down Expand Up @@ -254,7 +254,7 @@ def test_nonzero_locks(orig_tx, node, relayfee, use_height_lock):

# 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 = get_mocktime()
for i in range(10):
self.nodes[0].setmocktime(cur_time + 600)
Expand All @@ -267,7 +267,7 @@ def test_nonzero_locks(orig_tx, node, relayfee, use_height_lock):
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)
Expand Down
8 changes: 4 additions & 4 deletions qa/rpc-tests/mempool_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,19 +103,19 @@ def run_test(self):

# Check that ancestor modified fees includes fee deltas from
# prioritisetransaction
self.nodes[0].prioritisetransaction(chain[0], 0, 1000)
self.nodes[0].prioritisetransaction(chain[0], 1000)
mempool = self.nodes[0].getrawmempool(True)
ancestor_fees = 0
for x in chain:
ancestor_fees += mempool[x]['fee']
assert_equal(mempool[x]['ancestorfees'], ancestor_fees * COIN + 1000)

# Undo the prioritisetransaction for later tests
self.nodes[0].prioritisetransaction(chain[0], 0, -1000)
self.nodes[0].prioritisetransaction(chain[0], -1000)

# 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
Expand All @@ -136,7 +136,7 @@ def run_test(self):
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())
Expand Down
36 changes: 12 additions & 24 deletions qa/rpc-tests/prioritise_transaction.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,8 @@ def run_test(self):
assert(sizes[i] > MAX_BLOCK_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)

Expand All @@ -74,7 +72,7 @@ def run_test(self):

# 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())
Expand All @@ -98,52 +96,42 @@ def run_test(self):
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]

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))

self.log.info("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())

# Test that calling prioritisetransaction is sufficient to trigger
# getblocktemplate to (eventually) return a new block.
mock_time = get_mocktime()
self.nodes[0].setmocktime(mock_time)
template = self.nodes[0].getblocktemplate()
self.nodes[0].prioritisetransaction(tx2_id, 0, -int(self.relayfee*COIN))
self.nodes[0].prioritisetransaction(tx2_id, -int(self.relayfee*COIN))
self.nodes[0].setmocktime(mock_time+10)
new_template = self.nodes[0].getblocktemplate()

Expand Down
16 changes: 8 additions & 8 deletions qa/rpc-tests/smartfees.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,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()
tx = CTransaction()
Expand Down Expand Up @@ -150,7 +151,7 @@ def __init__(self):
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 = []
Expand All @@ -159,7 +160,7 @@ def setup_network(self):
"-whitelist=127.0.0.1"]))

self.log.info("This test is time consuming, please be patient")
self.log.info("Splitting inputs to small size so we can generate low priority tx's")
self.log.info("Splitting inputs so we can generate tx's")
self.txouts = []
self.txouts2 = []
# Split a coinbase into two transaction puzzle outputs
Expand Down Expand Up @@ -188,18 +189,17 @@ def setup_network(self):

# 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"]))
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)
Expand Down
41 changes: 0 additions & 41 deletions qa/rpc-tests/test_framework/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -501,47 +501,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.
Expand Down
5 changes: 2 additions & 3 deletions src/bench/mempool_eviction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,13 @@
static void AddTx(const CTransaction& tx, const CAmount& nFee, CTxMemPool& pool)
{
int64_t nTime = 0;
double dPriority = 10.0;
unsigned int nHeight = 1;
bool spendsCoinbase = false;
unsigned int sigOpCost = 4;
LockPoints lp;
pool.addUnchecked(tx.GetHash(), CTxMemPoolEntry(
MakeTransactionRef(tx), nFee, nTime, dPriority, nHeight,
tx.GetValueOut(), spendsCoinbase, sigOpCost, lp));
MakeTransactionRef(tx), nFee, nTime, nHeight,
spendsCoinbase, sigOpCost, lp));
}

// Right now this is only testing eviction performance in an extremely small
Expand Down
18 changes: 0 additions & 18 deletions src/coins.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -243,24 +243,6 @@ bool CCoinsViewCache::HaveInputs(const CTransaction& tx) const
return true;
}

double CCoinsViewCache::GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const
{
inChainInputValue = 0;
if (tx.IsCoinBase())
return 0.0;
double dResult = 0.0;
BOOST_FOREACH(const CTxIn& txin, tx.vin)
{
const Coin& coin = AccessCoin(txin.prevout);
if (coin.IsSpent()) continue;
if (coin.nHeight <= nHeight) {
dResult += (double)coin.out.nValue * (nHeight-coin.nHeight);
inChainInputValue += coin.out.nValue;
}
}
return tx.ComputePriority(dResult);
}

static const size_t MAX_OUTPUTS_PER_BLOCK = MaxBlockSize(true) / ::GetSerializeSize(CTxOut(), SER_NETWORK, PROTOCOL_VERSION); // TODO: merge with similar definition in undo.h.

const Coin& AccessByTxid(const CCoinsViewCache& view, const uint256& txid)
Expand Down
7 changes: 0 additions & 7 deletions src/coins.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,13 +280,6 @@ class CCoinsViewCache : public CCoinsViewBacked
//! Check whether all prevouts of the transaction are present in the UTXO set represented by this view
bool HaveInputs(const CTransaction& tx) const;

/**
* Return priority of tx at height nHeight. Also calculate the sum of the values of the inputs
* that are already in the chain. These are the inputs that will age and increase priority as
* new blocks are added to the chain.
*/
double GetPriority(const CTransaction &tx, int nHeight, CAmount &inChainInputValue) const;

private:
CCoinsMap::iterator FetchCoin(const COutPoint &outpoint) const;

Expand Down
Loading

0 comments on commit 6f90cf7

Please sign in to comment.