diff --git a/doc/release-notes.md b/doc/release-notes.md --- a/doc/release-notes.md +++ b/doc/release-notes.md @@ -6,3 +6,7 @@ - Remove deprecated "startingpriority" and "currentpriority" from `getrawmempool`, `getmempoolancestors`, `getmempooldescendants` and `getmempoolentry` RPC. + - The `prioritisetransaction` RPC no longer takes a `priority_delta` argument, + which is replaced by a `dummy` argument for backwards compatibility with + clients using positional arguments. The RPC is still used to change the + apparent fee-rate of the transaction by using the `fee_delta` argument. diff --git a/src/rpc/mining.cpp b/src/rpc/mining.cpp --- a/src/rpc/mining.cpp +++ b/src/rpc/mining.cpp @@ -268,12 +268,15 @@ const JSONRPCRequest &request) { if (request.fHelp || request.params.size() != 3) { 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. dummy (required) unused.\n" + "2. dummy (numeric, optional) API-Compatibility for " + "previous API. Must be zero or null.\n" + " DEPRECATED. For forward compatibility use named " + "arguments and omit this parameter.\n" "3. fee_delta (numeric, required) The fee value (in satoshis) " "to add (or subtract, if negative).\n" " The fee is not actually paid, only the " @@ -292,6 +295,12 @@ TxId txid(ParseHashStr(request.params[0].get_str(), "txid")); Amount nAmount = request.params[2].get_int64() * SATOSHI; + if (!(request.params[1].isNull() || request.params[1].get_real() == 0)) { + throw JSONRPCError(RPC_INVALID_PARAMETER, + "Priority is no longer supported, dummy argument to " + "prioritisetransaction must be 0."); + } + g_mempool.PrioritiseTransaction(txid, nAmount); return true; } diff --git a/test/functional/feature_bip68_sequence.py b/test/functional/feature_bip68_sequence.py --- a/test/functional/feature_bip68_sequence.py +++ b/test/functional/feature_bip68_sequence.py @@ -308,7 +308,7 @@ # 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, -fee_multiplier * self.nodes[0].calculate_fee(tx2)) + txid=tx2.hash, fee_delta=-fee_multiplier * self.nodes[0].calculate_fee(tx2)) cur_time = int(time.time()) for i in range(10): self.nodes[0].setmocktime(cur_time + 600) @@ -324,7 +324,7 @@ # Mine tx2, and then try again self.nodes[0].prioritisetransaction( - tx2.hash, 1e15, fee_multiplier * self.nodes[0].calculate_fee(tx2)) + txid=tx2.hash, fee_delta=fee_multiplier * self.nodes[0].calculate_fee(tx2)) # Advance the time on the node so that we can test timelocks self.nodes[0].setmocktime(cur_time + 600) diff --git a/test/functional/mempool_packages.py b/test/functional/mempool_packages.py --- a/test/functional/mempool_packages.py +++ b/test/functional/mempool_packages.py @@ -148,7 +148,7 @@ # Check that ancestor modified fees includes fee deltas from # prioritisetransaction - self.nodes[0].prioritisetransaction(chain[0], 0, 1000) + self.nodes[0].prioritisetransaction(txid=chain[0], fee_delta=1000) mempool = self.nodes[0].getrawmempool(True) ancestor_fees = 0 for x in chain: @@ -159,11 +159,11 @@ ancestor_fees * COIN + 1000) # Undo the prioritisetransaction for later tests - self.nodes[0].prioritisetransaction(chain[0], 0, -1000) + self.nodes[0].prioritisetransaction(txid=chain[0], fee_delta=-1000) # Check that descendant modified fees includes fee deltas from # prioritisetransaction - self.nodes[0].prioritisetransaction(chain[-1], 0, 1000) + self.nodes[0].prioritisetransaction(txid=chain[-1], fee_delta=1000) mempool = self.nodes[0].getrawmempool(True) descendant_fees = 0 @@ -185,7 +185,7 @@ 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(txid=chain[-1], fee_delta=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/test/functional/mining_prioritisetransaction.py b/test/functional/mining_prioritisetransaction.py --- a/test/functional/mining_prioritisetransaction.py +++ b/test/functional/mining_prioritisetransaction.py @@ -52,11 +52,9 @@ assert sizes[i] > LEGACY_MAX_BLOCK_SIZE # 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) + # also check that a different entry in the cheapest bucket is NOT mined self.nodes[0].prioritisetransaction( - txids[0][0], 0, 100 * self.nodes[0].calculate_fee_from_txid(txids[0][0])) - self.nodes[0].prioritisetransaction(txids[0][1], -1e15, 0) + txid=txids[0][0], fee_delta=100 * self.nodes[0].calculate_fee_from_txid(txids[0][0])) self.nodes[0].generate(1) @@ -84,7 +82,7 @@ # we add the minimum fee back. tx_fee = self.nodes[0].gettransaction(high_fee_tx)['fee'] self.nodes[0].prioritisetransaction( - high_fee_tx, -1e15, int(tx_fee * COIN) + self.nodes[0].calculate_fee_from_txid(high_fee_tx)) + txid=high_fee_tx, fee_delta=int(tx_fee * COIN) + self.nodes[0].calculate_fee_from_txid(high_fee_tx)) # Add everything back to mempool self.nodes[0].invalidateblock(self.nodes[0].getbestblockhash()) @@ -109,7 +107,7 @@ 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] @@ -117,37 +115,26 @@ 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].signrawtransactionwithwallet(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].signrawtransactionwithwallet(raw_tx2)["hex"] - tx2_id = self.nodes[0].decoderawtransaction(tx2_hex)["txid"] + tx_id = self.nodes[0].decoderawtransaction(tx_hex)["txid"] # This will raise an exception due to min relay fee not being met assert_raises_rpc_error(-26, "min relay fee not met (code 66)", - self.nodes[0].sendrawtransaction, tx2_hex) - assert tx2_id not in self.nodes[0].getrawmempool() + self.nodes[0].sendrawtransaction, tx_hex) + assert tx_id not in self.nodes[0].getrawmempool() # 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)) + txid=tx_id, fee_delta=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. @@ -155,7 +142,7 @@ self.nodes[0].setmocktime(mock_time) template = self.nodes[0].getblocktemplate() self.nodes[0].prioritisetransaction( - tx2_id, 0, -int(self.relayfee * COIN)) + txid=tx_id, fee_delta=-int(self.relayfee * COIN)) self.nodes[0].setmocktime(mock_time + 10) new_template = self.nodes[0].getblocktemplate()