diff --git a/contrib/debian/examples/dash.conf b/contrib/debian/examples/dash.conf index 2d4f7a66fe..2ea1730184 100644 --- a/contrib/debian/examples/dash.conf +++ b/contrib/debian/examples/dash.conf @@ -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 @@ -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 diff --git a/contrib/devtools/check-doc.py b/contrib/devtools/check-doc.py index 464e2a8a46..4bd65ad947 100755 --- a/contrib/devtools/check-doc.py +++ b/contrib/devtools/check-doc.py @@ -21,7 +21,7 @@ CMD_GREP_DOCS = r"egrep -r -I 'HelpMessageOpt\(\"\-[^\"=]+?(=|\")' {}".format(CM 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) diff --git a/qa/rpc-tests/abandonconflict.py b/qa/rpc-tests/abandonconflict.py index 7c581ea85d..887dbebd4f 100755 --- a/qa/rpc-tests/abandonconflict.py +++ b/qa/rpc-tests/abandonconflict.py @@ -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, ["-minrelaytxfee=0.0001"]) diff --git a/qa/rpc-tests/bip68-sequence.py b/qa/rpc-tests/bip68-sequence.py index fccec29127..c6d11ac9a2 100755 --- a/qa/rpc-tests/bip68-sequence.py +++ b/qa/rpc-tests/bip68-sequence.py @@ -24,8 +24,8 @@ class BIP68Test(BitcoinTestFramework): 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) @@ -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 = get_mocktime() 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) diff --git a/qa/rpc-tests/mempool_packages.py b/qa/rpc-tests/mempool_packages.py index 96aad919b2..d475aabdf8 100755 --- a/qa/rpc-tests/mempool_packages.py +++ b/qa/rpc-tests/mempool_packages.py @@ -103,7 +103,7 @@ class MempoolPackagesTest(BitcoinTestFramework): # 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: @@ -111,11 +111,11 @@ class MempoolPackagesTest(BitcoinTestFramework): 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 @@ -136,7 +136,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()) diff --git a/qa/rpc-tests/prioritise_transaction.py b/qa/rpc-tests/prioritise_transaction.py index 5d34ca325e..9d7dcdfed9 100755 --- a/qa/rpc-tests/prioritise_transaction.py +++ b/qa/rpc-tests/prioritise_transaction.py @@ -52,10 +52,8 @@ class PrioritiseTransactionTest(BitcoinTestFramework): 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) @@ -74,7 +72,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()) @@ -98,7 +96,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] @@ -106,44 +104,34 @@ 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)) 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() diff --git a/qa/rpc-tests/smartfees.py b/qa/rpc-tests/smartfees.py index d753b86011..dae8f24f76 100755 --- a/qa/rpc-tests/smartfees.py +++ b/qa/rpc-tests/smartfees.py @@ -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() @@ -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"])) 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 @@ -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"])) 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) diff --git a/qa/rpc-tests/test_framework/util.py b/qa/rpc-tests/test_framework/util.py index 079f924fad..33e425e07f 100644 --- a/qa/rpc-tests/test_framework/util.py +++ b/qa/rpc-tests/test_framework/util.py @@ -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. diff --git a/src/bench/mempool_eviction.cpp b/src/bench/mempool_eviction.cpp index 8d4c791a1d..1600dd9a62 100644 --- a/src/bench/mempool_eviction.cpp +++ b/src/bench/mempool_eviction.cpp @@ -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 diff --git a/src/coins.cpp b/src/coins.cpp index 30fbbe6fb1..1f8baa2b1b 100644 --- a/src/coins.cpp +++ b/src/coins.cpp @@ -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) diff --git a/src/coins.h b/src/coins.h index 421020cc97..e2606c7c21 100644 --- a/src/coins.h +++ b/src/coins.h @@ -280,13 +280,6 @@ public: //! 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; diff --git a/src/init.cpp b/src/init.cpp index 14cf007cc1..26e91bdcdc 100644 --- a/src/init.cpp +++ b/src/init.cpp @@ -568,8 +568,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-logtimemicros", strprintf("Add microsecond precision to debug timestamps (default: %u)", DEFAULT_LOGTIMEMICROS)); strUsage += HelpMessageOpt("-logthreadnames", strprintf("Add thread names to debug messages (default: %u)", DEFAULT_LOGTHREADNAMES)); strUsage += HelpMessageOpt("-mocktime=", "Replace actual time with seconds since epoch (default: 0)"); - strUsage += HelpMessageOpt("-limitfreerelay=", strprintf("Continuously rate-limit free transactions to *1000 bytes per minute (default: %u)", DEFAULT_LIMITFREERELAY)); - strUsage += HelpMessageOpt("-relaypriority", strprintf("Require high priority for relaying free or low-fee transactions (default: %u)", DEFAULT_RELAYPRIORITY)); strUsage += HelpMessageOpt("-maxsigcachesize=", strprintf("Limit size of signature cache to MiB (default: %u)", DEFAULT_MAX_SIG_CACHE_SIZE)); strUsage += HelpMessageOpt("-maxtipage=", strprintf("Maximum tip age in seconds to consider node in initial block download (default: %u)", DEFAULT_MAX_TIP_AGE)); } @@ -581,7 +579,7 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageOpt("-printtodebuglog", strprintf(_("Send trace/debug info to debug.log file (default: %u)"), 1)); if (showDebug) { - strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction priority and fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY)); + strUsage += HelpMessageOpt("-printpriority", strprintf("Log transaction fee per kB when mining blocks (default: %u)", DEFAULT_PRINTPRIORITY)); } strUsage += HelpMessageOpt("-shrinkdebugfile", _("Shrink debug.log file on client startup (default: 1 when no -debug)")); AppendParamsHelpMessages(strUsage, showDebug); @@ -621,7 +619,6 @@ std::string HelpMessage(HelpMessageMode mode) strUsage += HelpMessageGroup(_("Block creation options:")); strUsage += HelpMessageOpt("-blockmaxsize=", strprintf(_("Set maximum block size in bytes (default: %d)"), DEFAULT_BLOCK_MAX_SIZE)); - strUsage += HelpMessageOpt("-blockprioritysize=", strprintf(_("Set maximum size of high-priority/low-fee transactions in bytes (default: %d)"), DEFAULT_BLOCK_PRIORITY_SIZE)); strUsage += HelpMessageOpt("-blockmintxfee=", strprintf(_("Set lowest fee rate (in %s/kB) for transactions to be included in block creation. (default: %s)"), CURRENCY_UNIT, FormatMoney(DEFAULT_BLOCK_MIN_TX_FEE))); if (showDebug) strUsage += HelpMessageOpt("-blockversion=", "Override block version to test forking scenarios"); @@ -1231,17 +1228,18 @@ bool AppInitParameterInteraction() if (nConnectTimeout <= 0) nConnectTimeout = DEFAULT_CONNECT_TIMEOUT; - // Fee-per-kilobyte amount considered the same as "free" + // Fee-per-kilobyte amount required for mempool acceptance and relay // If you are mining, be careful setting this: // if you set it to zero then // a transaction spammer can cheaply fill blocks using - // 1-satoshi-fee transactions. It should be set above the real + // 0-fee transactions. It should be set above the real // cost to you of processing a transaction. if (IsArgSet("-minrelaytxfee")) { CAmount n = 0; - if (!ParseMoney(GetArg("-minrelaytxfee", ""), n) || 0 == n) + if (!ParseMoney(GetArg("-minrelaytxfee", ""), n)) { return InitError(AmountErrMsg("minrelaytxfee", GetArg("-minrelaytxfee", ""))); + } // High fee check is done afterward in CWallet::ParameterInteraction() ::minRelayTxFee = CFeeRate(n); } else if (incrementalRelayFee > ::minRelayTxFee) { diff --git a/src/miner.cpp b/src/miner.cpp index c4c8490693..015424e7f6 100644 --- a/src/miner.cpp +++ b/src/miner.cpp @@ -50,8 +50,8 @@ // // Unconfirmed transactions in the memory pool often depend on other // transactions in the memory pool. When we select transactions from the -// pool, we select by highest priority or fee rate, so we might consider -// transactions that depend on transactions that aren't yet in the block. +// pool, we select by highest fee rate of a transaction combined with all +// its ancestors. uint64_t nLastBlockTx = 0; uint64_t nLastBlockSize = 0; @@ -125,9 +125,6 @@ void BlockAssembler::resetBlock() // These counters do not include coinbase tx nBlockTx = 0; nFees = 0; - - lastFewTxs = 0; - blockFinished = false; } std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& scriptPubKeyIn) @@ -180,8 +177,6 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc } } - addPriorityTxs(); - int nPackagesSelected = 0; int nDescendantsUpdated = 0; addPackageTxs(nPackagesSelected, nDescendantsUpdated); @@ -252,17 +247,6 @@ std::unique_ptr BlockAssembler::CreateNewBlock(const CScript& sc return std::move(pblocktemplate); } -bool BlockAssembler::isStillDependent(CTxMemPool::txiter iter) -{ - BOOST_FOREACH(CTxMemPool::txiter parent, mempool.GetMemPoolParents(iter)) - { - if (!inBlock.count(parent)) { - return true; - } - } - return false; -} - void BlockAssembler::onlyUnconfirmed(CTxMemPool::setEntries& testSet) { for (CTxMemPool::setEntries::iterator iit = testSet.begin(); iit != testSet.end(); ) { @@ -300,50 +284,6 @@ bool BlockAssembler::TestPackageTransactions(const CTxMemPool::setEntries& packa return true; } -bool BlockAssembler::TestForBlock(CTxMemPool::txiter iter) -{ - if (nBlockSize + iter->GetTxSize() >= nBlockMaxSize) { - // If the block is so close to full that no more txs will fit - // or if we've tried more than 50 times to fill remaining space - // then flag that the block is finished - if (nBlockSize > nBlockMaxSize - 100 || lastFewTxs > 50) { - blockFinished = true; - return false; - } - // Once we're within 1000 bytes of a full block, only look at 50 more txs - // to try to fill the remaining space. - if (nBlockSize > nBlockMaxSize - 1000) { - lastFewTxs++; - } - return false; - } - - unsigned int nMaxBlockSigOps = MaxBlockSigOps(fDIP0001ActiveAtTip); - if (nBlockSigOps + iter->GetSigOpCount() >= nMaxBlockSigOps) { - // If the block has room for no more sig ops then - // flag that the block is finished - if (nBlockSigOps > nMaxBlockSigOps - 2) { - blockFinished = true; - return false; - } - // Otherwise attempt to find another tx with fewer sigops - // to put in the block. - return false; - } - - // Must check that lock times are still valid - // This can be removed once MTP is always enforced - // as long as reorgs keep the mempool consistent. - if (!IsFinalTx(iter->GetTx(), nHeight, nLockTimeCutoff)) - return false; - - if (!llmq::chainLocksHandler->IsTxSafeForMining(iter->GetTx().GetHash())) { - return false; - } - - return true; -} - void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) { pblock->vtx.emplace_back(iter->GetSharedTx()); @@ -357,11 +297,7 @@ void BlockAssembler::AddToBlock(CTxMemPool::txiter iter) bool fPrintPriority = GetBoolArg("-printpriority", DEFAULT_PRINTPRIORITY); if (fPrintPriority) { - double dPriority = iter->GetPriority(nHeight); - CAmount dummy; - mempool.ApplyDeltas(iter->GetTx().GetHash(), dPriority, dummy); - LogPrintf("priority %.1f fee %s txid %s\n", - dPriority, + LogPrintf("fee %s txid %s\n", CFeeRate(iter->GetModifiedFee(), iter->GetTxSize()).ToString(), iter->GetTx().GetHash().ToString()); } @@ -561,80 +497,6 @@ void BlockAssembler::addPackageTxs(int &nPackagesSelected, int &nDescendantsUpda } } -void BlockAssembler::addPriorityTxs() -{ - // How much of the block should be dedicated to high-priority transactions, - // included regardless of the fees they pay - unsigned int nBlockPrioritySize = GetArg("-blockprioritysize", DEFAULT_BLOCK_PRIORITY_SIZE); - nBlockPrioritySize = std::min(nBlockMaxSize, nBlockPrioritySize); - - if (nBlockPrioritySize == 0) { - return; - } - - // This vector will be sorted into a priority queue: - std::vector vecPriority; - TxCoinAgePriorityCompare pricomparer; - std::map waitPriMap; - typedef std::map::iterator waitPriIter; - double actualPriority = -1; - - vecPriority.reserve(mempool.mapTx.size()); - for (CTxMemPool::indexed_transaction_set::iterator mi = mempool.mapTx.begin(); - mi != mempool.mapTx.end(); ++mi) - { - double dPriority = mi->GetPriority(nHeight); - CAmount dummy; - mempool.ApplyDeltas(mi->GetTx().GetHash(), dPriority, dummy); - vecPriority.push_back(TxCoinAgePriority(dPriority, mi)); - } - std::make_heap(vecPriority.begin(), vecPriority.end(), pricomparer); - - CTxMemPool::txiter iter; - while (!vecPriority.empty() && !blockFinished) { // add a tx from priority queue to fill the blockprioritysize - iter = vecPriority.front().second; - actualPriority = vecPriority.front().first; - std::pop_heap(vecPriority.begin(), vecPriority.end(), pricomparer); - vecPriority.pop_back(); - - // If tx already in block, skip - if (inBlock.count(iter)) { - assert(false); // shouldn't happen for priority txs - continue; - } - - // If tx is dependent on other mempool txs which haven't yet been included - // then put it in the waitSet - if (isStillDependent(iter)) { - waitPriMap.insert(std::make_pair(iter, actualPriority)); - continue; - } - - // If this tx fits in the block add it, otherwise keep looping - if (TestForBlock(iter)) { - AddToBlock(iter); - - // If now that this txs is added we've surpassed our desired priority size - // or have dropped below the AllowFreeThreshold, then we're done adding priority txs - if (nBlockSize >= nBlockPrioritySize || !AllowFree(actualPriority)) { - break; - } - - // This tx was successfully added, so - // add transactions that depend on this one to the priority queue to try again - BOOST_FOREACH(CTxMemPool::txiter child, mempool.GetMemPoolChildren(iter)) - { - waitPriIter wpiter = waitPriMap.find(child); - if (wpiter != waitPriMap.end()) { - vecPriority.push_back(TxCoinAgePriority(wpiter->second,child)); - std::push_heap(vecPriority.begin(), vecPriority.end(), pricomparer); - waitPriMap.erase(wpiter); - } - } - } - } -} - void IncrementExtraNonce(CBlock* pblock, const CBlockIndex* pindexPrev, unsigned int& nExtraNonce) { // Update nExtraNonce diff --git a/src/miner.h b/src/miner.h index d49a89d8ed..995cce10c7 100644 --- a/src/miner.h +++ b/src/miner.h @@ -158,10 +158,6 @@ private: int64_t nLockTimeCutoff; const CChainParams& chainparams; - // Variables used for addPriorityTxs - int lastFewTxs; - bool blockFinished; - public: struct Options { Options(); @@ -183,19 +179,11 @@ private: void AddToBlock(CTxMemPool::txiter iter); // Methods for how to add transactions to a block. - /** Add transactions based on tx "priority" */ - void addPriorityTxs(); /** Add transactions based on feerate including unconfirmed ancestors * Increments nPackagesSelected / nDescendantsUpdated with corresponding * statistics from the package selection (for logging statistics). */ void addPackageTxs(int &nPackagesSelected, int &nDescendantsUpdated); - // helper function for addPriorityTxs - /** Test if tx will still "fit" in the block */ - bool TestForBlock(CTxMemPool::txiter iter); - /** Test if tx still has unconfirmed parents not yet in block */ - bool isStillDependent(CTxMemPool::txiter iter); - // helper functions for addPackageTxs() /** Remove confirmed (inBlock) entries from given set */ void onlyUnconfirmed(CTxMemPool::setEntries& testSet); diff --git a/src/net_processing.cpp b/src/net_processing.cpp index 20850a1606..6d6b3b8ff1 100644 --- a/src/net_processing.cpp +++ b/src/net_processing.cpp @@ -972,12 +972,12 @@ bool static AlreadyHave(const CInv& inv) EXCLUSIVE_LOCKS_REQUIRED(cs_main) case MSG_BLOCK: return mapBlockIndex.count(inv.hash); - /* + /* Dash Related Inventory Messages -- - We shouldn't update the sync times for each of the messages when we already have it. + We shouldn't update the sync times for each of the messages when we already have it. We're going to be asking many nodes upfront for the full inventory list, so we'll get duplicates of these. We want to only update the time on new hits, so that we can time out appropriately if needed. */ @@ -2142,7 +2142,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr } LogPrintf("DSTX -- Got Masternode transaction %s\n", hashTx.ToString()); - mempool.PrioritiseTransaction(hashTx, 1000, 0.1*COIN); + mempool.PrioritiseTransaction(hashTx, 0.1*COIN); mmetaman.DisallowMixing(dmn->proTxHash); } @@ -2226,7 +2226,7 @@ bool static ProcessMessage(CNode* pfrom, const std::string& strCommand, CDataStr LogPrint("mempool", " invalid orphan tx %s\n", orphanHash.ToString()); } // Has inputs but not accepted to mempool - // Probably non-standard or insufficient fee/priority + // Probably non-standard or insufficient fee LogPrint("mempool", " removed orphan tx %s\n", orphanHash.ToString()); vEraseQueue.push_back(orphanHash); if (!stateDummy.CorruptionPossible()) { diff --git a/src/policy/fees.cpp b/src/policy/fees.cpp index aab1d2230c..a3c13bb7e9 100644 --- a/src/policy/fees.cpp +++ b/src/policy/fees.cpp @@ -450,24 +450,6 @@ CFeeRate CBlockPolicyEstimator::estimateSmartFee(int confTarget, int *answerFoun return CFeeRate(median); } -double CBlockPolicyEstimator::estimatePriority(int confTarget) -{ - return -1; -} - -double CBlockPolicyEstimator::estimateSmartPriority(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool) -{ - if (answerFoundAtTarget) - *answerFoundAtTarget = confTarget; - - // If mempool is limiting txs, no priority txs are allowed - CAmount minPoolFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFeePerK(); - if (minPoolFee > 0) - return INF_PRIORITY; - - return -1; -} - void CBlockPolicyEstimator::Write(CAutoFile& fileout) { fileout << nBestSeenHeight; diff --git a/src/policy/fees.h b/src/policy/fees.h index 6a0e756281..06494cabc7 100644 --- a/src/policy/fees.h +++ b/src/policy/fees.h @@ -187,7 +187,6 @@ static const double SUFFICIENT_FEETXS = 1; static constexpr double MIN_BUCKET_FEERATE = 1000; static const double MAX_BUCKET_FEERATE = 1e7; static const double INF_FEERATE = MAX_MONEY; -static const double INF_PRIORITY = 1e9 * MAX_MONEY; // We have to lump transactions into buckets based on feerate, but we want to be able // to give accurate estimates over a large range of potential feerates @@ -228,20 +227,6 @@ public: */ CFeeRate estimateSmartFee(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool); - /** Return a priority estimate. - * DEPRECATED - * Returns -1 - */ - double estimatePriority(int confTarget); - - /** Estimate priority needed to get be included in a block within - * confTarget blocks. - * DEPRECATED - * Returns -1 unless mempool is currently limited then returns INF_PRIORITY - * answerFoundAtTarget is set to confTarget - */ - double estimateSmartPriority(int confTarget, int *answerFoundAtTarget, const CTxMemPool& pool); - /** Write estimation data to a file */ void Write(CAutoFile& fileout); diff --git a/src/policy/policy.h b/src/policy/policy.h index 92fa07d17e..bb515f1c68 100644 --- a/src/policy/policy.h +++ b/src/policy/policy.h @@ -16,8 +16,6 @@ class CCoinsViewCache; /** Default for -blockmaxsize, which controls the maximum size of block the mining code will create **/ static const unsigned int DEFAULT_BLOCK_MAX_SIZE = 2000000; -/** Default for -blockprioritysize, maximum space for zero/low-fee transactions **/ -static const unsigned int DEFAULT_BLOCK_PRIORITY_SIZE = 10000; // was 50000 in 0.12.0 and it is 0 in Bitcoin since 0.12 /** Default for -blockmintxfee, which sets the minimum feerate for a transaction in blocks created by mining code **/ static const unsigned int DEFAULT_BLOCK_MIN_TX_FEE = 1000; /** The maximum size for transactions we're willing to relay/mine */ diff --git a/src/primitives/transaction.cpp b/src/primitives/transaction.cpp index fd8e56ff5d..a6bec1411e 100644 --- a/src/primitives/transaction.cpp +++ b/src/primitives/transaction.cpp @@ -108,32 +108,6 @@ CAmount CTransaction::GetValueOut() const return nValueOut; } -double CTransaction::ComputePriority(double dPriorityInputs, unsigned int nTxSize) const -{ - nTxSize = CalculateModifiedSize(nTxSize); - if (nTxSize == 0) return 0.0; - - return dPriorityInputs / nTxSize; -} - -unsigned int CTransaction::CalculateModifiedSize(unsigned int nTxSize) const -{ - // In order to avoid disincentivizing cleaning up the UTXO set we don't count - // the constant overhead for each txin and up to 110 bytes of scriptSig (which - // is enough to cover a compressed pubkey p2sh redemption) for priority. - // Providing any more cleanup incentive than making additional inputs free would - // risk encouraging people to create junk outputs to redeem later. - if (nTxSize == 0) - nTxSize = ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); - for (std::vector::const_iterator it(vin.begin()); it != vin.end(); ++it) - { - unsigned int offset = 41U + std::min(110U, (unsigned int)it->scriptSig.size()); - if (nTxSize > offset) - nTxSize -= offset; - } - return nTxSize; -} - unsigned int CTransaction::GetTotalSize() const { return ::GetSerializeSize(*this, SER_NETWORK, PROTOCOL_VERSION); diff --git a/src/primitives/transaction.h b/src/primitives/transaction.h index ec99b589f2..76cdc3463a 100644 --- a/src/primitives/transaction.h +++ b/src/primitives/transaction.h @@ -283,12 +283,6 @@ public: // GetValueIn() is a method on CCoinsViewCache, because // inputs must be known to compute value in. - // Compute priority, given priority of inputs and (optionally) tx size - double ComputePriority(double dPriorityInputs, unsigned int nTxSize=0) const; - - // Compute modified tx size for priority calculation (optionally given tx size) - unsigned int CalculateModifiedSize(unsigned int nTxSize=0) const; - /** * Get the total transaction size in bytes, including witness data. * "Total Size" defined in BIP141 and BIP144. diff --git a/src/privatesend-server.cpp b/src/privatesend-server.cpp index f39cf6dee7..9b03e95bbd 100644 --- a/src/privatesend-server.cpp +++ b/src/privatesend-server.cpp @@ -348,7 +348,7 @@ void CPrivateSendServer::CommitFinalTransaction(CConnman& connman) // See if the transaction is valid TRY_LOCK(cs_main, lockMain); CValidationState validationState; - mempool.PrioritiseTransaction(hashTx, 1000, 0.1 * COIN); + mempool.PrioritiseTransaction(hashTx, 0.1 * COIN); if (!lockMain || !AcceptToMemoryPool(mempool, validationState, finalTransaction, false, NULL, false, maxTxFee, true)) { LogPrintf("CPrivateSendServer::CommitFinalTransaction -- AcceptToMemoryPool() error: Transaction not valid\n"); SetNull(); diff --git a/src/qt/coincontroldialog.cpp b/src/qt/coincontroldialog.cpp index 8d6b6b6f2f..c7d57572ff 100644 --- a/src/qt/coincontroldialog.cpp +++ b/src/qt/coincontroldialog.cpp @@ -54,7 +54,7 @@ CoinControlDialog::CoinControlDialog(const PlatformStyle *_platformStyle, QWidge platformStyle(_platformStyle) { ui->setupUi(this); - + /* Open CSS when configured */ this->setStyleSheet(GUIUtil::loadStyleSheet()); @@ -499,11 +499,8 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) CAmount nChange = 0; unsigned int nBytes = 0; unsigned int nBytesInputs = 0; - double dPriority = 0; - double dPriorityInputs = 0; unsigned int nQuantity = 0; int nQuantityUncompressed = 0; - bool fAllowFree = false; std::vector vCoinControl; std::vector vOutputs; @@ -527,9 +524,6 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // Amount nAmount += out.tx->tx->vout[out.i].nValue; - // Priority - dPriorityInputs += (double)out.tx->tx->vout[out.i].nValue * (out.nDepth+1); - // Bytes CTxDestination address; if(ExtractDestination(out.tx->tx->vout[out.i].scriptPubKey, address)) @@ -539,8 +533,6 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) if (keyid && model->getPubKey(*keyid, pubkey)) { nBytesInputs += (pubkey.IsCompressed() ? 148 : 180); - if (!pubkey.IsCompressed()) - nQuantityUncompressed++; } else nBytesInputs += 148; // in all error cases, simply assume 148 here @@ -571,16 +563,6 @@ void CoinControlDialog::updateLabels(WalletModel *model, QDialog* dialog) // InstantSend Fee if (coinControl->fUseInstantSend) nPayFee = std::max(nPayFee, CTxLockRequest(txDummy).GetMinFee(true)); - // Allow free? (require at least hard-coded threshold and default to that if no estimate) - double mempoolEstimatePriority = mempool.estimateSmartPriority(nTxConfirmTarget); - dPriority = dPriorityInputs / (nBytes - nBytesInputs + (nQuantityUncompressed * 29)); // 29 = 180 - 151 (uncompressed public keys are over the limit. max 151 bytes of the input are ignored for priority) - double dPriorityNeeded = std::max(mempoolEstimatePriority, AllowFreeThreshold()); - fAllowFree = (dPriority >= dPriorityNeeded); - - if (fSendFreeTransactions) - if (fAllowFree && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE) - nPayFee = 0; - if (nPayAmount > 0) { nChange = nAmount - nPayAmount; @@ -690,7 +672,7 @@ void CoinControlDialog::updateView() bool treeMode = ui->radioTreeMode->isChecked(); QString theme = GUIUtil::getThemeName(); - + ui->treeWidget->clear(); ui->treeWidget->setEnabled(false); // performance, otherwise updateLabels would be called for every checked checkbox ui->treeWidget->setAlternatingRowColors(!treeMode); diff --git a/src/rpc/blockchain.cpp b/src/rpc/blockchain.cpp index de5bd13ceb..c9ec3554c8 100644 --- a/src/rpc/blockchain.cpp +++ b/src/rpc/blockchain.cpp @@ -362,8 +362,6 @@ std::string EntryDescriptionString() " \"modifiedfee\" : n, (numeric) transaction fee with fee deltas used for mining priority\n" " \"time\" : n, (numeric) local time transaction entered pool in seconds since 1 Jan 1970 GMT\n" " \"height\" : n, (numeric) block height when transaction entered pool\n" - " \"startingpriority\" : n, (numeric) DEPRECATED. Priority when transaction entered pool\n" - " \"currentpriority\" : n, (numeric) DEPRECATED. Transaction priority now\n" " \"descendantcount\" : n, (numeric) number of in-mempool descendant transactions (including this one)\n" " \"descendantsize\" : n, (numeric) size of in-mempool descendants (including this one)\n" " \"descendantfees\" : n, (numeric) modified fees (see above) of in-mempool descendants (including this one)\n" @@ -386,8 +384,6 @@ void entryToJSON(UniValue &info, const CTxMemPoolEntry &e) info.push_back(Pair("modifiedfee", ValueFromAmount(e.GetModifiedFee()))); info.push_back(Pair("time", e.GetTime())); info.push_back(Pair("height", (int)e.GetHeight())); - info.push_back(Pair("startingpriority", e.GetPriority(e.GetHeight()))); - info.push_back(Pair("currentpriority", e.GetPriority(chainActive.Height()))); info.push_back(Pair("descendantcount", e.GetCountWithDescendants())); info.push_back(Pair("descendantsize", e.GetSizeWithDescendants())); info.push_back(Pair("descendantfees", e.GetModFeesWithDescendants())); diff --git a/src/rpc/client.cpp b/src/rpc/client.cpp index 9905345d0c..fdd6ac876b 100644 --- a/src/rpc/client.cpp +++ b/src/rpc/client.cpp @@ -130,11 +130,8 @@ static const CRPCConvertParam vRPCConvertParams[] = { "keypoolrefill", 0, "newsize" }, { "getrawmempool", 0, "verbose" }, { "estimatefee", 0, "nblocks" }, - { "estimatepriority", 0, "nblocks" }, { "estimatesmartfee", 0, "nblocks" }, - { "estimatesmartpriority", 0, "nblocks" }, - { "prioritisetransaction", 1, "priority_delta" }, - { "prioritisetransaction", 2, "fee_delta" }, + { "prioritisetransaction", 1, "fee_delta" }, { "setban", 2, "bantime" }, { "setban", 3, "absolute" }, { "setbip69enabled", 0, "enabled" }, diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp index 173f122daa..2f070f9275 100644 --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -264,31 +264,28 @@ UniValue getmininginfo(const JSONRPCRequest& request) // NOTE: Unlike wallet RPC (which use BTC values), mining RPCs follow GBT (BIP 22) in using satoshi amounts UniValue prioritisetransaction(const JSONRPCRequest& request) { - if (request.fHelp || request.params.size() != 3) + if (request.fHelp || request.params.size() != 2) throw std::runtime_error( - "prioritisetransaction \n" + "prioritisetransaction \n" "Accepts the transaction into mined blocks at a higher (or lower) priority\n" "\nArguments:\n" "1. \"txid\" (string, required) The transaction id.\n" - "2. priority_delta (numeric, required) The priority to add or subtract.\n" - " The transaction selection algorithm considers the tx as it would have a higher priority.\n" - " (priority of a transaction is calculated: coinage * value_in_duffs / txsize) \n" - "3. fee_delta (numeric, required) The fee value (in duffs) to add (or subtract, if negative).\n" + "2. fee_delta (numeric, required) The fee value (in duffs) to add (or subtract, if negative).\n" " The fee is not actually paid, only the algorithm for selecting transactions into a block\n" " considers the transaction as it would have paid a higher (or lower) fee.\n" "\nResult:\n" "true (boolean) Returns true\n" "\nExamples:\n" - + HelpExampleCli("prioritisetransaction", "\"txid\" 0.0 10000") - + HelpExampleRpc("prioritisetransaction", "\"txid\", 0.0, 10000") + + HelpExampleCli("prioritisetransaction", "\"txid\" 10000") + + HelpExampleRpc("prioritisetransaction", "\"txid\", 10000") ); LOCK(cs_main); uint256 hash = ParseHashStr(request.params[0].get_str(), "txid"); - CAmount nAmount = request.params[2].get_int64(); + CAmount nAmount = request.params[1].get_int64(); - mempool.PrioritiseTransaction(hash, request.params[1].get_real(), nAmount); + mempool.PrioritiseTransaction(hash, nAmount); return true; } @@ -861,33 +858,6 @@ UniValue estimatefee(const JSONRPCRequest& request) return ValueFromAmount(feeRate.GetFeePerK()); } -UniValue estimatepriority(const JSONRPCRequest& request) -{ - if (request.fHelp || request.params.size() != 1) - throw std::runtime_error( - "estimatepriority nblocks\n" - "\nDEPRECATED. Estimates the approximate priority a zero-fee transaction needs to begin\n" - "confirmation within nblocks blocks.\n" - "\nArguments:\n" - "1. nblocks (numeric, required)\n" - "\nResult:\n" - "n (numeric) estimated priority\n" - "\n" - "A negative value is returned if not enough transactions and blocks\n" - "have been observed to make an estimate.\n" - "\nExample:\n" - + HelpExampleCli("estimatepriority", "6") - ); - - RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)); - - int nBlocks = request.params[0].get_int(); - if (nBlocks < 1) - nBlocks = 1; - - return mempool.estimatePriority(nBlocks); -} - UniValue estimatesmartfee(const JSONRPCRequest& request) { if (request.fHelp || request.params.size() != 1) @@ -924,48 +894,12 @@ UniValue estimatesmartfee(const JSONRPCRequest& request) return result; } -UniValue estimatesmartpriority(const JSONRPCRequest& request) -{ - if (request.fHelp || request.params.size() != 1) - throw std::runtime_error( - "estimatesmartpriority nblocks\n" - "\nDEPRECATED. WARNING: This interface is unstable and may disappear or change!\n" - "\nEstimates the approximate priority a zero-fee transaction needs to begin\n" - "confirmation within nblocks blocks if possible and return the number of blocks\n" - "for which the estimate is valid.\n" - "\nArguments:\n" - "1. nblocks (numeric, required)\n" - "\nResult:\n" - "{\n" - " \"priority\" : x.x, (numeric) estimated priority\n" - " \"blocks\" : n (numeric) block number where estimate was found\n" - "}\n" - "\n" - "A negative value is returned if not enough transactions and blocks\n" - "have been observed to make an estimate for any number of blocks.\n" - "However if the mempool reject fee is set it will return 1e9 * MAX_MONEY.\n" - "\nExample:\n" - + HelpExampleCli("estimatesmartpriority", "6") - ); - - RPCTypeCheck(request.params, boost::assign::list_of(UniValue::VNUM)); - - int nBlocks = request.params[0].get_int(); - - UniValue result(UniValue::VOBJ); - int answerFound; - double priority = mempool.estimateSmartPriority(nBlocks, &answerFound); - result.push_back(Pair("priority", priority)); - result.push_back(Pair("blocks", answerFound)); - return result; -} - static const CRPCCommand commands[] = { // category name actor (function) okSafeMode // --------------------- ------------------------ ----------------------- ---------- { "mining", "getnetworkhashps", &getnetworkhashps, true, {"nblocks","height"} }, { "mining", "getmininginfo", &getmininginfo, true, {} }, - { "mining", "prioritisetransaction", &prioritisetransaction, true, {"txid","priority_delta","fee_delta"} }, + { "mining", "prioritisetransaction", &prioritisetransaction, true, {"txid","fee_delta"} }, { "mining", "getblocktemplate", &getblocktemplate, true, {"template_request"} }, { "mining", "submitblock", &submitblock, true, {"hexdata","parameters"} }, @@ -973,9 +907,7 @@ static const CRPCCommand commands[] = { "generating", "generatetoaddress", &generatetoaddress, true, {"nblocks","address","maxtries"} }, { "util", "estimatefee", &estimatefee, true, {"nblocks"} }, - { "util", "estimatepriority", &estimatepriority, true, {"nblocks"} }, { "util", "estimatesmartfee", &estimatesmartfee, true, {"nblocks"} }, - { "util", "estimatesmartpriority", &estimatesmartpriority, true, {"nblocks"} }, }; void RegisterMiningRPCCommands(CRPCTable &t) diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 10757196f4..fedfd2ad93 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -67,7 +67,7 @@ UniValue getinfo(const JSONRPCRequest& request) " \"keypoolsize\": xxxx, (numeric) how many new keys are pre-generated\n" " \"unlocked_until\": ttt, (numeric) the timestamp in seconds since epoch (midnight Jan 1 1970 GMT) that the wallet is unlocked for transfers, or 0 if the wallet is locked\n" " \"paytxfee\": x.xxxx, (numeric) the transaction fee set in " + CURRENCY_UNIT + "/kB\n" - " \"relayfee\": x.xxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n" + " \"relayfee\": x.xxxx, (numeric) minimum relay fee for transactions in " + CURRENCY_UNIT + "/kB\n" " \"errors\": \"...\" (string) any error messages\n" "}\n" "\nExamples:\n" diff --git a/src/rpc/net.cpp b/src/rpc/net.cpp index 725cb6ac9f..1828a8a965 100644 --- a/src/rpc/net.cpp +++ b/src/rpc/net.cpp @@ -416,7 +416,7 @@ UniValue getnetworkinfo(const JSONRPCRequest& request) " }\n" " ,...\n" " ],\n" - " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for non-free transactions in " + CURRENCY_UNIT + "/kB\n" + " \"relayfee\": x.xxxxxxxx, (numeric) minimum relay fee for transactions in " + CURRENCY_UNIT + "/kB\n" " \"incrementalfee\": x.xxxxxxxx, (numeric) minimum fee increment for mempool limiting or BIP 125 replacement in " + CURRENCY_UNIT + "/kB\n" " \"localaddresses\": [ (array) list of local addresses\n" " {\n" diff --git a/src/test/mempool_tests.cpp b/src/test/mempool_tests.cpp index 762cd7b464..4618f222bf 100644 --- a/src/test/mempool_tests.cpp +++ b/src/test/mempool_tests.cpp @@ -125,28 +125,28 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx1.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).Priority(10.0).FromTx(tx1)); + pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).FromTx(tx1)); /* highest fee */ CMutableTransaction tx2 = CMutableTransaction(); tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx2.vout[0].nValue = 2 * COIN; - pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).Priority(9.0).FromTx(tx2)); + pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).FromTx(tx2)); /* lowest fee */ CMutableTransaction tx3 = CMutableTransaction(); tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx3.vout[0].nValue = 5 * COIN; - pool.addUnchecked(tx3.GetHash(), entry.Fee(0LL).Priority(100.0).FromTx(tx3)); + pool.addUnchecked(tx3.GetHash(), entry.Fee(0LL).FromTx(tx3)); /* 2nd highest fee */ CMutableTransaction tx4 = CMutableTransaction(); tx4.vout.resize(1); tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx4.vout[0].nValue = 6 * COIN; - pool.addUnchecked(tx4.GetHash(), entry.Fee(15000LL).Priority(1.0).FromTx(tx4)); + pool.addUnchecked(tx4.GetHash(), entry.Fee(15000LL).FromTx(tx4)); /* equal fee rate to tx1, but newer */ CMutableTransaction tx5 = CMutableTransaction(); @@ -154,7 +154,6 @@ BOOST_AUTO_TEST_CASE(MempoolIndexingTest) tx5.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx5.vout[0].nValue = 11 * COIN; entry.nTime = 1; - entry.dPriority = 10.0; pool.addUnchecked(tx5.GetHash(), entry.Fee(10000LL).FromTx(tx5)); BOOST_CHECK_EQUAL(pool.size(), 5); @@ -327,14 +326,14 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx1.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).Priority(10.0).FromTx(tx1)); + pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).FromTx(tx1)); /* highest fee */ CMutableTransaction tx2 = CMutableTransaction(); tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx2.vout[0].nValue = 2 * COIN; - pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).Priority(9.0).FromTx(tx2)); + pool.addUnchecked(tx2.GetHash(), entry.Fee(20000LL).FromTx(tx2)); uint64_t tx2Size = ::GetSerializeSize(tx2, SER_NETWORK, PROTOCOL_VERSION); /* lowest fee */ @@ -342,14 +341,14 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx3.vout[0].nValue = 5 * COIN; - pool.addUnchecked(tx3.GetHash(), entry.Fee(0LL).Priority(100.0).FromTx(tx3)); + pool.addUnchecked(tx3.GetHash(), entry.Fee(0LL).FromTx(tx3)); /* 2nd highest fee */ CMutableTransaction tx4 = CMutableTransaction(); tx4.vout.resize(1); tx4.vout[0].scriptPubKey = CScript() << OP_11 << OP_EQUAL; tx4.vout[0].nValue = 6 * COIN; - pool.addUnchecked(tx4.GetHash(), entry.Fee(15000LL).Priority(1.0).FromTx(tx4)); + pool.addUnchecked(tx4.GetHash(), entry.Fee(15000LL).FromTx(tx4)); /* equal fee rate to tx1, but newer */ CMutableTransaction tx5 = CMutableTransaction(); @@ -407,7 +406,6 @@ BOOST_AUTO_TEST_CASE(MempoolAncestorIndexingTest) /* set the fee to just below tx2's feerate when including ancestor */ CAmount fee = (20000/tx2Size)*(tx7Size + tx6Size) - 1; - //CTxMemPoolEntry entry7(tx7, fee, 2, 10.0, 1, true); pool.addUnchecked(tx7.GetHash(), entry.Fee(fee).FromTx(tx7)); BOOST_CHECK_EQUAL(pool.size(), 7); sortedOrder.insert(sortedOrder.begin()+1, tx7.GetHash().ToString()); @@ -433,7 +431,6 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) { CTxMemPool pool; TestMemPoolEntryHelper entry; - entry.dPriority = 10.0; CMutableTransaction tx1 = CMutableTransaction(); tx1.vin.resize(1); @@ -441,7 +438,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) tx1.vout.resize(1); tx1.vout[0].scriptPubKey = CScript() << OP_1 << OP_EQUAL; tx1.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).FromTx(tx1, &pool)); + pool.addUnchecked(tx1.GetHash(), entry.Fee(10000LL).FromTx(tx1)); CMutableTransaction tx2 = CMutableTransaction(); tx2.vin.resize(1); @@ -449,7 +446,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) tx2.vout.resize(1); tx2.vout[0].scriptPubKey = CScript() << OP_2 << OP_EQUAL; tx2.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx2.GetHash(), entry.Fee(5000LL).FromTx(tx2, &pool)); + pool.addUnchecked(tx2.GetHash(), entry.Fee(5000LL).FromTx(tx2)); pool.TrimToSize(pool.DynamicMemoryUsage()); // should do nothing BOOST_CHECK(pool.exists(tx1.GetHash())); @@ -459,7 +456,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) BOOST_CHECK(pool.exists(tx1.GetHash())); BOOST_CHECK(!pool.exists(tx2.GetHash())); - pool.addUnchecked(tx2.GetHash(), entry.FromTx(tx2, &pool)); + pool.addUnchecked(tx2.GetHash(), entry.FromTx(tx2)); CMutableTransaction tx3 = CMutableTransaction(); tx3.vin.resize(1); tx3.vin[0].prevout = COutPoint(tx2.GetHash(), 0); @@ -467,7 +464,7 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) tx3.vout.resize(1); tx3.vout[0].scriptPubKey = CScript() << OP_3 << OP_EQUAL; tx3.vout[0].nValue = 10 * COIN; - pool.addUnchecked(tx3.GetHash(), entry.Fee(20000LL).FromTx(tx3, &pool)); + pool.addUnchecked(tx3.GetHash(), entry.Fee(20000LL).FromTx(tx3)); pool.TrimToSize(pool.DynamicMemoryUsage() * 3 / 4); // tx3 should pay for tx2 (CPFP) BOOST_CHECK(!pool.exists(tx1.GetHash())); @@ -530,10 +527,10 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) tx7.vout[1].scriptPubKey = CScript() << OP_7 << OP_EQUAL; tx7.vout[1].nValue = 10 * COIN; - pool.addUnchecked(tx4.GetHash(), entry.Fee(7000LL).FromTx(tx4, &pool)); - pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5, &pool)); - pool.addUnchecked(tx6.GetHash(), entry.Fee(1100LL).FromTx(tx6, &pool)); - pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7, &pool)); + pool.addUnchecked(tx4.GetHash(), entry.Fee(7000LL).FromTx(tx4)); + pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5)); + pool.addUnchecked(tx6.GetHash(), entry.Fee(1100LL).FromTx(tx6)); + pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7)); // we only require this remove, at max, 2 txn, because its not clear what we're really optimizing for aside from that pool.TrimToSize(pool.DynamicMemoryUsage() - 1); @@ -542,8 +539,8 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) BOOST_CHECK(!pool.exists(tx7.GetHash())); if (!pool.exists(tx5.GetHash())) - pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5, &pool)); - pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7, &pool)); + pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5)); + pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7)); pool.TrimToSize(pool.DynamicMemoryUsage() / 2); // should maximize mempool size by only removing 5/7 BOOST_CHECK(pool.exists(tx4.GetHash())); @@ -551,8 +548,8 @@ BOOST_AUTO_TEST_CASE(MempoolSizeLimitTest) BOOST_CHECK(pool.exists(tx6.GetHash())); BOOST_CHECK(!pool.exists(tx7.GetHash())); - pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5, &pool)); - pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7, &pool)); + pool.addUnchecked(tx5.GetHash(), entry.Fee(1000LL).FromTx(tx5)); + pool.addUnchecked(tx7.GetHash(), entry.Fee(9000LL).FromTx(tx7)); std::vector vtx; SetMockTime(42); diff --git a/src/test/miner_tests.cpp b/src/test/miner_tests.cpp index e9c7123b15..78b49cbc7d 100644 --- a/src/test/miner_tests.cpp +++ b/src/test/miner_tests.cpp @@ -90,7 +90,6 @@ bool TestSequenceLocks(const CTransaction &tx, int flags) // Test suite for ancestor feerate transaction selection. // Implemented as an additional function, rather than a separate test case, // to allow reusing the blockchain created in CreateNewBlock_validity. -// Note that this test assumes blockprioritysize is 0. void TestPackageSelection(const CChainParams& chainparams, CScript scriptPubKey, std::vector& txFirst) { // Disable free transactions, otherwise TX selection is non-deterministic @@ -207,7 +206,6 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) uint256 hash; TestMemPoolEntryHelper entry; entry.nFee = 11; - entry.dPriority = 111.0; entry.nHeight = 11; fCheckpointsEnabled = false; @@ -328,7 +326,7 @@ BOOST_AUTO_TEST_CASE(CreateNewBlock_validity) BOOST_CHECK_THROW(AssemblerForTest(chainparams).CreateNewBlock(scriptPubKey), std::runtime_error); mempool.clear(); - // child with higher priority than parent + // child with higher feerate than parent tx.vin[0].scriptSig = CScript() << OP_1; tx.vin[0].prevout.hash = txFirst[1]->GetHash(); tx.vout[0].nValue = BLOCKSUBSIDY-HIGHFEE; diff --git a/src/test/policyestimator_tests.cpp b/src/test/policyestimator_tests.cpp index db42907f94..4b5bccb942 100644 --- a/src/test/policyestimator_tests.cpp +++ b/src/test/policyestimator_tests.cpp @@ -55,7 +55,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 4; k++) { // add 4 fee txs tx.vin[0].prevout.n = 10000*blocknum+100*j+k; // make transaction unique uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Priority(0).Height(blocknum).FromTx(tx, &mpool)); + mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Height(blocknum).FromTx(tx)); txHashes[j].push_back(hash); } } @@ -131,7 +131,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 4; k++) { // add 4 fee txs tx.vin[0].prevout.n = 10000*blocknum+100*j+k; uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Priority(0).Height(blocknum).FromTx(tx, &mpool)); + mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Height(blocknum).FromTx(tx)); txHashes[j].push_back(hash); } } @@ -168,7 +168,7 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) for (int k = 0; k < 4; k++) { // add 4 fee txs tx.vin[0].prevout.n = 10000*blocknum+100*j+k; uint256 hash = tx.GetHash(); - mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Priority(0).Height(blocknum).FromTx(tx, &mpool)); + mpool.addUnchecked(hash, entry.Fee(feeV[j]).Time(GetTime()).Height(blocknum).FromTx(tx)); CTransactionRef ptx = mpool.get(hash); if (ptx) block.push_back(ptx); @@ -184,15 +184,13 @@ BOOST_AUTO_TEST_CASE(BlockPolicyEstimates) } // Test that if the mempool is limited, estimateSmartFee won't return a value below the mempool min fee - // and that estimateSmartPriority returns essentially an infinite value - mpool.addUnchecked(tx.GetHash(), entry.Fee(feeV[5]).Time(GetTime()).Priority(0).Height(blocknum).FromTx(tx, &mpool)); + mpool.addUnchecked(tx.GetHash(), entry.Fee(feeV[5]).Time(GetTime()).Height(blocknum).FromTx(tx)); // evict that transaction which should set a mempool min fee of minRelayTxFee + feeV[5] mpool.TrimToSize(1); BOOST_CHECK(mpool.GetMinFee(1).GetFeePerK() > feeV[5]); for (int i = 1; i < 10; i++) { BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= mpool.estimateFee(i).GetFeePerK()); BOOST_CHECK(mpool.estimateSmartFee(i).GetFeePerK() >= mpool.GetMinFee(1).GetFeePerK()); - BOOST_CHECK(mpool.estimateSmartPriority(i) == INF_PRIORITY); } } diff --git a/src/test/test_dash.cpp b/src/test/test_dash.cpp index eed85d7d46..e6679a7571 100644 --- a/src/test/test_dash.cpp +++ b/src/test/test_dash.cpp @@ -203,14 +203,14 @@ TestChainSetup::~TestChainSetup() } -CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction &tx, CTxMemPool *pool) { +CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CMutableTransaction &tx) { CTransaction txn(tx); - return FromTx(txn, pool); + return FromTx(txn); } -CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn, CTxMemPool *pool) { - return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, dPriority, nHeight, - txn.GetValueOut(), spendsCoinbase, sigOpCount, lp); +CTxMemPoolEntry TestMemPoolEntryHelper::FromTx(const CTransaction &txn) { + return CTxMemPoolEntry(MakeTransactionRef(txn), nFee, nTime, nHeight, + spendsCoinbase, sigOpCount, lp); } void Shutdown(void* parg) diff --git a/src/test/test_dash.h b/src/test/test_dash.h index 69213b0cfa..f9ca803f18 100644 --- a/src/test/test_dash.h +++ b/src/test/test_dash.h @@ -82,30 +82,27 @@ struct TestChainDIP3BeforeActivationSetup : public TestChainSetup }; class CTxMemPoolEntry; -class CTxMemPool; struct TestMemPoolEntryHelper { // Default values CAmount nFee; int64_t nTime; - double dPriority; unsigned int nHeight; bool spendsCoinbase; unsigned int sigOpCount; LockPoints lp; TestMemPoolEntryHelper() : - nFee(0), nTime(0), dPriority(0.0), nHeight(1), + nFee(0), nTime(0), nHeight(1), spendsCoinbase(false), sigOpCount(4) { } - CTxMemPoolEntry FromTx(const CMutableTransaction &tx, CTxMemPool *pool = NULL); - CTxMemPoolEntry FromTx(const CTransaction &tx, CTxMemPool *pool = NULL); + CTxMemPoolEntry FromTx(const CMutableTransaction &tx); + CTxMemPoolEntry FromTx(const CTransaction &tx); // Change the default value TestMemPoolEntryHelper &Fee(CAmount _fee) { nFee = _fee; return *this; } TestMemPoolEntryHelper &Time(int64_t _time) { nTime = _time; return *this; } - TestMemPoolEntryHelper &Priority(double _priority) { dPriority = _priority; return *this; } TestMemPoolEntryHelper &Height(unsigned int _height) { nHeight = _height; return *this; } TestMemPoolEntryHelper &SpendsCoinbase(bool _flag) { spendsCoinbase = _flag; return *this; } TestMemPoolEntryHelper &SigOps(unsigned int _sigops) { sigOpCount = _sigops; return *this; } diff --git a/src/txmempool.cpp b/src/txmempool.cpp index 9575ba99ca..a14ce6aab1 100644 --- a/src/txmempool.cpp +++ b/src/txmempool.cpp @@ -27,22 +27,17 @@ #include "llmq/quorums_instantsend.h" CTxMemPoolEntry::CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee, - int64_t _nTime, double _entryPriority, unsigned int _entryHeight, - CAmount _inChainInputValue, + int64_t _nTime, unsigned int _entryHeight, bool _spendsCoinbase, unsigned int _sigOps, LockPoints lp): - tx(_tx), nFee(_nFee), nTime(_nTime), entryPriority(_entryPriority), entryHeight(_entryHeight), - inChainInputValue(_inChainInputValue), + tx(_tx), nFee(_nFee), nTime(_nTime), entryHeight(_entryHeight), spendsCoinbase(_spendsCoinbase), sigOpCount(_sigOps), lockPoints(lp) { nTxSize = ::GetSerializeSize(*_tx, SER_NETWORK, PROTOCOL_VERSION); - nModSize = _tx->CalculateModifiedSize(nTxSize); nUsageSize = RecursiveDynamicUsage(*tx) + memusage::DynamicUsage(tx); nCountWithDescendants = 1; nSizeWithDescendants = nTxSize; nModFeesWithDescendants = nFee; - CAmount nValueIn = tx->GetValueOut()+nFee; - assert(inChainInputValue <= nValueIn); feeDelta = 0; @@ -57,16 +52,6 @@ CTxMemPoolEntry::CTxMemPoolEntry(const CTxMemPoolEntry& other) *this = other; } -double -CTxMemPoolEntry::GetPriority(unsigned int currentHeight) const -{ - double deltaPriority = ((double)(currentHeight-entryHeight)*inChainInputValue)/nModSize; - double dResult = entryPriority + deltaPriority; - if (dResult < 0) // This should only happen if it was called with a height below entry height - dResult = 0; - return dResult; -} - void CTxMemPoolEntry::UpdateFeeDelta(int64_t newFeeDelta) { nModFeesWithDescendants += newFeeDelta - feeDelta; @@ -400,11 +385,11 @@ bool CTxMemPool::addUnchecked(const uint256& hash, const CTxMemPoolEntry &entry, // Update transaction for any feeDelta created by PrioritiseTransaction // TODO: refactor so that the fee delta is calculated before inserting // into mapTx. - std::map >::const_iterator pos = mapDeltas.find(hash); + std::map::const_iterator pos = mapDeltas.find(hash); if (pos != mapDeltas.end()) { - const std::pair &deltas = pos->second; - if (deltas.second) { - mapTx.modify(newit, update_fee_delta(deltas.second)); + const CAmount &delta = pos->second; + if (delta) { + mapTx.modify(newit, update_fee_delta(delta)); } } @@ -1350,16 +1335,6 @@ CFeeRate CTxMemPool::estimateSmartFee(int nBlocks, int *answerFoundAtBlocks) con LOCK(cs); return minerPolicyEstimator->estimateSmartFee(nBlocks, answerFoundAtBlocks, *this); } -double CTxMemPool::estimatePriority(int nBlocks) const -{ - LOCK(cs); - return minerPolicyEstimator->estimatePriority(nBlocks); -} -double CTxMemPool::estimateSmartPriority(int nBlocks, int *answerFoundAtBlocks) const -{ - LOCK(cs); - return minerPolicyEstimator->estimateSmartPriority(nBlocks, answerFoundAtBlocks, *this); -} bool CTxMemPool::WriteFeeEstimates(CAutoFile& fileout) const @@ -1395,16 +1370,15 @@ CTxMemPool::ReadFeeEstimates(CAutoFile& filein) return true; } -void CTxMemPool::PrioritiseTransaction(const uint256& hash, double dPriorityDelta, const CAmount& nFeeDelta) +void CTxMemPool::PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta) { { LOCK(cs); - std::pair &deltas = mapDeltas[hash]; - deltas.first += dPriorityDelta; - deltas.second += nFeeDelta; + CAmount &delta = mapDeltas[hash]; + delta += nFeeDelta; txiter it = mapTx.find(hash); if (it != mapTx.end()) { - mapTx.modify(it, update_fee_delta(deltas.second)); + mapTx.modify(it, update_fee_delta(delta)); // Now update all ancestors' modified fees with descendants setEntries setAncestors; uint64_t nNoLimit = std::numeric_limits::max(); @@ -1423,18 +1397,17 @@ void CTxMemPool::PrioritiseTransaction(const uint256& hash, double dPriorityDelt ++nTransactionsUpdated; } } - LogPrintf("PrioritiseTransaction: %s priority += %f, fee += %d\n", hash.ToString(), dPriorityDelta, FormatMoney(nFeeDelta)); + LogPrintf("PrioritiseTransaction: %s feerate += %s\n", hash.ToString(), FormatMoney(nFeeDelta)); } -void CTxMemPool::ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) const +void CTxMemPool::ApplyDelta(const uint256 hash, CAmount &nFeeDelta) const { LOCK(cs); - std::map >::const_iterator pos = mapDeltas.find(hash); + std::map::const_iterator pos = mapDeltas.find(hash); if (pos == mapDeltas.end()) return; - const std::pair &deltas = pos->second; - dPriorityDelta += deltas.first; - nFeeDelta += deltas.second; + const CAmount &delta = pos->second; + nFeeDelta += delta; } void CTxMemPool::ClearPrioritisation(const uint256 hash) diff --git a/src/txmempool.h b/src/txmempool.h index 9893ccdcfb..bceffd1954 100644 --- a/src/txmempool.h +++ b/src/txmempool.h @@ -33,19 +33,6 @@ class CAutoFile; class CBlockIndex; -inline double AllowFreeThreshold() -{ - return COIN * 144 / 250; -} - -inline bool AllowFree(double dPriority) -{ - // Large (in bytes) low-priority (new, small-coin) transactions - // need a fee. - return dPriority > AllowFreeThreshold(); -} - - /** Fake height value used in Coin to signify they are only in the memory pool (since 0.8) */ static const uint32_t MEMPOOL_HEIGHT = 0x7FFFFFFF; @@ -89,12 +76,9 @@ private: CTransactionRef tx; CAmount nFee; //!< Cached to avoid expensive parent-transaction lookups size_t nTxSize; //!< ... and avoid recomputing tx size - size_t nModSize; //!< ... and modified size for priority size_t nUsageSize; //!< ... and total memory usage int64_t nTime; //!< Local time when entering the mempool - double entryPriority; //!< Priority when entering the mempool unsigned int entryHeight; //!< Chain height when entering the mempool - CAmount inChainInputValue; //!< Sum of all txin values that are already in blockchain bool spendsCoinbase; //!< keep track of transactions that spend a coinbase unsigned int sigOpCount; //!< Legacy sig ops plus P2SH sig op count int64_t feeDelta; //!< Used for determining the priority of the transaction for mining in a block @@ -117,19 +101,14 @@ private: public: CTxMemPoolEntry(const CTransactionRef& _tx, const CAmount& _nFee, - int64_t _nTime, double _entryPriority, unsigned int _entryHeight, - CAmount _inChainInputValue, bool spendsCoinbase, + int64_t _nTime, unsigned int _entryHeight, + bool spendsCoinbase, unsigned int nSigOps, LockPoints lp); CTxMemPoolEntry(const CTxMemPoolEntry& other); const CTransaction& GetTx() const { return *this->tx; } CTransactionRef GetSharedTx() const { return this->tx; } - /** - * Fast calculation of lower bound of current priority as update - * from entry priority. Only inputs that were originally in-chain will age. - */ - double GetPriority(unsigned int currentHeight) const; const CAmount& GetFee() const { return nFee; } size_t GetTxSize() const { return nTxSize; } int64_t GetTime() const { return nTime; } @@ -550,7 +529,7 @@ private: public: indirectmap mapNextTx; - std::map > mapDeltas; + std::map mapDeltas; /** Create a new CTxMemPool. */ @@ -607,8 +586,8 @@ public: bool HasNoInputsOf(const CTransaction& tx) const; /** Affect CreateNewBlock prioritisation of transactions */ - void PrioritiseTransaction(const uint256& hash, double dPriorityDelta, const CAmount& nFeeDelta); - void ApplyDeltas(const uint256 hash, double &dPriorityDelta, CAmount &nFeeDelta) const; + void PrioritiseTransaction(const uint256& hash, const CAmount& nFeeDelta); + void ApplyDelta(const uint256 hash, CAmount &nFeeDelta) const; void ClearPrioritisation(const uint256 hash); public: @@ -709,15 +688,6 @@ public: /** Estimate fee rate needed to get into the next nBlocks */ CFeeRate estimateFee(int nBlocks) const; - /** Estimate priority needed to get into the next nBlocks - * If no answer can be given at nBlocks, return an estimate - * at the lowest number of blocks where one can be given - */ - double estimateSmartPriority(int nBlocks, int *answerFoundAtBlocks = NULL) const; - - /** Estimate priority needed to get into the next nBlocks */ - double estimatePriority(int nBlocks) const; - /** Write/Read estimates to disk */ bool WriteFeeEstimates(CAutoFile& fileout) const; bool ReadFeeEstimates(CAutoFile& filein); @@ -782,17 +752,4 @@ public: bool GetCoin(const COutPoint &outpoint, Coin &coin) const override; }; -// We want to sort transactions by coin age priority -typedef std::pair TxCoinAgePriority; - -struct TxCoinAgePriorityCompare -{ - bool operator()(const TxCoinAgePriority& a, const TxCoinAgePriority& b) - { - if (a.first == b.first) - return CompareTxMemPoolEntryByScore()(*(b.second), *(a.second)); //Reverse order to make sort less than - return a.first < b.first; - } -}; - #endif // BITCOIN_TXMEMPOOL_H diff --git a/src/validation.cpp b/src/validation.cpp index a198aee3bd..157aa59885 100644 --- a/src/validation.cpp +++ b/src/validation.cpp @@ -639,7 +639,7 @@ static bool IsCurrentForFeeEstimation() } bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const CTransactionRef& ptx, bool fLimitFree, - bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, + bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, const CAmount& nAbsurdFee, std::vector& coins_to_uncache, bool fDryRun) { const CTransaction& tx = *ptx; @@ -714,7 +714,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C if (itConflicting != pool.mapNextTx.end()) { const CTransaction *ptxConflicting = itConflicting->second; - + // InstantSend txes are not replacable if(instantsend.HasTxLockRequest(ptxConflicting->GetHash())) { // this tx conflicts with a Transaction Lock Request candidate @@ -797,11 +797,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C CAmount nFees = nValueIn-nValueOut; // nModifiedFees includes any fee deltas from PrioritiseTransaction CAmount nModifiedFees = nFees; - double nPriorityDummy = 0; - pool.ApplyDeltas(hash, nPriorityDummy, nModifiedFees); - - CAmount inChainInputValue; - double dPriority = view.GetPriority(tx, chainActive.Height(), inChainInputValue); + pool.ApplyDelta(hash, nModifiedFees); // Keep track of transactions that spend a coinbase, which we re-scan // during reorgs to ensure COINBASE_MATURITY is still met. @@ -814,8 +810,8 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } } - CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, dPriority, chainActive.Height(), - inChainInputValue, fSpendsCoinbase, nSigOps, lp); + CTxMemPoolEntry entry(ptx, nFees, nAcceptTime, chainActive.Height(), + fSpendsCoinbase, nSigOps, lp); unsigned int nSize = entry.GetTxSize(); // Check that the transaction doesn't have an excessive number of @@ -830,32 +826,11 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C CAmount mempoolRejectFee = pool.GetMinFee(GetArg("-maxmempool", DEFAULT_MAX_MEMPOOL_SIZE) * 1000000).GetFee(nSize); if (mempoolRejectFee > 0 && nModifiedFees < mempoolRejectFee) { return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "mempool min fee not met", false, strprintf("%d < %d", nFees, mempoolRejectFee)); - } else if (GetBoolArg("-relaypriority", DEFAULT_RELAYPRIORITY) && nModifiedFees < ::minRelayTxFee.GetFee(nSize) && !AllowFree(entry.GetPriority(chainActive.Height() + 1))) { - // Require that free transactions have sufficient priority to be mined in the next block. - return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "insufficient priority"); } - // Continuously rate-limit free (really, very-low-fee) transactions - // This mitigates 'penny-flooding' -- sending thousands of free transactions just to - // be annoying or make others' transactions take longer to confirm. - if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFee(nSize)) - { - static CCriticalSection csFreeLimiter; - static double dFreeCount; - static int64_t nLastTime; - int64_t nNow = GetTime(); - - LOCK(csFreeLimiter); - - // Use an exponentially decaying ~10-minute window: - dFreeCount *= pow(1.0 - 1.0/600.0, (double)(nNow - nLastTime)); - nLastTime = nNow; - // -limitfreerelay unit is thousand-bytes-per-minute - // At default rate it would take over a month to fill 1GB - if (dFreeCount + nSize >= GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) * 10 * 1000) - return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "rate limited free transaction"); - LogPrint("mempool", "Rate limit dFreeCount: %g => %g\n", dFreeCount, dFreeCount+nSize); - dFreeCount += nSize; + // No transactions are allowed below minRelayTxFee except from disconnected blocks + if (fLimitFree && nModifiedFees < ::minRelayTxFee.GetFee(nSize)) { + return state.DoS(0, false, REJECT_INSUFFICIENTFEE, "min relay fee not met"); } if (nAbsurdFee && nFees > nAbsurdFee) @@ -940,7 +915,7 @@ bool AcceptToMemoryPoolWorker(CTxMemPool& pool, CValidationState& state, const C } bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree, - bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, + bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit, const CAmount nAbsurdFee, bool fDryRun) { std::vector coins_to_uncache; @@ -4559,7 +4534,6 @@ bool LoadMempool(void) } uint64_t num; file >> num; - double prioritydummy = 0; while (num--) { CTransactionRef tx; int64_t nTime; @@ -4570,7 +4544,7 @@ bool LoadMempool(void) CAmount amountdelta = nFeeDelta; if (amountdelta) { - mempool.PrioritiseTransaction(tx->GetHash(), prioritydummy, amountdelta); + mempool.PrioritiseTransaction(tx->GetHash(), amountdelta); } CValidationState state; if (nTime + nExpiryTimeout > nNow) { @@ -4591,7 +4565,7 @@ bool LoadMempool(void) file >> mapDeltas; for (const auto& i : mapDeltas) { - mempool.PrioritiseTransaction(i.first, prioritydummy, i.second); + mempool.PrioritiseTransaction(i.first, i.second); } } catch (const std::exception& e) { LogPrintf("Failed to deserialize mempool data on disk: %s. Continuing anyway.\n", e.what()); @@ -4612,7 +4586,7 @@ void DumpMempool(void) { LOCK(mempool.cs); for (const auto &i : mempool.mapDeltas) { - mapDeltas[i.first] = i.second.second; + mapDeltas[i.first] = i.second; } vinfo = mempool.infoAll(); } diff --git a/src/validation.h b/src/validation.h index cdb373f81a..6be85f4ae6 100644 --- a/src/validation.h +++ b/src/validation.h @@ -124,8 +124,6 @@ static const int64_t BLOCK_DOWNLOAD_TIMEOUT_BASE = 1000000; /** Additional block download timeout per parallel downloading peer (i.e. 1.25 min) */ static const int64_t BLOCK_DOWNLOAD_TIMEOUT_PER_PEER = 500000; -static const unsigned int DEFAULT_LIMITFREERELAY = 0; -static const bool DEFAULT_RELAYPRIORITY = true; static const int64_t DEFAULT_MAX_TIP_AGE = 6 * 60 * 60; // ~144 blocks behind -> 2 x fork detection time, was 24 * 60 * 60 in bitcoin /** Maximum age of our tip in seconds for us to be considered current for fee estimation */ static const int64_t MAX_FEE_ESTIMATION_TIP_AGE = 3 * 60 * 60; @@ -338,7 +336,7 @@ bool AcceptToMemoryPool(CTxMemPool& pool, CValidationState &state, const CTransa /** (try to) add transaction to memory pool with a specified acceptance time **/ bool AcceptToMemoryPoolWithTime(CTxMemPool& pool, CValidationState &state, const CTransactionRef &tx, bool fLimitFree, - bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit=false, + bool* pfMissingInputs, int64_t nAcceptTime, bool fOverrideMempoolLimit=false, const CAmount nAbsurdFee=0, bool fDryRun=false); bool GetUTXOCoin(const COutPoint& outpoint, Coin& coin); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 1fcd043cd7..3fb3529c56 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -49,12 +49,11 @@ CWallet* pwalletMain = NULL; CFeeRate payTxFee(DEFAULT_TRANSACTION_FEE); unsigned int nTxConfirmTarget = DEFAULT_TX_CONFIRM_TARGET; bool bSpendZeroConfChange = DEFAULT_SPEND_ZEROCONF_CHANGE; -bool fSendFreeTransactions = DEFAULT_SEND_FREE_TRANSACTIONS; bool bBIP69Enabled = true; const char * DEFAULT_WALLET_DAT = "wallet.dat"; -/** +/** * Fees smaller than this (in duffs) are considered zero fee (for transaction creation) * Override with -mintxfee */ @@ -3437,7 +3436,6 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT CAmount nValueToSelect = nValue; if (nSubtractFeeFromAmount == 0) nValueToSelect += nFeeRet; - double dPriority = 0; // vouts to the payees for (const auto& recipient : vecSend) { @@ -3495,20 +3493,6 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT return false; } - for (const auto& pcoin : setCoins) - { - CAmount nCredit = pcoin.first->tx->vout[pcoin.second].nValue; - //The coin age after the next block (depth+1) is used instead of the current, - //reflecting an assumption the user would accept a bit more delay for - //a chance at a free transaction. - //But mempool inputs might still be in the mempool, so their age stays 0 - int age = pcoin.first->GetDepthInMainChain(); - assert(age >= 0); - if (age != 0) - age += 1; - dPriority += (double)nCredit * age; - } - const CAmount nChange = nValueIn - nValueToSelect; CTxOut newTxOut; @@ -3666,7 +3650,6 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT } CTransaction txNewConst(txNew); - dPriority = txNewConst.ComputePriority(dPriority, nBytes); // Remove scriptSigs to eliminate the fee calculation dummy signatures for (auto& txin : txNew.vin) { @@ -3678,20 +3661,6 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT if (coinControl && coinControl->nConfirmTarget > 0) currentConfirmationTarget = coinControl->nConfirmTarget; - // Can we complete this as a free transaction? - // Note: InstantSend transaction can't be a free one - if (!fUseInstantSend && fSendFreeTransactions && nBytes <= MAX_FREE_TRANSACTION_CREATE_SIZE) - { - // Not enough fee: enough priority? - double dPriorityNeeded = mempool.estimateSmartPriority(currentConfirmationTarget); - // Require at least hard-coded AllowFree. - if (dPriority >= dPriorityNeeded && AllowFree(dPriority)) - break; - - // Small enough, and priority high enough, to send for free -// if (dPriorityNeeded > 0 && dPriority >= dPriorityNeeded) -// break; - } CAmount nFeeNeeded = std::max(nFeePay, GetMinimumFee(nBytes, currentConfirmationTarget, mempool)); if (coinControl && nFeeNeeded > 0 && coinControl->nMinimumTotalFee > nFeeNeeded) { nFeeNeeded = coinControl->nMinimumTotalFee; @@ -3774,7 +3743,7 @@ bool CWallet::CreateTransaction(const std::vector& vecSend, CWalletT if (GetBoolArg("-walletrejectlongchains", DEFAULT_WALLET_REJECT_LONG_CHAINS)) { // Lastly, ensure this tx will pass the mempool's chain limits LockPoints lp; - CTxMemPoolEntry entry(wtxNew.tx, 0, 0, 0, 0, 0, false, 0, lp); + CTxMemPoolEntry entry(wtxNew.tx, 0, 0, 0, false, 0, lp); CTxMemPool::setEntries setAncestors; size_t nLimitAncestors = GetArg("-limitancestorcount", DEFAULT_ANCESTOR_LIMIT); size_t nLimitAncestorSize = GetArg("-limitancestorsize", DEFAULT_ANCESTOR_SIZE_LIMIT)*1000; @@ -4818,8 +4787,6 @@ std::string CWallet::GetWalletHelpString(bool showDebug) CURRENCY_UNIT, FormatMoney(payTxFee.GetFeePerK()))); strUsage += HelpMessageOpt("-rescan", _("Rescan the block chain for missing wallet transactions on startup")); strUsage += HelpMessageOpt("-salvagewallet", _("Attempt to recover private keys from a corrupt wallet on startup")); - if (showDebug) - strUsage += HelpMessageOpt("-sendfreetransactions", strprintf(_("Send transactions as zero-fee transactions if possible (default: %u)"), DEFAULT_SEND_FREE_TRANSACTIONS)); strUsage += HelpMessageOpt("-spendzeroconfchange", strprintf(_("Spend unconfirmed change when sending transactions (default: %u)"), DEFAULT_SPEND_ZEROCONF_CHANGE)); strUsage += HelpMessageOpt("-txconfirmtarget=", strprintf(_("If paytxfee is not set, include enough fee so transactions begin confirmation on average within n blocks (default: %u)"), DEFAULT_TX_CONFIRM_TARGET)); strUsage += HelpMessageOpt("-usehd", _("Use hierarchical deterministic key generation (HD) after BIP39/BIP44. Only has effect during wallet creation/first start") + " " + strprintf(_("(default: %u)"), DEFAULT_USE_HD_WALLET)); @@ -5177,10 +5144,6 @@ bool CWallet::ParameterInteraction() } nTxConfirmTarget = GetArg("-txconfirmtarget", DEFAULT_TX_CONFIRM_TARGET); bSpendZeroConfChange = GetBoolArg("-spendzeroconfchange", DEFAULT_SPEND_ZEROCONF_CHANGE); - fSendFreeTransactions = GetBoolArg("-sendfreetransactions", DEFAULT_SEND_FREE_TRANSACTIONS); - - if (fSendFreeTransactions && GetArg("-limitfreerelay", DEFAULT_LIMITFREERELAY) <= 0) - return InitError("Creation of free transactions with their relay disabled is not supported."); if (IsArgSet("-walletbackupsdir")) { if (!boost::filesystem::is_directory(GetArg("-walletbackupsdir", ""))) { diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index c8979d6028..4c9ce788b1 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -43,7 +43,6 @@ extern CWallet* pwalletMain; extern CFeeRate payTxFee; extern unsigned int nTxConfirmTarget; extern bool bSpendZeroConfChange; -extern bool fSendFreeTransactions; extern bool bBIP69Enabled; static const unsigned int DEFAULT_KEYPOOL_SIZE = 1000; @@ -61,14 +60,10 @@ static const CAmount MIN_CHANGE = CENT; static const CAmount MIN_FINAL_CHANGE = MIN_CHANGE/2; //! Default for -spendzeroconfchange static const bool DEFAULT_SPEND_ZEROCONF_CHANGE = true; -//! Default for -sendfreetransactions -static const bool DEFAULT_SEND_FREE_TRANSACTIONS = false; //! Default for -walletrejectlongchains static const bool DEFAULT_WALLET_REJECT_LONG_CHAINS = false; //! -txconfirmtarget default static const unsigned int DEFAULT_TX_CONFIRM_TARGET = 6; -//! Largest (in bytes) free transaction we're willing to create -static const unsigned int MAX_FREE_TRANSACTION_CREATE_SIZE = 1000; static const bool DEFAULT_WALLETBROADCAST = true; static const bool DEFAULT_DISABLE_WALLET = false; @@ -780,7 +775,7 @@ public: SetNull(); } - CWallet(const std::string& strWalletFileIn) + CWallet(const std::string& strWalletFileIn) : strWalletFile(strWalletFileIn) { SetNull();