From f57cc59be2be4b9b2305d5cd76001f7061ac3bbb Mon Sep 17 00:00:00 2001 From: lateminer Date: Mon, 15 Oct 2018 22:21:51 +0300 Subject: [PATCH] Remove replace-by-fee --- qa/rpc-tests/listtransactions.py | 107 ------------------------------- src/Makefile.am | 2 - src/policy/rbf.cpp | 46 ------------- src/policy/rbf.h | 20 ------ src/wallet/rpcwallet.cpp | 22 ------- 5 files changed, 197 deletions(-) delete mode 100644 src/policy/rbf.cpp delete mode 100644 src/policy/rbf.h diff --git a/qa/rpc-tests/listtransactions.py b/qa/rpc-tests/listtransactions.py index 8dad687ed..8f42db08f 100755 --- a/qa/rpc-tests/listtransactions.py +++ b/qa/rpc-tests/listtransactions.py @@ -10,12 +10,6 @@ from test_framework.util import * from test_framework.mininode import CTransaction, COIN from io import BytesIO -def txFromHex(hexstring): - tx = CTransaction() - f = BytesIO(hex_str_to_bytes(hexstring)) - tx.deserialize(f) - return tx - class ListTransactionsTest(BitcoinTestFramework): def setup_nodes(self): @@ -94,107 +88,6 @@ class ListTransactionsTest(BitcoinTestFramework): {"category":"receive","amount":Decimal("0.1")}, {"txid":txid, "account" : "watchonly"} ) - self.run_rbf_opt_in_test() - - # Check that the opt-in-rbf flag works properly, for sent and received - # transactions. - def run_rbf_opt_in_test(self): - # Check whether a transaction signals opt-in RBF itself - def is_opt_in(node, txid): - rawtx = node.getrawtransaction(txid, 1) - for x in rawtx["vin"]: - if x["sequence"] < 0xfffffffe: - return True - return False - - # Find an unconfirmed output matching a certain txid - def get_unconfirmed_utxo_entry(node, txid_to_match): - utxo = node.listunspent(0, 0) - for i in utxo: - if i["txid"] == txid_to_match: - return i - return None - - # 1. Chain a few transactions that don't opt-in. - txid_1 = self.nodes[0].sendtoaddress(self.nodes[1].getnewaddress(), 1) - assert(not is_opt_in(self.nodes[0], txid_1)) - assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"}) - sync_mempools(self.nodes) - assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_1}, {"bip125-replaceable":"no"}) - - # Tx2 will build off txid_1, still not opting in to RBF. - utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_1) - - # Create tx2 using createrawtransaction - inputs = [{"txid":utxo_to_use["txid"], "vout":utxo_to_use["vout"]}] - outputs = {self.nodes[0].getnewaddress(): 0.999} - tx2 = self.nodes[1].createrawtransaction(inputs, outputs) - tx2_signed = self.nodes[1].signrawtransaction(tx2)["hex"] - txid_2 = self.nodes[1].sendrawtransaction(tx2_signed) - - # ...and check the result - assert(not is_opt_in(self.nodes[1], txid_2)) - assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"}) - sync_mempools(self.nodes) - assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_2}, {"bip125-replaceable":"no"}) - - # Tx3 will opt-in to RBF - utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[0], txid_2) - inputs = [{"txid": txid_2, "vout":utxo_to_use["vout"]}] - outputs = {self.nodes[1].getnewaddress(): 0.998} - tx3 = self.nodes[0].createrawtransaction(inputs, outputs) - tx3_modified = txFromHex(tx3) - tx3_modified.vin[0].nSequence = 0 - tx3 = bytes_to_hex_str(tx3_modified.serialize()) - tx3_signed = self.nodes[0].signrawtransaction(tx3)['hex'] - txid_3 = self.nodes[0].sendrawtransaction(tx3_signed) - - assert(is_opt_in(self.nodes[0], txid_3)) - assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"}) - sync_mempools(self.nodes) - assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_3}, {"bip125-replaceable":"yes"}) - - # Tx4 will chain off tx3. Doesn't signal itself, but depends on one - # that does. - utxo_to_use = get_unconfirmed_utxo_entry(self.nodes[1], txid_3) - inputs = [{"txid": txid_3, "vout":utxo_to_use["vout"]}] - outputs = {self.nodes[0].getnewaddress(): 0.997} - tx4 = self.nodes[1].createrawtransaction(inputs, outputs) - tx4_signed = self.nodes[1].signrawtransaction(tx4)["hex"] - txid_4 = self.nodes[1].sendrawtransaction(tx4_signed) - - assert(not is_opt_in(self.nodes[1], txid_4)) - assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"}) - sync_mempools(self.nodes) - assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"yes"}) - - # Replace tx3, and check that tx4 becomes unknown - tx3_b = tx3_modified - tx3_b.vout[0].nValue -= int(Decimal("0.004") * COIN) # bump the fee - tx3_b = bytes_to_hex_str(tx3_b.serialize()) - tx3_b_signed = self.nodes[0].signrawtransaction(tx3_b)['hex'] - txid_3b = self.nodes[0].sendrawtransaction(tx3_b_signed, True) - assert(is_opt_in(self.nodes[0], txid_3b)) - - assert_array_result(self.nodes[0].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"}) - sync_mempools(self.nodes) - assert_array_result(self.nodes[1].listtransactions(), {"txid": txid_4}, {"bip125-replaceable":"unknown"}) - - # Check gettransaction as well: - for n in self.nodes[0:2]: - assert_equal(n.gettransaction(txid_1)["bip125-replaceable"], "no") - assert_equal(n.gettransaction(txid_2)["bip125-replaceable"], "no") - assert_equal(n.gettransaction(txid_3)["bip125-replaceable"], "yes") - assert_equal(n.gettransaction(txid_3b)["bip125-replaceable"], "yes") - assert_equal(n.gettransaction(txid_4)["bip125-replaceable"], "unknown") - - # After mining a transaction, it's no longer BIP125-replaceable - self.nodes[0].generate(1) - assert(txid_3b not in self.nodes[0].getrawmempool()) - assert_equal(self.nodes[0].gettransaction(txid_3b)["bip125-replaceable"], "no") - assert_equal(self.nodes[0].gettransaction(txid_4)["bip125-replaceable"], "unknown") - - if __name__ == '__main__': ListTransactionsTest().main() diff --git a/src/Makefile.am b/src/Makefile.am index ed8fbaedd..6fe3d2e91 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -122,7 +122,6 @@ BITCOIN_CORE_H = \ noui.h \ policy/fees.h \ policy/policy.h \ - policy/rbf.h \ pos.h \ pow.h \ prevector.h \ @@ -244,7 +243,6 @@ libbitcoin_wallet_a_SOURCES = \ wallet/rpcwallet.cpp \ wallet/wallet.cpp \ wallet/walletdb.cpp \ - policy/rbf.cpp \ $(BITCOIN_CORE_H) # crypto primitives library diff --git a/src/policy/rbf.cpp b/src/policy/rbf.cpp deleted file mode 100644 index 98b1a1ba4..000000000 --- a/src/policy/rbf.cpp +++ /dev/null @@ -1,46 +0,0 @@ -// Copyright (c) 2016 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#include "policy/rbf.h" - -bool SignalsOptInRBF(const CTransaction &tx) -{ - BOOST_FOREACH(const CTxIn &txin, tx.vin) { - if (txin.nSequence < std::numeric_limits::max()-1) { - return true; - } - } - return false; -} - -bool IsRBFOptIn(const CTxMemPoolEntry &entry, CTxMemPool &pool) -{ - AssertLockHeld(pool.cs); - - CTxMemPool::setEntries setAncestors; - - // First check the transaction itself. - if (SignalsOptInRBF(entry.GetTx())) { - return true; - } - - // If this transaction is not in our mempool, then we can't be sure - // we will know about all its inputs. - if (!pool.exists(entry.GetTx().GetHash())) { - throw std::runtime_error("Cannot determine RBF opt-in signal for non-mempool transaction\n"); - } - - // If all the inputs have nSequence >= maxint-1, it still might be - // signaled for RBF if any unconfirmed parents have signaled. - uint64_t noLimit = std::numeric_limits::max(); - std::string dummy; - pool.CalculateMemPoolAncestors(entry, setAncestors, noLimit, noLimit, noLimit, noLimit, dummy, false); - - BOOST_FOREACH(CTxMemPool::txiter it, setAncestors) { - if (SignalsOptInRBF(it->GetTx())) { - return true; - } - } - return false; -} diff --git a/src/policy/rbf.h b/src/policy/rbf.h deleted file mode 100644 index 925ce0d9b..000000000 --- a/src/policy/rbf.h +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2016 The Bitcoin developers -// Distributed under the MIT software license, see the accompanying -// file COPYING or http://www.opensource.org/licenses/mit-license.php. - -#ifndef BITCOIN_POLICY_RBF_H -#define BITCOIN_POLICY_RBF_H - -#include "txmempool.h" - -// Check whether the sequence numbers on this transaction are signaling -// opt-in to replace-by-fee, according to BIP 125 -bool SignalsOptInRBF(const CTransaction &tx); - -// Determine whether an in-mempool transaction is signaling opt-in to RBF -// according to BIP 125 -// This involves checking sequence numbers of the transaction, as well -// as the sequence numbers of all in-mempool ancestors. -bool IsRBFOptIn(const CTxMemPoolEntry &entry, CTxMemPool &pool); - -#endif // BITCOIN_POLICY_RBF_H diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index fa13e834a..c84cf3ae2 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -11,7 +11,6 @@ #include "main.h" #include "net.h" #include "netbase.h" -#include "policy/rbf.h" #include "rpc/server.h" #include "timedata.h" #include "util.h" @@ -100,23 +99,6 @@ void WalletTxToJSON(const CWalletTx& wtx, UniValue& entry) entry.push_back(Pair("respendsobserved", respends)); entry.push_back(Pair("time", wtx.GetTxTime())); entry.push_back(Pair("timereceived", (int64_t)wtx.nTimeReceived)); - - // Add opt-in RBF status - std::string rbfStatus = "no"; - if (confirms <= 0) { - LOCK(mempool.cs); - if (!mempool.exists(hash)) { - if (SignalsOptInRBF(wtx)) { - rbfStatus = "yes"; - } else { - rbfStatus = "unknown"; - } - } else if (IsRBFOptIn(*mempool.mapTx.find(hash), mempool)) { - rbfStatus = "yes"; - } - } - entry.push_back(Pair("bip125-replaceable", rbfStatus)); - BOOST_FOREACH(const PAIRTYPE(string,string)& item, wtx.mapValue) entry.push_back(Pair(item.first, item.second)); } @@ -1439,8 +1421,6 @@ UniValue listtransactions(const UniValue& params, bool fHelp) " \"otheraccount\": \"accountname\", (string) For the 'move' category of transactions, the account the funds came \n" " from (for receiving funds, positive amounts), or went to (for sending funds,\n" " negative amounts).\n" - " \"bip125-replaceable\": \"yes|no|unknown\" (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" - " may be unknown for unconfirmed transactions not in the mempool\n" " }\n" "]\n" @@ -1723,8 +1703,6 @@ UniValue gettransaction(const UniValue& params, bool fHelp) " ],\n" " \"time\" : ttt, (numeric) The transaction time in seconds since epoch (1 Jan 1970 GMT)\n" " \"timereceived\" : ttt, (numeric) The time received in seconds since epoch (1 Jan 1970 GMT)\n" - " \"bip125-replaceable\": \"yes|no|unknown\" (string) Whether this transaction could be replaced due to BIP125 (replace-by-fee);\n" - " may be unknown for unconfirmed transactions not in the mempool\n" " \"details\" : [\n" " {\n" " \"account\" : \"accountname\", (string) DEPRECATED. The account name involved in the transaction, can be \"\" for the default account.\n"