0
0
Fork 0
mirror of https://github.com/bitcoin/bitcoin.git synced 2025-03-08 14:34:53 -05:00
bitcoin-core/src
MarcoFalke 2583966130
Merge #19478: Remove CTxMempool::mapLinks data structure member
296be8f58e Get rid of unused functions CTxMemPool::GetMemPoolChildren, CTxMemPool::GetMemPoolParents (Jeremy Rubin)
46d955d196 Remove mapLinks in favor of entry inlined structs with iterator type erasure (Jeremy Rubin)

Pull request description:

  Currently we have a peculiar data structure in the mempool called maplinks. Maplinks job is to track the in-pool children and parents of each transaction. This PR can be primarily understood and reviewed as a simple refactoring to remove this extra data structure, although it comes with a nice memory and performance improvement for free.

  Maplinks is particularly peculiar because removing it is not as simple as just moving it's inner structure to the owning CTxMempoolEntry. Because TxLinks (the class storing the setEntries for parents and children) store txiters to each entry in the mempool corresponding to the parent or child, it means that the TxLinks type is "aware" of the boost multiindex (mapTx) it's coming from, which is in turn, aware of the entry type stored in mapTx. Thus we used maplinks to store this entry associated data we in an entirely separate data structure just to avoid a circular type reference caused by storing a txiter inside a CTxMempoolEntry.

  It turns out, we can kill this circular reference by making use of iterator_to multiindex function and std::reference_wrapper. This allows us to get rid of the maplinks data structure and move the ownership of the parents/child sets to the entries themselves.

  The benefit of this good all around, for any of the reasons given below the change would be acceptable, and it doesn't make the code harder to reason about or worse in any respect (as far as I can tell, there's no tradeoff).

  ### Simpler ownership model
  No longer having to consistency check that mapLinks did have records for our CTxMempoolEntry, impossible to have a mapLinks entry outlive or incorrectly die before a CTxMempoolEntry.

  ### Memory Usage
  We get rid of a O(Transactions) sized map in the mempool, which is a long lived data structure.

  ### Performance
  If you have a CTxMemPoolEntry, you immediately know the address of it's children/parents, rather than having to do a O(log(Transactions)) lookup via maplinks (which we do very often). We do it in *so many* places that a true benchmark has to look at a full running node, but it is easy enough to show an improvement in this case.

  The ComplexMemPool shows a good coherence check that we see the expected result of it being 12.5% faster / 1.14x faster.
  ```
  Before:
  # Benchmark, evals, iterations, total, min, max, median
  ComplexMemPool, 5, 1, 1.40462, 0.277222, 0.285339, 0.279793

  After:
  # Benchmark, evals, iterations, total, min, max, median
  ComplexMemPool, 5, 1, 1.22586, 0.243831, 0.247076, 0.244596
  ```
  The ComplexMemPool benchmark only checks doing addUnchecked and TrimToSize for 800 transactions. While this bench does a good job of hammering the relevant types of function, it doesn't test everything.

  Subbing in 5000 transactions shows a that the advantage isn't completely wiped out by other asymptotic factors (this isn't the only bottleneck in growing the mempool), but it's only a bit proportionally slower (10.8%, 1.12x), which adds evidence that this will be a good change for performance minded users.

  ```
  # Benchmark, evals, iterations, total, min, max, median
  ComplexMemPool, 5, 1, 59.1321, 11.5919, 12.235, 11.7068

  # Benchmark, evals, iterations, total, min, max, median
  ComplexMemPool, 5, 1, 52.1307, 10.2641, 10.5206, 10.4306
  ```
  I don't think it's possible to come up with an example of where a maplinks based design would have better performance, but it's something for reviewers to consider.

  # Discussion
  ## Why maplinks in the first place?

  I spoke with the author of mapLinks (sdaftuar) a while back, and my recollection from our conversation was that it was implemented because he did not know how to resolve the circular dependency at the time, and there was no other reason for making it a separate map.

  ## Is iterator_to weird?

  iterator_to is expressly for this purpose, see https://www.boost.org/doc/libs/1_51_0/libs/multi_index/doc/tutorial/indices.html#iterator_to

  >  iterator_to provides a way to retrieve an iterator to an element from a pointer to the element, thus making iterators and pointers interchangeable for the purposes of element pointing (not so for traversal) in many situations. This notwithstanding, it is not the aim of iterator_to to promote the usage of pointers as substitutes for real iterators: the latter are specifically designed for handling the elements of a container, and not only benefit from the iterator orientation of container interfaces, but are also capable of exposing many more programming bugs than raw pointers, both at compile and run time. iterator_to is thus meant to be used in scenarios where access via iterators is not suitable or desireable:
  >
  >     - Interoperability with preexisting APIs based on pointers or references.
  >     - Publication of pointer-based interfaces (for instance, when designing a C-compatible library).
  >     - The exposure of pointers in place of iterators can act as a type erasure barrier effectively decoupling the user of the code from the implementation detail of which particular container is being used. Similar techniques, like the famous Pimpl idiom, are used in large projects to reduce dependencies and build times.
  >     - Self-referencing contexts where an element acts upon its owner container and no iterator to itself is available.

  In other words, iterator_to is the perfect tool for the job by the last reason given. Under the hood it should just be a simple pointer cast and have no major runtime overhead (depending on if the function call is inlined).

  Edit by laanwj: removed at sign from the description

