elements/src/CMakeLists.txt
Ava Chow 7b66815b16
Merge bitcoin/bitcoin#30110: refactor: TxDownloadManager + fuzzing
0f4bc63585 [fuzz] txdownloadman and txdownload_impl (glozow)
699643f23a [unit test] MempoolRejectedTx (glozow)
fa584cbe72 [p2p] add TxDownloadOptions bool to make TxRequestTracker deterministic (glozow)
f803c8ce8d [p2p] filter 1p1c for child txid in recent rejects (glozow)
5269d57e6d [p2p] don't process orphan if in recent rejects (glozow)
2266eba43a [p2p] don't find 1p1cs for reconsiderable txns that are AlreadyHaveTx (glozow)
fa7027d0fc [refactor] add CheckIsEmpty and GetOrphanTransactions, remove access to TxDownloadMan internals (glozow)
969b07237b [refactor] wrap {Have,Get}TxToReconsider in txdownload (glozow)
f150fb94e7 [refactor] make AlreadyHaveTx and Find1P1CPackage private to TxDownloadImpl (glozow)
1e08195135 [refactor] move new tx logic to txdownload (glozow)
257568eab5 [refactor] move invalid package processing to TxDownload (glozow)
c4ce0c1218 [refactor] move invalid tx processing to TxDownload (glozow)
c6b21749ca [refactor] move valid tx processing to TxDownload (glozow)
a8cf3b6e84 [refactor] move Find1P1CPackage to txdownload (glozow)
f497414ce7 [refactor] put peerman tasks at the end of ProcessInvalidTx (glozow)
6797bc42a7 [p2p] restrict RecursiveDynamicUsage of orphans added to vExtraTxnForCompact (glozow)
798cc8f5aa [refactor] move Find1P1CPackage into ProcessInvalidTx (glozow)
416fbc952b [refactor] move new orphan handling to ProcessInvalidTx (glozow)
c8e67b9169 [refactor] move ProcessInvalidTx and ProcessValidTx definitions down (glozow)
3a41926d1b [refactor] move notfound processing to txdownload (glozow)
042a97ce7f [refactor] move tx inv/getdata handling to txdownload (glozow)
58e09f244b [p2p] don't log tx invs when in IBD (glozow)
288865338f [refactor] rename maybe_add_extra_compact_tx to first_time_failure (glozow)
f48d36cd97 [refactor] move peer (dis)connection logic to TxDownload (glozow)
f61d9e4b4b [refactor] move AlreadyHaveTx to TxDownload (glozow)
84e4ef843d [txdownload] add read-only reference to mempool (glozow)
af918349de [refactor] move ValidationInterface functions to TxDownloadManager (glozow)
f6c860efb1 [doc] fix typo in m_lazy_recent_confirmed_transactions doc (glozow)
5f9004e155 [refactor] add TxDownloadManager wrapping TxOrphanage, TxRequestTracker, and bloom filters (glozow)

Pull request description:

  Part of #27463.

  This PR does 3 things:

  (1) It modularizes transaction download logic into a `TxDownloadManager`. Transaction download logic refers to the process of deciding what transactions to request, download, and validate.[1] There should be no behavior changes. Using `--color_moved=dimmed_zebra -w` may help.
  (2) It adds unit and fuzz (🪄) testing for transaction download.
  (3) It makes a few small behavioral changes:
  - Stop (debug-only) logging tx invs during IBD
  - Just like all other transactions, require orphans have RecursiveDynamicUsage < 100k before adding to vExtraTxnForCompact
  - Don't return a 1p1c that contains a parent or child in recent rejects. Don't process any orphan already in recent rejects. These cases should not happen in actual node operation; it's just to allow tighter sanity checks during fuzzing.

  There are several benefits to this interface, such as:
  - Unit test coverage and fuzzing for logic that currently isn't feasible to test as thoroughly (without lots of overhead) and/or currently only lightly tested through `assert_debug_log` (not good) in functional tests.
  - When we add more functionality (e.g. package relay messages, more robust orphan handling), the vast majority of it will be within `TxDownloadManager` instead of `PeerManager`, making it easier to review and test. See #28031 for what this looks like.
  - `PeerManager` will no longer know anything about / have access to `TxOrphanage`, `TxRequestTracker` or the rejection caches. Its primary interface with `TxDownloadManager` would be much simpler:
      - Passing on  `ValidationInterface` callbacks
      - Telling `txdownloadman` when a peer {connects, disconnects}
      - Telling `txdownloadman`when a {transaction, package} is {accepted, rejected} from mempool
      - Telling `txdownloadman` when invs, notfounds, and txs are received.
      - Getting instructions on what to download.
      - Getting instructions on what {transactions, packages, orphans} to validate.
      - Get whether a peer `HaveMoreWork` for the `ProessMessages` loop
  - (todo) Thread-safety can be handled internally.

  [1]: This module is concerned with tx *download*, not upload. It excludes transaction announcements/gossip which happens after we download/accept a transaction. Txreconciliation (erlay) is excluded from this module, as it only relates to deciding which `inv`s to send or helping the other peer decide which `inv`s to send. It is independent from this logic.