ACKs for top commit:
  jonatack:
    re-ACK 296be8f per `git range-diff ab338a19 3ba1665 296be8f`, sanity check gcc 10.2 debug build is clean.
  hebasto:
    re-ACK 296be8f58e, only rebased since my [previous](https://github.com/bitcoin/bitcoin/pull/19478#pullrequestreview-482400727) review (verified with `git range-diff`).

Tree-SHA512: f5c30a4936fcde6ae32a02823c303b3568a747c2681d11f87df88a149f984a6d3b4c81f391859afbeb68864ef7f6a3d8779f74a58e3de701b3d51f78e498682e
2020-09-07 12:06:55 +02:00
..
bench Remove WalletLocation class 2020-09-03 12:24:32 -04:00
compat net: Use C++11 member initialization in protocol 2020-05-20 08:27:07 -04:00
config
consensus Add txids with non-standard inputs to reject filter 2020-08-04 13:29:40 -04:00
crc32c Import crc32c using subtree merge as as 'src/crc32c' 2020-01-28 17:00:01 +01:00
crypto build: improve builtin_clz* detection 2020-06-29 11:31:17 +08:00
index Merge #19733: Move comment about BaseIndex::DB from TxIndex::DB 2020-08-21 12:48:46 +08:00
interfaces Merge #19619: Remove wallet.dat path handling from wallet.cpp, rpcwallet.cpp 2020-09-07 11:45:36 +12:00
leveldb Update to leveldb upstream using subtree merge 2020-01-28 16:59:07 +01:00
logging Remove use of non-standard zero variadic macros 2020-04-30 18:02:04 +08:00
node Remove mempool global 2020-09-05 16:24:56 +02:00
policy doc: Add doxygen comment to IsRBFOptIn 2020-09-05 11:45:16 +02:00
primitives refactor: add GenTxid (=txid or wtxid) type and use it for tx request logic 2020-07-30 13:44:54 -07:00
qt Merge #19754: wallet, gui: Reload previously loaded wallets on startup 2020-09-03 18:24:32 +02:00
rpc Merge #19478: Remove CTxMempool::mapLinks data structure member 2020-09-07 12:06:55 +02:00
script Merge #19601: Refactoring CHashWriter & Get{Prevouts,Sequence,Outputs}Hash to SHA256 (Alternative to #18071) 2020-08-25 20:18:40 +08:00
secp256k1 Update src/secp256k1 subtree 2020-06-09 13:39:09 -07:00
support Move Win32 defines to configure.ac to ensure they are globally defined 2020-08-20 17:55:06 +00:00
test Remove mempool global 2020-09-05 16:24:56 +02:00
univalue Update univalue subtree 2020-02-09 07:44:29 -08:00
util Merge #19803: Bugfix: Define and use HAVE_FDATASYNC correctly outside LevelDB 2020-08-31 13:07:24 +08:00
wallet Merge #19738: wallet: Avoid multiple BerkeleyBatch in DelAddressBook 2020-09-07 15:56:31 +12:00
zmq Merge #14687: zmq: enable tcp keepalive 2020-09-02 09:09:18 +02:00
.clang-format tools: clang-format 6 compatibility 2020-07-06 03:52:37 +02:00
addrdb.cpp refactor: Use uint16_t instead of unsigned short 2020-06-22 12:12:22 +02:00
addrdb.h Clean up separated ban/discourage interface 2020-07-03 20:43:55 -07:00
addrman.cpp [addrman] Specify max addresses and pct when calling GetAddresses() 2020-08-12 09:22:07 +01:00
addrman.h [addrman] Specify max addresses and pct when calling GetAddresses() 2020-08-12 09:22:07 +01:00
amount.h
arith_uint256.cpp scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
arith_uint256.h scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
attributes.h
banman.cpp banlist: log post-swept banlist size at startup 2020-07-08 21:44:45 +08:00
banman.h Clean up separated ban/discourage interface 2020-07-03 20:43:55 -07:00
base58.cpp Merge #19739: refactor: remove c-string interfaces for DecodeBase58{Check} 2020-08-28 16:50:57 +02:00
base58.h Merge #19739: refactor: remove c-string interfaces for DecodeBase58{Check} 2020-08-28 16:50:57 +02:00
bech32.cpp Add some general std::vector utility functions 2019-10-16 08:56:57 -07:00
bech32.h Assert that the HRP is lowercase in Bech32::Encode 2019-09-05 13:25:11 +12:00
bitcoin-cli-res.rc
bitcoin-cli.cpp Add in/out connections to cli -getinfo 2020-08-24 18:41:24 +02:00
bitcoin-tx-res.rc
bitcoin-tx.cpp Replace usage of GetScriptForWitness with GetScriptForDestination 2020-08-14 08:44:42 +12:00
bitcoin-wallet-res.rc
bitcoin-wallet.cpp scripted-diff: Replace gArgs with local argsman 2020-07-29 16:39:00 +07:00
bitcoind-res.rc
bitcoind.cpp refactor: Create interfaces earlier during initialization 2020-08-27 14:33:00 -04:00
blockencodings.cpp Get rid of -Wthread-safety-precise warnings 2020-05-28 09:55:39 +03:00
blockencodings.h Get rid of -Wthread-safety-precise warnings 2020-05-28 09:55:39 +03:00
blockfilter.cpp Make CHash256/CHash160 output to Span 2020-07-30 13:57:54 -07:00
blockfilter.h [indexes] Fix default [de]serialization of BlockFilter. 2020-05-26 17:27:15 -04:00
bloom.cpp scripted-diff: TxoutType C++11 scoped enum class 2020-06-21 06:41:55 -04:00
bloom.h Merge #18317: Serialization improvements step 6 (all except wallet/gui) 2020-05-20 07:30:29 -04:00
chain.cpp scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
chain.h chain: Remove UB CChain comparison 2020-08-27 20:07:27 -04:00
chainparams.cpp Merge #19316: [net] Cleanup logic around connection types 2020-08-12 10:01:44 +08:00
chainparams.h scripted-diff: Bump copyright headers 2020-04-16 13:33:09 -04:00
chainparamsbase.cpp scripted-diff: Replace gArgs with local argsman 2020-07-29 16:39:00 +07:00
chainparamsbase.h refactor: add unused ArgsManager to replace gArgs 2020-07-29 16:36:44 +07:00
chainparamsseeds.h net: Hardcoded seeds update for 0.20 2020-04-03 16:29:26 +02:00
checkqueue.h scripted-diff: Bump copyright headers 2020-04-16 13:33:09 -04:00
clientversion.cpp Drop unused GIT_COMMIT_DATE macro 2020-05-04 19:53:58 +03:00
clientversion.h
coins.cpp Add CChainState::ResizeCoinsCaches 2020-07-01 14:44:28 -04:00
coins.h Add CChainState::ResizeCoinsCaches 2020-07-01 14:44:28 -04:00
compat.h Move Win32 defines to configure.ac to ensure they are globally defined 2020-08-20 17:55:06 +00:00
compressor.cpp scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
compressor.h scripted-diff: Bump copyright headers 2020-04-16 13:33:09 -04:00
core_io.h scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
core_memusage.h
core_read.cpp refactor: Replace const char* to std::string 2020-05-22 01:40:31 +09:00
core_write.cpp refactor: Avoid duplicate map lookup in ScriptToAsmStr 2020-09-04 10:25:44 +01:00
cuckoocache.h tests: Add fuzzing harness for classes/functions in cuckoocache.h 2020-04-08 14:45:27 +00:00
dbwrapper.cpp scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
dbwrapper.h Drop unused CDBWrapper methods 2020-07-08 14:26:14 +03:00
dummywallet.cpp Merge #19671: wallet: Remove -zapwallettxes 2020-09-01 09:26:28 +08:00
flatfile.cpp Style cleanup. 2019-02-22 17:38:45 -08:00
flatfile.h Merge #18317: Serialization improvements step 6 (all except wallet/gui) 2020-05-20 07:30:29 -04:00
fs.cpp Add missing includes to fix compile errors 2020-06-16 15:15:46 -04:00
fs.h scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
hash.cpp Add SHA256Uint256 helper functions 2020-08-06 16:28:26 -07:00
hash.h Add SHA256Uint256 helper functions 2020-08-06 16:28:26 -07:00
httprpc.cpp Merge #18740: Remove g_rpc_node global 2020-05-21 06:53:39 -04:00
httprpc.h refactor: Pass NodeContext to RPC and REST methods through util::Ref 2020-05-13 16:20:13 -04:00
httpserver.cpp scripted-diff: Move ui_interface to the node lib 2020-06-27 11:49:28 -04:00
httpserver.h scripted-diff: Bump copyright headers 2020-04-16 13:33:09 -04:00
indirectmap.h scripted-diff: Bump copyright headers 2020-04-16 13:33:09 -04:00
init.cpp Remove mempool global 2020-09-05 16:24:56 +02:00
init.h refactor: Create interfaces earlier during initialization 2020-08-27 14:33:00 -04:00
key.cpp tests: Add fuzzing harness for ec_seckey_import_der(...) and ec_seckey_export_der(...) 2020-08-18 18:03:57 +00:00
key.h scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
key_io.cpp scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
key_io.h
limitedmap.h
logging.cpp log: remove deprecated db log category 2020-06-07 17:03:49 +02:00
logging.h refactor: Rename LockGuard to StdLockGuard for consistency with StdMutex 2020-05-28 09:54:24 +03:00
Makefile.am Move only: Move CDiskTxPos to its own file 2020-08-15 18:23:55 -04:00
Makefile.bench.include Replace current benchmarking framework with nanobench 2020-06-13 12:24:18 +02:00
Makefile.crc32c.include build: CRC32C build system integration 2020-01-28 17:01:48 +01:00
Makefile.leveldb.include build: Enable -Wsuggest-override 2020-05-12 18:03:39 +03:00
Makefile.qt.include scripted-diff: rename movie folder to animation 2020-06-29 18:49:13 +01:00
Makefile.qt_locale.include qt: Translations update pre-branch 2020-04-01 12:49:15 +02:00
Makefile.qttest.include build: Create test utility library from src/test/util/ 2019-11-21 21:13:08 +01:00
Makefile.test.include Merge #19379: tests: Add fuzzing harness for SigHasLowR(...) and ecdsa_signature_parse_der_lax(...) 2020-08-31 10:56:34 +02:00
Makefile.test_fuzz.include build: create test_fuzz library from src/test/fuzz/fuzz.cpp 2020-04-05 01:01:13 +02:00
Makefile.test_util.include fuzz: Add process_messages harness 2020-04-05 10:46:24 +08:00
memusage.h scripted-diff: Bump copyright headers 2020-04-16 13:33:09 -04:00
merkleblock.cpp Make Hash[160] consume range-like objects 2020-07-30 13:57:54 -07:00
merkleblock.h Convert merkleblock to new serialization 2020-03-30 16:09:51 -07:00
miner.cpp refactor: Remove unused BlockAssembler::pblock member var 2020-06-15 08:08:19 -04:00
miner.h Remove mapLinks in favor of entry inlined structs with iterator type erasure 2020-09-04 09:46:44 -07:00
net.cpp Merge #19670: Protect localhost and block-relay-only peers from eviction 2020-09-03 17:20:47 +02:00
net.h [doc] Follow developer notes, add comment about missing default. 2020-09-02 17:18:22 -07:00
net_permissions.cpp Add addr permission flag enabling non-cached addr sharing 2020-07-30 14:38:50 +03:00
net_permissions.h Add addr permission flag enabling non-cached addr sharing 2020-07-30 14:38:50 +03:00
net_processing.cpp Merge #19478: Remove CTxMempool::mapLinks data structure member 2020-09-07 12:06:55 +02:00
net_processing.h Merge #19607: [p2p] Add Peer struct for per-peer data in net processing 2020-08-28 20:29:16 +02:00
net_types.h refactor: Remove addrdb.h dependency from node.h 2019-10-29 11:30:12 +02:00
netaddress.cpp Merge #19797: net: Remove old check for 3-byte shifted IP addresses from pre-0.2.9 nodes 2020-08-28 17:51:37 +02:00
netaddress.h net: change CNetAddr::ip to have flexible size 2020-08-24 21:50:59 +02:00
netbase.cpp net: change CNetAddr::ip to have flexible size 2020-08-24 21:50:59 +02:00
netbase.h net: Avoid using C-style NUL-terminated strings as arguments in the netbase interface 2020-01-08 12:35:59 +00:00
netmessagemaker.h refactor: s/command/msg_type/ in CNetMsgMaker and CSerializedNetMsg 2020-05-11 00:20:57 +02:00
noui.cpp scripted-diff: Move ui_interface to the node lib 2020-06-27 11:49:28 -04:00
noui.h Make ThreadSafe{MessageBox|Question} bilingual 2020-05-05 04:45:59 +03:00
optional.h scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
outputtype.cpp Enable Wswitch for OutputType 2020-07-01 18:03:12 -04:00
outputtype.h Remove confusing OutputType::CHANGE_AUTO 2020-07-01 18:02:38 -04:00
pow.cpp
pow.h
prevector.h prevector: Avoid unnamed struct, which is a GNU extension 2020-04-30 18:02:03 +08:00
protocol.cpp refactor: remove unused header <arpa/inet.h> in protocol.cpp 2020-09-06 02:29:30 +02:00
protocol.h Merge #19818: p2p: change CInv::type from int to uint32_t, fix UBSan warning 2020-09-03 17:23:52 +02:00
psbt.cpp psbt: always put a non_witness_utxo and don't remove it 2020-06-24 16:32:19 -04:00
psbt.h psbt: always put a non_witness_utxo and don't remove it 2020-06-24 16:32:19 -04:00
pubkey.cpp tests: Add fuzzing harness for SigHasLowR(...) and ecdsa_signature_parse_der_lax(...) 2020-08-18 18:03:56 +00:00
pubkey.h Make Hash[160] consume range-like objects 2020-07-30 13:57:54 -07:00
random.cpp Merge #17563: lib: fix a compiler warning: unused GetDevURandom() 2020-08-10 21:30:42 +08:00
random.h Add templated GetRandomDuration<> 2020-04-30 09:19:14 -04:00
randomenv.cpp scripted-diff: Bump copyright headers 2020-04-16 13:33:09 -04:00
randomenv.h [MOVEONLY] Move perfmon data gathering to new randomenv module 2019-11-12 14:50:44 -08:00
rest.cpp Remove mempool global 2020-09-05 16:24:56 +02:00
reverse_iterator.h
scheduler.cpp clang-format scheduler 2020-06-21 06:02:59 -04:00
scheduler.h clang-format scheduler 2020-06-21 06:02:59 -04:00
serialize.h refactor: Use uint16_t instead of unsigned short 2020-06-22 12:12:22 +02:00
shutdown.cpp
shutdown.h
span.h Add MakeUCharSpan, to help constructing Span<[const] unsigned char> 2020-07-30 13:57:09 -07:00
streams.h refactor: Drop unused CBufferedFile::Seek() 2020-07-26 22:46:28 +03:00
sync.cpp sync.h: Make runtime lock checks require compile-time lock checks 2020-08-29 20:46:47 +03:00
sync.h sync.h: Make runtime lock checks require compile-time lock checks 2020-08-29 20:46:47 +03:00
threadinterrupt.cpp
threadinterrupt.h scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
threadsafety.h Drop deprecated and unused GUARDED_VAR and PT_GUARDED_VAR annotations 2020-08-18 10:46:53 +03:00
timedata.cpp scripted-diff: Move ui_interface to the node lib 2020-06-27 11:49:28 -04:00
timedata.h
tinyformat.h util: Update tinyformat to upstream 2019-12-06 10:02:08 +01:00
torcontrol.cpp Replace hidden service with onion service 2020-08-07 14:55:02 +02:00
torcontrol.h scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
txdb.cpp Merge #18637: coins: allow cache resize after init 2020-07-29 07:53:19 +02:00
txdb.h txdb: add CCoinsViewDB::ChangeCacheSize 2020-07-01 14:44:24 -04:00
txmempool.cpp Get rid of unused functions CTxMemPool::GetMemPoolChildren, CTxMemPool::GetMemPoolParents 2020-09-04 09:46:44 -07:00
txmempool.h Get rid of unused functions CTxMemPool::GetMemPoolChildren, CTxMemPool::GetMemPoolParents 2020-09-04 09:46:44 -07:00
uint256.cpp refactor: Make HexStr take a span 2020-08-06 19:41:43 +02:00
uint256.h Make uint256 Span-convertible by adding ::data() 2020-07-30 13:57:09 -07:00
undo.h scripted-diff: Bump copyright headers 2020-04-16 13:33:09 -04:00
validation.cpp Remove mempool global 2020-09-05 16:24:56 +02:00
validation.h Remove mempool global 2020-09-05 16:24:56 +02:00
validationinterface.cpp trivial: Suggested cleanups to surrounding code 2020-05-22 16:30:07 -04:00
validationinterface.h trivial: Suggested cleanups to surrounding code 2020-05-22 16:30:07 -04:00
version.h Add p2p message "wtxidrelay" 2020-07-19 02:10:41 -04:00
versionbits.cpp scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
versionbits.h scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
versionbitsinfo.cpp scripted-diff: Bump copyright of files changed in 2019 2019-12-30 10:42:20 +13:00
versionbitsinfo.h
walletinitinterface.h refactor: add unused ArgsManager to replace gArgs 2020-07-29 16:36:44 +07:00
warnings.cpp Make SetMiscWarning() accept bilingual_str argument 2020-06-10 15:01:20 +03:00
warnings.h Make SetMiscWarning() accept bilingual_str argument 2020-06-10 15:01:20 +03:00