ACKs for top commit:
  achow101:
    light ACK 0f4bc63585
  theStack:
    ACK 0f4bc63585
  instagibbs:
    reACK 0f4bc63585
  naumenkogs:
    ACK 0f4bc63585

Tree-SHA512: 84ab8ef8a0fc705eb829d7f7d6885f28944aaa42b03172f256a42605677b3e783919bb900d4e3b8589f85a0c387dfbd972bcd61d252d44a88c6aaa90e4bf920f
2024-10-29 14:41:12 -04:00

454 lines
11 KiB
CMake

# Copyright (c) 2023-present The Bitcoin Core developers
# Distributed under the MIT software license, see the accompanying
# file COPYING or https://opensource.org/license/mit/.
include(GNUInstallDirs)
include(AddWindowsResources)
configure_file(${PROJECT_SOURCE_DIR}/cmake/bitcoin-build-config.h.in bitcoin-build-config.h USE_SOURCE_PERMISSIONS @ONLY)
include_directories(${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_SOURCE_DIR})
add_custom_target(generate_build_info
BYPRODUCTS ${PROJECT_BINARY_DIR}/src/bitcoin-build-info.h
COMMAND ${CMAKE_COMMAND} -DBUILD_INFO_HEADER_PATH=${PROJECT_BINARY_DIR}/src/bitcoin-build-info.h -DSOURCE_DIR=${PROJECT_SOURCE_DIR} -P ${PROJECT_SOURCE_DIR}/cmake/script/GenerateBuildInfo.cmake
COMMENT "Generating bitcoin-build-info.h"
VERBATIM
)
add_library(bitcoin_clientversion OBJECT EXCLUDE_FROM_ALL
clientversion.cpp
)
target_link_libraries(bitcoin_clientversion
PRIVATE
core_interface
)
add_dependencies(bitcoin_clientversion generate_build_info)
add_subdirectory(crypto)
add_subdirectory(univalue)
add_subdirectory(util)
if(WITH_MULTIPROCESS)
add_subdirectory(ipc)
endif()
#=============================
# secp256k1 subtree
#=============================
message("")
message("Configuring secp256k1 subtree...")
set(SECP256K1_DISABLE_SHARED ON CACHE BOOL "" FORCE)
set(SECP256K1_ENABLE_MODULE_ECDH OFF CACHE BOOL "" FORCE)
set(SECP256K1_ENABLE_MODULE_RECOVERY ON CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_BENCHMARK OFF CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE)
set(SECP256K1_BUILD_EXHAUSTIVE_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE)
if(NOT BUILD_TESTS)
# Always skip the ctime tests, if we are building no other tests.
# Otherwise, they are built if Valgrind is available. See SECP256K1_VALGRIND.
set(SECP256K1_BUILD_CTIME_TESTS ${BUILD_TESTS} CACHE BOOL "" FORCE)
endif()
set(SECP256K1_BUILD_EXAMPLES OFF CACHE BOOL "" FORCE)
include(GetTargetInterface)
# -fsanitize and related flags apply to both C++ and C,
# so we can pass them down to libsecp256k1 as CFLAGS and LDFLAGS.
get_target_interface(core_sanitizer_cxx_flags "" sanitize_interface COMPILE_OPTIONS)
set(SECP256K1_APPEND_CFLAGS ${core_sanitizer_cxx_flags} CACHE STRING "" FORCE)
unset(core_sanitizer_cxx_flags)
get_target_interface(core_sanitizer_linker_flags "" sanitize_interface LINK_OPTIONS)
set(SECP256K1_APPEND_LDFLAGS ${core_sanitizer_linker_flags} CACHE STRING "" FORCE)
unset(core_sanitizer_linker_flags)
# We want to build libsecp256k1 with the most tested RelWithDebInfo configuration.
enable_language(C)
foreach(config IN LISTS CMAKE_BUILD_TYPE CMAKE_CONFIGURATION_TYPES)
if(config STREQUAL "")
continue()
endif()
string(TOUPPER "${config}" config)
set(CMAKE_C_FLAGS_${config} "${CMAKE_C_FLAGS_RELWITHDEBINFO}")
endforeach()
# If the CFLAGS environment variable is defined during building depends
# and configuring this build system, its content might be duplicated.
if(DEFINED ENV{CFLAGS})
deduplicate_flags(CMAKE_C_FLAGS)
endif()
set(CMAKE_EXPORT_COMPILE_COMMANDS OFF)
add_subdirectory(secp256k1)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
string(APPEND CMAKE_C_COMPILE_OBJECT " ${APPEND_CPPFLAGS} ${APPEND_CFLAGS}")
add_library(bitcoin_consensus STATIC EXCLUDE_FROM_ALL
arith_uint256.cpp
consensus/merkle.cpp
consensus/tx_check.cpp
hash.cpp
primitives/block.cpp
primitives/transaction.cpp
pubkey.cpp
script/interpreter.cpp
script/script.cpp
script/script_error.cpp
uint256.cpp
)
target_link_libraries(bitcoin_consensus
PRIVATE
core_interface
bitcoin_crypto
secp256k1
)
if(WITH_ZMQ)
add_subdirectory(zmq)
endif()
# Home for common functionality shared by different executables and libraries.
# Similar to `bitcoin_util` library, but higher-level.
add_library(bitcoin_common STATIC EXCLUDE_FROM_ALL
addresstype.cpp
base58.cpp
bech32.cpp
chainparams.cpp
chainparamsbase.cpp
coins.cpp
common/args.cpp
common/bloom.cpp
common/config.cpp
common/init.cpp
common/interfaces.cpp
common/messages.cpp
common/netif.cpp
common/pcp.cpp
common/run_command.cpp
common/settings.cpp
common/signmessage.cpp
common/system.cpp
common/url.cpp
compressor.cpp
core_read.cpp
core_write.cpp
deploymentinfo.cpp
external_signer.cpp
init/common.cpp
kernel/chainparams.cpp
key.cpp
key_io.cpp
merkleblock.cpp
net_permissions.cpp
net_types.cpp
netaddress.cpp
netbase.cpp
outputtype.cpp
policy/feerate.cpp
policy/policy.cpp
protocol.cpp
psbt.cpp
rpc/external_signer.cpp
rpc/rawtransaction_util.cpp
rpc/request.cpp
rpc/util.cpp
scheduler.cpp
script/descriptor.cpp
script/miniscript.cpp
script/parsing.cpp
script/sign.cpp
script/signingprovider.cpp
script/solver.cpp
)
target_link_libraries(bitcoin_common
PRIVATE
core_interface
bitcoin_consensus
bitcoin_util
univalue
secp256k1
Boost::headers
$<TARGET_NAME_IF_EXISTS:USDT::headers>
$<$<PLATFORM_ID:Windows>:ws2_32>
)
set(installable_targets)
if(ENABLE_WALLET)
add_subdirectory(wallet)
if(BUILD_WALLET_TOOL)
add_executable(bitcoin-wallet
bitcoin-wallet.cpp
init/bitcoin-wallet.cpp
wallet/wallettool.cpp
)
add_windows_resources(bitcoin-wallet bitcoin-wallet-res.rc)
target_link_libraries(bitcoin-wallet
core_interface
bitcoin_wallet
bitcoin_common
bitcoin_util
Boost::headers
)
list(APPEND installable_targets bitcoin-wallet)
endif()
endif()
# P2P and RPC server functionality used by `bitcoind` and `bitcoin-qt` executables.
add_library(bitcoin_node STATIC EXCLUDE_FROM_ALL
addrdb.cpp
addrman.cpp
banman.cpp
bip324.cpp
blockencodings.cpp
blockfilter.cpp
chain.cpp
consensus/tx_verify.cpp
dbwrapper.cpp
deploymentstatus.cpp
flatfile.cpp
headerssync.cpp
httprpc.cpp
httpserver.cpp
i2p.cpp
index/base.cpp
index/blockfilterindex.cpp
index/coinstatsindex.cpp
index/txindex.cpp
init.cpp
kernel/chain.cpp
kernel/checks.cpp
kernel/coinstats.cpp
kernel/context.cpp
kernel/cs_main.cpp
kernel/disconnected_transactions.cpp
kernel/mempool_removal_reason.cpp
mapport.cpp
net.cpp
net_processing.cpp
netgroup.cpp
node/abort.cpp
node/blockmanager_args.cpp
node/blockstorage.cpp
node/caches.cpp
node/chainstate.cpp
node/chainstatemanager_args.cpp
node/coin.cpp
node/coins_view_args.cpp
node/connection_types.cpp
node/context.cpp
node/database_args.cpp
node/eviction.cpp
node/interface_ui.cpp
node/interfaces.cpp
node/kernel_notifications.cpp
node/mempool_args.cpp
node/mempool_persist.cpp
node/mempool_persist_args.cpp
node/miner.cpp
node/mini_miner.cpp
node/minisketchwrapper.cpp
node/peerman_args.cpp
node/psbt.cpp
node/timeoffsets.cpp
node/transaction.cpp
node/txdownloadman_impl.cpp
node/txreconciliation.cpp
node/utxo_snapshot.cpp
node/warnings.cpp
noui.cpp
policy/fees.cpp
policy/fees_args.cpp
policy/packages.cpp
policy/rbf.cpp
policy/settings.cpp
policy/truc_policy.cpp
pow.cpp
rest.cpp
rpc/blockchain.cpp
rpc/fees.cpp
rpc/mempool.cpp
rpc/mining.cpp
rpc/net.cpp
rpc/node.cpp
rpc/output_script.cpp
rpc/rawtransaction.cpp
rpc/server.cpp
rpc/server_util.cpp
rpc/signmessage.cpp
rpc/txoutproof.cpp
script/sigcache.cpp
signet.cpp
torcontrol.cpp
txdb.cpp
txmempool.cpp
txorphanage.cpp
txrequest.cpp
validation.cpp
validationinterface.cpp
versionbits.cpp
$<$<TARGET_EXISTS:bitcoin_wallet>:wallet/init.cpp>
$<$<NOT:$<TARGET_EXISTS:bitcoin_wallet>>:dummywallet.cpp>
)
target_link_libraries(bitcoin_node
PRIVATE
core_interface
bitcoin_common
bitcoin_util
leveldb
minisketch
univalue
Boost::headers
$<TARGET_NAME_IF_EXISTS:libevent::libevent>
$<TARGET_NAME_IF_EXISTS:libevent::pthreads>
$<TARGET_NAME_IF_EXISTS:bitcoin_zmq>
$<TARGET_NAME_IF_EXISTS:USDT::headers>
)
# Bitcoin Core bitcoind.
if(BUILD_DAEMON)
add_executable(bitcoind
bitcoind.cpp
init/bitcoind.cpp
)
add_windows_resources(bitcoind bitcoind-res.rc)
target_link_libraries(bitcoind
core_interface
bitcoin_node
$<TARGET_NAME_IF_EXISTS:bitcoin_wallet>
)
list(APPEND installable_targets bitcoind)
endif()
if(WITH_MULTIPROCESS)
add_executable(bitcoin-node
bitcoind.cpp
init/bitcoin-node.cpp
)
target_link_libraries(bitcoin-node
core_interface
bitcoin_node
bitcoin_ipc
$<TARGET_NAME_IF_EXISTS:bitcoin_wallet>
)
list(APPEND installable_targets bitcoin-node)
if(BUILD_TESTS)
# bitcoin_ipc_test library target is defined here in src/CMakeLists.txt
# instead of src/test/CMakeLists.txt so capnp files in src/test/ are able to
# reference capnp files in src/ipc/capnp/ by relative path. The Cap'n Proto
# compiler only allows importing by relative path when the importing and
# imported files are underneath the same compilation source prefix, so the
# source prefix must be src/, not src/test/
add_library(bitcoin_ipc_test STATIC EXCLUDE_FROM_ALL
test/ipc_test.cpp
)
target_capnp_sources(bitcoin_ipc_test ${PROJECT_SOURCE_DIR}
test/ipc_test.capnp
)
add_dependencies(bitcoin_ipc_test bitcoin_ipc_headers)
endif()
endif()
add_library(bitcoin_cli STATIC EXCLUDE_FROM_ALL
compat/stdin.cpp
rpc/client.cpp
)
target_link_libraries(bitcoin_cli
PUBLIC
core_interface
univalue
)
# Bitcoin Core RPC client
if(BUILD_CLI)
add_executable(bitcoin-cli bitcoin-cli.cpp)
add_windows_resources(bitcoin-cli bitcoin-cli-res.rc)
target_link_libraries(bitcoin-cli
core_interface
bitcoin_cli
bitcoin_common
bitcoin_util
$<TARGET_NAME_IF_EXISTS:libevent::libevent>
)
list(APPEND installable_targets bitcoin-cli)
endif()
if(BUILD_TX)
add_executable(bitcoin-tx bitcoin-tx.cpp)
add_windows_resources(bitcoin-tx bitcoin-tx-res.rc)
target_link_libraries(bitcoin-tx
core_interface
bitcoin_common
bitcoin_util
univalue
)
list(APPEND installable_targets bitcoin-tx)
endif()
if(BUILD_UTIL)
add_executable(bitcoin-util bitcoin-util.cpp)
add_windows_resources(bitcoin-util bitcoin-util-res.rc)
target_link_libraries(bitcoin-util
core_interface
bitcoin_common
bitcoin_util
)
list(APPEND installable_targets bitcoin-util)
endif()
if(BUILD_GUI)
add_subdirectory(qt)
endif()
if(BUILD_KERNEL_LIB)
add_subdirectory(kernel)
endif()
if(BUILD_UTIL_CHAINSTATE)
add_executable(bitcoin-chainstate
bitcoin-chainstate.cpp
)
# TODO: The `SKIP_BUILD_RPATH` property setting can be deleted
# in the future after reordering Guix script commands to
# perform binary checks after the installation step.
# Relevant discussions:
# - https://github.com/hebasto/bitcoin/pull/236#issuecomment-2183120953
# - https://github.com/bitcoin/bitcoin/pull/30312#issuecomment-2191235833
set_target_properties(bitcoin-chainstate PROPERTIES
SKIP_BUILD_RPATH OFF
)
target_link_libraries(bitcoin-chainstate
PRIVATE
core_interface
bitcoinkernel
)
endif()
add_subdirectory(test/util)
if(BUILD_BENCH)
add_subdirectory(bench)
endif()
if(BUILD_TESTS)
add_subdirectory(test)
endif()
if(BUILD_FUZZ_BINARY)
add_subdirectory(test/fuzz)
endif()
install(TARGETS ${installable_targets}
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)
unset(installable_targets)
if(INSTALL_MAN)
# TODO: these stubs are no longer needed. man pages should be generated at install time.
install(DIRECTORY ../doc/man/
DESTINATION ${CMAKE_INSTALL_MANDIR}/man1
FILES_MATCHING PATTERN *.1
)
endif()