-
Notifications
You must be signed in to change notification settings - Fork 1.2k
backport: bitcoin#24836, #25379, #25773, #25957, #25986, #26158, #26294, #26349, #26388, #26404, #26424, #26625, #26920, #27350 #7085
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
✅ No Merge Conflicts DetectedThis PR currently has no conflicts with other open PRs. |
eaba03f to
7d316cf
Compare
aa59e38 to
b21e0a6
Compare
WalkthroughThis PR adds fast descriptor-wallet rescans using compact block filters, a regtest-only submitpackage RPC for submitting transaction packages, moves URL headers from util/url.h to common/url.h and updates Makefile entries, changes the BENCHMARK macro to accept a priority and marks many benchmarks HIGH, extends the Chain interface with block-filter query/match methods and implements them, adds BCLog::SCAN, adds DescriptorScriptPubKeyMan index-aware accessors, introduces INVALID_PACKAGE error, and refactors many functional tests to use MiniWallet and exercise package/fast-rescan flows. Sequence Diagram(s)sequenceDiagram
participant Node as Node/Wallet
participant ChainImpl as ChainImpl
participant FilterIdx as BlockFilterIndex
participant Filter as GCSFilter
Note over Node,Filter: Block Filter Matching Request
Node->>ChainImpl: blockFilterMatchesAny(filter_type, block_hash, element_set)
ChainImpl->>FilterIdx: GetBlockFilterIndex(filter_type)
alt Index exists
FilterIdx-->>ChainImpl: BlockFilterIndex instance
ChainImpl->>ChainImpl: LookupFilter(block_hash)
alt Filter found
ChainImpl->>Filter: MatchAny(element_set)
Filter-->>ChainImpl: bool (match result)
ChainImpl-->>Node: std::optional<bool> (match result)
else Filter not found
ChainImpl-->>Node: std::nullopt
end
else Index not available
FilterIdx-->>ChainImpl: nullptr
ChainImpl-->>Node: std::nullopt
end
sequenceDiagram
participant Wallet as Wallet::Rescan
participant BlockFilter as FastWalletRescanFilter
participant ChainImpl as ChainImpl
participant Node as Node/Block
Note over Wallet,Node: Fast Rescan with Block Filters (Descriptor Wallet)
Wallet->>BlockFilter: Create (from DescriptorScriptPubKeyMans)
BlockFilter-->>BlockFilter: Build GCS filter set
loop For each block in range
Wallet->>BlockFilter: UpdateIfNeeded() [detect descriptor top-ups]
Wallet->>BlockFilter: MatchesBlock(block_hash)
alt Filter indicates match
BlockFilter-->>Wallet: true
Wallet->>Node: Fetch and inspect block
Node-->>Wallet: Block data & transactions
Wallet->>Wallet: Process transactions
else Filter indicates no match
BlockFilter-->>Wallet: false
Wallet->>Wallet: Skip block (update scan state)
else Filter cannot determine
BlockFilter-->>Wallet: std::nullopt
Wallet->>Wallet: Log warning, inspect block as fallback
end
end
Wallet-->>Wallet: Rescan complete
sequenceDiagram
participant RPC as submitpackage RPC
participant Validation as Validation/Parser
participant Mempool as Mempool
participant Net as Network/Broadcast
Note over RPC,Net: submitpackage RPC Execution
RPC->>RPC: Decode hex transactions array
RPC->>Validation: Parse & validate each transaction
loop For each transaction
alt Valid
Validation-->>RPC: Transaction object
else Invalid
Validation-->>RPC: Error (rejected)
RPC->>RPC: Record failure reason
end
end
RPC->>Mempool: Process package via ProcessNewPackage
alt Package policy valid
Mempool-->>RPC: per-tx acceptance/rejection
loop For each accepted tx
Mempool->>Net: Broadcast transaction
Net-->>RPC: Broadcast acknowledged
end
RPC-->>Caller: tx-results + optional package-feerate
else Package policy invalid
Mempool-->>RPC: Package error
RPC-->>Caller: Error response
end
Estimated code review effort🎯 4 (Complex) | ⏱️ ~75 minutes 🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
Fix all issues with AI Agents 🤖
In @test/functional/mempool_packages.py:
- Around line 231-239: The comparison currently uses identity instead of
equality: replace the identity check `if utxo['txid'] is parent_transaction`
with an equality check against the txid string (i.e., compare utxo['txid'] ==
parent_transaction) so tx_children is populated reliably when the utxo txid
matches parent_transaction; update the condition in the loop that builds
chain/tx_children accordingly.
In @test/functional/rpc_packages.py:
- Around line 268-293: In test_submit_child_with_parents, replace uses of the
internal integer tx.hash with the hex txid string package_txn["txid"]: change
the loop membership check and lookup against submitpackage_result["tx-results"]
to use package_txn["txid"] (both the assert and tx_result assignment), and
change the peer.wait_for_broadcast call to pass a list of package_txn["txid"]
strings instead of tx["tx"].hash so wait_for_broadcast receives hex txid
strings.
- Around line 295-323: In test_submit_cpfp the child transaction is being
referenced by tx_child["tx"].hash and wait_for_broadcast is passed integer
hashes, which is inconsistent with the parent lookups (tx_rich/tx_poor using
"txid") and P2PTxInvStore API; change the child lookup to use
submitpackage_result["tx-results"][tx_child["txid"]] and pass txid strings to
peer.wait_for_broadcast by using [tx["txid"] for tx in package_txns] so all
indexing and broadcast checking consistently use txid strings (update references
to tx_child, package_txns, submitpackage_result, and peer.wait_for_broadcast
accordingly).
🧹 Nitpick comments (4)
test/functional/wallet_listsinceblock.py (1)
404-416: Consider usingnext()for safer list filtering.The test logic correctly verifies that OP_RETURN outputs don't include an address field. However, the list comprehension with
[0]indexing could raiseIndexErrorif no matching transaction is found.🔎 Safer alternative using next()
- op_ret_tx = [tx for tx in self.nodes[2].listsinceblock(blockhash=block_hash)["transactions"] if tx['txid'] == tx_id][0] + op_ret_tx = next(tx for tx in self.nodes[2].listsinceblock(blockhash=block_hash)["transactions"] if tx['txid'] == tx_id)This will raise
StopIterationwith a clearer error message if the transaction isn't found, or you can provide a default value:op_ret_tx = next((tx for tx in self.nodes[2].listsinceblock(blockhash=block_hash)["transactions"] if tx['txid'] == tx_id), None) assert op_ret_tx is not None, "Transaction not found"test/functional/wallet_listtransactions.py (1)
170-179: Consider usingnext()for safer list filtering.The test correctly verifies that OP_RETURN outputs don't include an address field in
listtransactions. However, using[0]on the filtered list could raiseIndexErrorif no matching transaction is found.🔎 Safer alternative using next()
- op_ret_tx = [tx for tx in self.nodes[0].listtransactions() if tx['txid'] == tx_id][0] + op_ret_tx = next(tx for tx in self.nodes[0].listtransactions() if tx['txid'] == tx_id)This will raise
StopIterationwith a clearer error message if the transaction isn't found, or you can provide a default value with explicit error handling:op_ret_tx = next((tx for tx in self.nodes[0].listtransactions() if tx['txid'] == tx_id), None) assert op_ret_tx is not None, "Transaction not found in listtransactions"test/functional/wallet_fast_rescan.py (2)
47-47: Replaceprint()withself.log.info()for consistency.This appears to be leftover debug output. All other logging in this test uses
self.log.info().🔎 Proposed fix
- print(w.importdescriptors([{"desc": descsum_create(f"wpkh({fixed_key.privkey})"), "timestamp": "now"}])) + self.log.info(w.importdescriptors([{"desc": descsum_create(f"wpkh({fixed_key.privkey})"), "timestamp": "now"}]))
52-52: Remove extraneous f-string prefix.Static analysis correctly identifies this f-string has no placeholders. This is a minor style issue.
🔎 Proposed fix
- self.log.info(f"Create txs sending to end range address of each descriptor, triggering top-ups") + self.log.info("Create txs sending to end range address of each descriptor, triggering top-ups")
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (81)
ci/dash/lint-tidy.shci/test/00_setup_env_mac_native_arm64.shci/test/04_install.shdoc/descriptors.mdsrc/Makefile.amsrc/bench/addrman.cppsrc/bench/base58.cppsrc/bench/bech32.cppsrc/bench/bench.hsrc/bench/bip324_ecdh.cppsrc/bench/block_assemble.cppsrc/bench/bls.cppsrc/bench/bls_dkg.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/ccoins_caching.cppsrc/bench/chacha20.cppsrc/bench/checkblock.cppsrc/bench/checkqueue.cppsrc/bench/coin_selection.cppsrc/bench/crypto_hash.cppsrc/bench/duplicate_inputs.cppsrc/bench/ecdsa.cppsrc/bench/ellswift.cppsrc/bench/examples.cppsrc/bench/gcs_filter.cppsrc/bench/hashpadding.cppsrc/bench/load_external.cppsrc/bench/lockedpool.cppsrc/bench/logging.cppsrc/bench/mempool_eviction.cppsrc/bench/mempool_stress.cppsrc/bench/merkle_root.cppsrc/bench/peer_eviction.cppsrc/bench/poly1305.cppsrc/bench/pool.cppsrc/bench/pow_hash.cppsrc/bench/prevector.cppsrc/bench/rollingbloom.cppsrc/bench/rpc_blockchain.cppsrc/bench/rpc_mempool.cppsrc/bench/strencodings.cppsrc/bench/string_cast.cppsrc/bench/util_time.cppsrc/bench/verify_script.cppsrc/bench/wallet_balance.cppsrc/bench/wallet_create.cppsrc/bench/wallet_loading.cppsrc/bitcoin-cli.cppsrc/bitcoin-wallet.cppsrc/bitcoind.cppsrc/common/url.cppsrc/common/url.hsrc/interfaces/chain.hsrc/logging.cppsrc/logging.hsrc/node/interfaces.cppsrc/qt/main.cppsrc/rpc/client.cppsrc/rpc/mempool.cppsrc/test/fuzz/rpc.cppsrc/test/fuzz/string.cppsrc/test/util/setup_common.cppsrc/util/error.cppsrc/util/error.hsrc/wallet/rpc/backup.cppsrc/wallet/rpc/transactions.cppsrc/wallet/rpc/util.cppsrc/wallet/rpc/wallet.cppsrc/wallet/scriptpubkeyman.cppsrc/wallet/scriptpubkeyman.hsrc/wallet/wallet.cpptest/functional/mempool_package_limits.pytest/functional/mempool_packages.pytest/functional/rpc_getblockfrompeer.pytest/functional/rpc_packages.pytest/functional/test_framework/util.pytest/functional/test_framework/wallet.pytest/functional/test_runner.pytest/functional/wallet_fast_rescan.pytest/functional/wallet_listsinceblock.pytest/functional/wallet_listtransactions.py
💤 Files with no reviewable changes (1)
- test/functional/test_framework/util.py
🧰 Additional context used
📓 Path-based instructions (8)
src/**/*.{cpp,h,hpp,cc}
📄 CodeRabbit inference engine (CLAUDE.md)
Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1
Files:
src/wallet/rpc/util.cppsrc/bench/strencodings.cppsrc/bench/bip324_ecdh.cppsrc/bench/coin_selection.cppsrc/bench/hashpadding.cppsrc/bench/mempool_stress.cppsrc/bench/merkle_root.cppsrc/bench/bls_pubkey_agg.cppsrc/common/url.hsrc/wallet/scriptpubkeyman.hsrc/bench/pool.cppsrc/bench/wallet_create.cppsrc/bench/duplicate_inputs.cppsrc/bench/rollingbloom.cppsrc/wallet/rpc/backup.cppsrc/util/error.cppsrc/bench/gcs_filter.cppsrc/bench/load_external.cppsrc/bench/logging.cppsrc/bench/checkqueue.cppsrc/test/fuzz/rpc.cppsrc/bench/addrman.cppsrc/bench/rpc_blockchain.cppsrc/util/error.hsrc/bench/checkblock.cppsrc/bench/ecdsa.cppsrc/bench/mempool_eviction.cppsrc/bench/bench.hsrc/bench/ccoins_caching.cppsrc/interfaces/chain.hsrc/bench/pow_hash.cppsrc/bench/wallet_loading.cppsrc/bench/examples.cppsrc/bench/bls_dkg.cppsrc/bench/chacha20.cppsrc/bench/string_cast.cppsrc/logging.hsrc/bench/base58.cppsrc/wallet/rpc/wallet.cppsrc/bench/bls.cppsrc/bench/poly1305.cppsrc/bench/util_time.cppsrc/bitcoin-wallet.cppsrc/bench/lockedpool.cppsrc/wallet/wallet.cppsrc/logging.cppsrc/wallet/rpc/transactions.cppsrc/bench/rpc_mempool.cppsrc/bench/wallet_balance.cppsrc/test/fuzz/string.cppsrc/bitcoin-cli.cppsrc/node/interfaces.cppsrc/wallet/scriptpubkeyman.cppsrc/bench/block_assemble.cppsrc/bitcoind.cppsrc/bench/ellswift.cppsrc/rpc/client.cppsrc/common/url.cppsrc/bench/prevector.cppsrc/bench/verify_script.cppsrc/bench/crypto_hash.cppsrc/bench/bech32.cppsrc/bench/peer_eviction.cppsrc/rpc/mempool.cppsrc/qt/main.cppsrc/test/util/setup_common.cpp
src/wallet/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
Wallet implementation must use Berkeley DB and SQLite
Files:
src/wallet/rpc/util.cppsrc/wallet/scriptpubkeyman.hsrc/wallet/rpc/backup.cppsrc/wallet/rpc/wallet.cppsrc/wallet/wallet.cppsrc/wallet/rpc/transactions.cppsrc/wallet/scriptpubkeyman.cpp
src/bench/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
Performance benchmarks in src/bench/ must use the nanobench library
Files:
src/bench/strencodings.cppsrc/bench/bip324_ecdh.cppsrc/bench/coin_selection.cppsrc/bench/hashpadding.cppsrc/bench/mempool_stress.cppsrc/bench/merkle_root.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/pool.cppsrc/bench/wallet_create.cppsrc/bench/duplicate_inputs.cppsrc/bench/rollingbloom.cppsrc/bench/gcs_filter.cppsrc/bench/load_external.cppsrc/bench/logging.cppsrc/bench/checkqueue.cppsrc/bench/addrman.cppsrc/bench/rpc_blockchain.cppsrc/bench/checkblock.cppsrc/bench/ecdsa.cppsrc/bench/mempool_eviction.cppsrc/bench/bench.hsrc/bench/ccoins_caching.cppsrc/bench/pow_hash.cppsrc/bench/wallet_loading.cppsrc/bench/examples.cppsrc/bench/bls_dkg.cppsrc/bench/chacha20.cppsrc/bench/string_cast.cppsrc/bench/base58.cppsrc/bench/bls.cppsrc/bench/poly1305.cppsrc/bench/util_time.cppsrc/bench/lockedpool.cppsrc/bench/rpc_mempool.cppsrc/bench/wallet_balance.cppsrc/bench/block_assemble.cppsrc/bench/ellswift.cppsrc/bench/prevector.cppsrc/bench/verify_script.cppsrc/bench/crypto_hash.cppsrc/bench/bech32.cppsrc/bench/peer_eviction.cpp
{guix-build*,releases,**/guix-build*,releases/**,.github/**,depends/**,ci/**,contrib/**,doc/**}
📄 CodeRabbit inference engine (CLAUDE.md)
Do not make changes to build system files (guix-build*), release artifacts, or avoid changes to .github, depends, ci, contrib, and doc directories unless specifically prompted
Files:
ci/test/00_setup_env_mac_native_arm64.shci/test/04_install.shdoc/descriptors.mdci/dash/lint-tidy.sh
test/functional/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Functional tests in test/functional/ must be written in Python (minimum version specified in .python-version) and depend on dashd and dash-node
Files:
test/functional/wallet_listtransactions.pytest/functional/mempool_packages.pytest/functional/wallet_fast_rescan.pytest/functional/test_framework/wallet.pytest/functional/mempool_package_limits.pytest/functional/rpc_getblockfrompeer.pytest/functional/rpc_packages.pytest/functional/wallet_listsinceblock.pytest/functional/test_runner.py
src/{test,wallet/test}/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework
Files:
src/test/fuzz/rpc.cppsrc/test/fuzz/string.cppsrc/test/util/setup_common.cpp
src/node/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
NodeContext must be extended with Dash-specific managers for each subsystem during initialization
Files:
src/node/interfaces.cpp
src/qt/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
GUI implementation in src/qt/ must use Qt 5
Files:
src/qt/main.cpp
🧠 Learnings (31)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: For backport PRs from bitcoin/bitcoin, bitcoin-core/gui, etc., backported changes should match the original upstream PRs even if they appear strange, modify vendored code, or seem to violate coding guidelines. Still flag genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures.
Learnt from: knst
Repo: dashpay/dash PR: 6883
File: src/rpc/rawtransaction.cpp:1088-1125
Timestamp: 2025-10-13T12:37:12.357Z
Learning: In backport pull requests (especially from Bitcoin Core), treat "moved" or refactored code as out-of-scope for content-level review. Focus validation on verifying that code is moved correctly: no fields added, no fields removed, no fields reordered, and no unexpected changes beyond whitespace adjustments. Pre-existing issues in the upstream code should be preserved to maintain fidelity to the original implementation.
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6786
File: ci/test/04_install.sh:99-101
Timestamp: 2025-08-01T07:46:37.840Z
Learning: In backport PRs like #6786, UdjinM6 prefers to defer non-critical fixes (such as shell command expansion issues) to separate commits/PRs to maintain focus on the primary backport objectives, consistent with the project's pattern of avoiding scope creep.
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay
📚 Learning: 2025-08-08T07:01:47.332Z
Learnt from: knst
Repo: dashpay/dash PR: 6805
File: src/wallet/rpc/wallet.cpp:357-357
Timestamp: 2025-08-08T07:01:47.332Z
Learning: In src/wallet/rpc/wallet.cpp, the upgradetohd RPC now returns a UniValue string message (RPCResult::Type::STR) instead of a boolean, including guidance about mnemonic backup and null-character passphrase handling; functional tests have been updated to assert returned strings in several cases.
Applied to files:
src/wallet/rpc/util.cppsrc/bench/wallet_create.cppsrc/wallet/rpc/backup.cppsrc/bench/wallet_loading.cpptest/functional/mempool_packages.pysrc/wallet/rpc/wallet.cppsrc/bitcoin-wallet.cppsrc/wallet/rpc/transactions.cppsrc/bitcoin-cli.cpptest/functional/rpc_packages.pysrc/rpc/client.cppsrc/rpc/mempool.cpp
📚 Learning: 2025-10-25T07:08:51.918Z
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: The univalue library (in src/univalue/) is no longer a vendored external dependency but is now part of the Bitcoin Core codebase and can be modified as needed during backports.
Applied to files:
src/wallet/rpc/util.cppsrc/common/url.hsrc/bitcoin-wallet.cppsrc/bitcoind.cpp
📚 Learning: 2025-02-14T15:19:17.218Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/wallet/rpcwallet.cpp:3002-3003
Timestamp: 2025-02-14T15:19:17.218Z
Learning: The `GetWallet()` function calls in `src/wallet/rpcwallet.cpp` are properly validated with null checks that throw appropriate RPC errors, making additional validation unnecessary.
Applied to files:
src/wallet/rpc/util.cppsrc/wallet/rpc/wallet.cppsrc/wallet/rpc/transactions.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite
Applied to files:
src/wallet/rpc/util.cppsrc/bench/wallet_create.cppsrc/bench/wallet_loading.cppsrc/wallet/rpc/wallet.cppsrc/bitcoin-wallet.cppsrc/wallet/wallet.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/bench/**/*.{cpp,h} : Performance benchmarks in src/bench/ must use the nanobench library
Applied to files:
src/bench/strencodings.cppsrc/bench/coin_selection.cppsrc/bench/hashpadding.cppsrc/bench/mempool_stress.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/pool.cppsrc/bench/rollingbloom.cppsrc/bench/gcs_filter.cppsrc/bench/load_external.cppsrc/bench/logging.cppsrc/bench/checkqueue.cppsrc/bench/addrman.cppsrc/bench/rpc_blockchain.cppsrc/bench/checkblock.cppsrc/bench/ecdsa.cppsrc/bench/mempool_eviction.cppsrc/bench/bench.hsrc/bench/ccoins_caching.cppsrc/bench/pow_hash.cppsrc/bench/wallet_loading.cppsrc/bench/examples.cppsrc/bench/bls_dkg.cppsrc/bench/chacha20.cppsrc/bench/string_cast.cppsrc/bench/base58.cppsrc/bench/poly1305.cppsrc/bench/util_time.cppsrc/bench/lockedpool.cppsrc/bench/wallet_balance.cppsrc/bench/block_assemble.cppsrc/bench/prevector.cppsrc/bench/verify_script.cppsrc/bench/crypto_hash.cppsrc/bench/bech32.cppsrc/bench/peer_eviction.cpp
📚 Learning: 2025-01-02T08:33:26.751Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6516
File: ci/test/00_setup_env_mac.sh:11-11
Timestamp: 2025-01-02T08:33:26.751Z
Learning: The removal of DMG support in the macOS packaging process eliminates the need for python-based scripts or python3-setuptools in the build environment. The PACKAGES variable in ci/test/00_setup_env_mac.sh is vestigial due to the use of a general-purpose Docker container defined in contrib/containers/ci/Dockerfile.
Applied to files:
ci/test/00_setup_env_mac_native_arm64.shci/test/04_install.sh
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs
Applied to files:
src/bench/coin_selection.cppsrc/wallet/wallet.cppsrc/node/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features
Applied to files:
src/bench/bls_pubkey_agg.cppsrc/wallet/rpc/wallet.cppsrc/bench/bls.cppsrc/node/interfaces.cppsrc/rpc/mempool.cppsrc/test/util/setup_common.cpp
📚 Learning: 2025-12-22T15:42:48.595Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In C++/Qt codebases, use fail-fast asserts in setters to enforce invariants (e.g., ensuring internal maps contain necessary keys). Prefer assert() for programmer errors that should be caught in development and debugging, rather than defensive runtime checks with fallbacks. This helps catch invariant violations early during development. Apply to header and source files where invariant-driven state mutations occur, especially in setters like SetWeightBold/SetWeightNormal that assume established relationships or preconditions.
Applied to files:
src/common/url.hsrc/wallet/scriptpubkeyman.hsrc/util/error.hsrc/bench/bench.hsrc/interfaces/chain.hsrc/logging.h
📚 Learning: 2025-12-17T13:58:26.891Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.
Applied to files:
src/wallet/rpc/backup.cppsrc/wallet/wallet.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay
Applied to files:
src/bench/rpc_blockchain.cppsrc/bench/checkblock.cppsrc/Makefile.amsrc/interfaces/chain.htest/functional/mempool_packages.pysrc/wallet/rpc/wallet.cppsrc/bitcoin-wallet.cppsrc/wallet/wallet.cppsrc/wallet/rpc/transactions.cppsrc/bench/rpc_mempool.cppsrc/bitcoin-cli.cppsrc/node/interfaces.cppci/dash/lint-tidy.shsrc/rpc/mempool.cpp
📚 Learning: 2025-09-02T07:34:28.226Z
Learnt from: knst
Repo: dashpay/dash PR: 6834
File: test/functional/wallet_mnemonicbits.py:50-51
Timestamp: 2025-09-02T07:34:28.226Z
Learning: CJ (CoinJoin) descriptors with derivation path "9'/1" are intentionally inactive in descriptor wallets, while regular internal/external descriptors with different derivation paths remain active.
Applied to files:
doc/descriptors.md
📚 Learning: 2025-07-23T09:30:34.631Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.h:5-6
Timestamp: 2025-07-23T09:30:34.631Z
Learning: Dash Core uses BITCOIN_ prefix for header guards as the standard convention, inherited from Bitcoin Core. Only a few BLS-specific files in src/bls/ use DASH_ prefix. The vast majority of files (385+) use BITCOIN_ prefix.
Applied to files:
src/Makefile.amsrc/logging.hsrc/bench/crypto_hash.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Dash extends Bitcoin Core through composition with minimal changes to the Bitcoin Core foundation
Applied to files:
src/Makefile.am
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : ChainLocks implementation must prevent reorganizations and provide block finality through 51% attack prevention
Applied to files:
src/interfaces/chain.hsrc/rpc/mempool.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,consensus,net_processing}/**/*.{cpp,h} : ValidationInterface callbacks must be used for event-driven architecture to coordinate subsystems during block/transaction processing
Applied to files:
src/interfaces/chain.hsrc/node/interfaces.cppsrc/rpc/mempool.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/node/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files
Applied to files:
src/interfaces/chain.hsrc/bitcoin-wallet.cppsrc/bitcoind.cppsrc/rpc/mempool.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data
Applied to files:
src/bench/wallet_loading.cppsrc/node/interfaces.cppsrc/bench/crypto_hash.cpp
📚 Learning: 2025-06-09T16:43:20.996Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
Applied to files:
test/functional/mempool_packages.pytest/functional/mempool_package_limits.pytest/functional/rpc_packages.py
📚 Learning: 2025-06-20T23:32:16.225Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6726
File: test/functional/rpc_createmultisig.py:120-120
Timestamp: 2025-06-20T23:32:16.225Z
Learning: In the rpc_createmultisig.py test, the checkbalances() function correctly excludes 9 blocks from the balance calculation: 8 blocks from do_multisig() calls (2 blocks per call × 4 calls) plus 1 block from checkbalances() itself.
Applied to files:
test/functional/mempool_packages.py
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : LLMQ quorums must support multiple configurations (50/60, 400/60, 400/85) for different services (ChainLocks, InstantSend, governance voting)
Applied to files:
src/bench/bls_dkg.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : InstantSend implementation must provide distributed key generation for secure transaction locking with quorum consensus
Applied to files:
src/bench/bls_dkg.cpp
📚 Learning: 2025-11-04T18:23:28.175Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/governance/classes.cpp:147-154
Timestamp: 2025-11-04T18:23:28.175Z
Learning: In src/governance/classes.cpp, CSuperblock::GetPaymentsLimit intentionally uses synthetic difficulty constants (nBits = 1 for mainnet, powLimit for networks with min difficulty) and simple height-based V20 activation checks instead of actual chain block data. This is by design because superblocks themselves are "synthetic" governance payment blocks, not regular mined blocks.
Applied to files:
src/wallet/wallet.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/governance/**/*.{cpp,h} : Governance implementation must support governance objects (proposals, triggers, superblock management) and on-chain voting with tallying
Applied to files:
src/node/interfaces.cpp
📚 Learning: 2025-12-01T18:13:21.314Z
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 7018
File: test/lint/lint-github-actions.py:1-9
Timestamp: 2025-12-01T18:13:21.314Z
Learning: In the Dash repository, the file test/util/data/non-backported.txt should only include C++ files (.cpp or .h) because it is used for running clang-format. Other file types (such as Python files, .ui files, etc.) should not be added to this list.
Applied to files:
ci/dash/lint-tidy.sh
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/**/*.{cpp,h,hpp,cc} : Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1
Applied to files:
ci/dash/lint-tidy.sh
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{test,wallet/test}/**/*.{cpp,h} : Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework
Applied to files:
ci/dash/lint-tidy.sh
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq,evo,coinjoin,governance}/**/*.{cpp,h} : Use unordered_lru_cache for efficient caching with LRU eviction in Dash-specific data structures
Applied to files:
src/bench/crypto_hash.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/qt/**/*.{cpp,h} : GUI implementation in src/qt/ must use Qt 5
Applied to files:
src/qt/main.cpp
📚 Learning: 2025-12-17T13:58:19.813Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:19.813Z
Learning: In Dash Qt wallet code, prefer using existing Qt signals/slots (e.g., ShowProgress signals) for long-running operations instead of adding explicit QProgressDialog dialogs. This minimizes upstream deviations and simplifies backports. Apply this pattern to wallet-related Qt components (e.g., operations like rescanning) and rely on signal-based progress updates rather than bespoke dialogs.
Applied to files:
src/qt/main.cpp
🧬 Code graph analysis (8)
src/common/url.h (1)
src/common/url.cpp (2)
urlDecode(12-22)urlDecode(12-12)
src/wallet/scriptpubkeyman.h (1)
src/wallet/scriptpubkeyman.cpp (6)
GetScriptPubKeys(2516-2519)GetScriptPubKeys(2516-2516)GetScriptPubKeys(2521-2531)GetScriptPubKeys(2521-2521)GetEndRange(2533-2536)GetEndRange(2533-2533)
src/interfaces/chain.h (2)
src/node/interfaces.cpp (14)
filter_type(1072-1075)filter_type(1072-1072)filter_type(1076-1085)filter_type(1076-1076)block_hash(1056-1062)block_hash(1056-1056)block_hash(1124-1134)block_hash(1124-1124)block_hash(1135-1143)block_hash(1135-1135)block_hash(1159-1163)block_hash(1159-1159)block_hash(1164-1182)block_hash(1164-1164)src/wallet/wallet.cpp (2)
block_hash(319-322)block_hash(319-319)
test/functional/mempool_packages.py (3)
test/functional/test_framework/test_framework.py (1)
is_specified_wallet_compiled(1114-1120)test/functional/test_framework/p2p.py (1)
wait_for_broadcast(1019-1026)test/functional/test_framework/messages.py (1)
get_vsize(593-594)
test/functional/test_framework/wallet.py (1)
test/functional/test_framework/util.py (2)
assert_greater_than_or_equal(82-84)assert_equal(69-74)
test/functional/mempool_package_limits.py (1)
test/functional/test_framework/wallet.py (6)
MiniWallet(74-366)send_self_transfer_chain(357-366)create_self_transfer(315-335)create_self_transfer_multi(260-313)send_self_transfer(226-230)sendrawtransaction(337-340)
test/functional/rpc_packages.py (5)
test/functional/test_framework/messages.py (1)
tx_from_hex(230-232)test/functional/test_framework/p2p.py (2)
P2PTxInvStore(1001-1026)wait_for_broadcast(1019-1026)test/functional/test_framework/util.py (2)
assert_fee_amount(44-52)assert_raises_rpc_error(132-148)test/functional/test_framework/wallet.py (5)
MiniWallet(74-366)create_self_transfer(315-335)create_self_transfer_chain(342-355)create_self_transfer_multi(260-313)get_utxo(192-212)test/functional/test_framework/test_node.py (1)
get_deterministic_priv_key(191-194)
src/rpc/mempool.cpp (2)
src/wallet/rpc/spend.cpp (1)
tx(983-983)src/core_write.cpp (2)
ValueFromAmount(36-47)ValueFromAmount(36-36)
🪛 Cppcheck (2.19.0)
src/bench/bls_pubkey_agg.cpp
[error] 95-95: failed to evaluate #if condition, undefined function-like macro invocation
(syntaxError)
src/node/interfaces.cpp
[error] 22-22: failed to evaluate #if condition, undefined function-like macro invocation
(syntaxError)
src/bench/peer_eviction.cpp
[error] 148-148: Buffer is accessed out of bounds
(bufferAccessOutOfBounds)
src/test/util/setup_common.cpp
[error] 10-10: failed to evaluate #if condition, undefined function-like macro invocation
(syntaxError)
🪛 Flake8 (7.3.0)
test/functional/wallet_fast_rescan.py
[error] 52-52: f-string is missing placeholders
(F541)
test/functional/rpc_packages.py
[error] 51-51: continuation line over-indented for hanging indent
(E126)
[error] 56-56: continuation line under-indented for hanging indent
(E121)
[error] 101-101: continuation line under-indented for visual indent
(E128)
🪛 Ruff (0.14.10)
test/functional/wallet_listtransactions.py
177-177: Prefer next(...) over single element slice
Replace with next(...)
(RUF015)
test/functional/wallet_fast_rescan.py
52-52: f-string without any placeholders
Remove extraneous f prefix
(F541)
test/functional/test_framework/wallet.py
290-290: zip() without an explicit strict= parameter
Add explicit value for parameter strict=
(B905)
test/functional/rpc_packages.py
120-120: Consider [tx_high_fee["hex"], *self.independent_txns_hex] instead of concatenation
Replace with [tx_high_fee["hex"], *self.independent_txns_hex]
(RUF005)
197-197: Consider [*package_hex, child_tx['hex']] instead of concatenation
Replace with [*package_hex, child_tx['hex']]
(RUF005)
202-202: Consider [*package_hex, child_tx["hex"]] instead of concatenation
Replace with [*package_hex, child_tx["hex"]]
(RUF005)
245-245: Unnecessary key check before dictionary access
Replace with dict.get
(RUF019)
260-260: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
test/functional/wallet_listsinceblock.py
413-413: Prefer next(...) over single element slice
Replace with next(...)
(RUF015)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: linux64_multiprocess-build / Build source
- GitHub Check: linux64_tsan-build / Build source
- GitHub Check: linux64_sqlite-build / Build source
- GitHub Check: linux64_fuzz-build / Build source
- GitHub Check: linux64-build / Build source
- GitHub Check: linux64_ubsan-build / Build source
- GitHub Check: mac-build / Build source
- GitHub Check: win64-build / Build source
- GitHub Check: arm-linux-build / Build source
- GitHub Check: linux64_nowallet-build / Build source
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 6
🤖 Fix all issues with AI Agents
In @src/bench/bls_pubkey_agg.cpp:
- Around line 90-99: Each BENCHMARK macro invocation in this snippet is missing
the trailing semicolon; update every BENCHMARK line (e.g.,
BENCHMARK(BLS_PubKeyAggregate_Iterative_5, benchmark::PriorityLevel::HIGH),
BENCHMARK(BLS_PubKeyAggregate_Batch_5, ...),
BENCHMARK(BLS_PubKeyAggregate_Iterative_25, ...), etc.) to end with a semicolon
so the macros are treated as statements and match the style used elsewhere.
In @src/rpc/mempool.cpp:
- Around line 861-870: The loop declares num_submitted inside the for-loop but
never increments it, causing the error message to incorrectly report "0
transactions were broadcast successfully"; either move size_t num_submitted out
before the for-loop and increment it after each successful call to
BroadcastTransaction(node, tx, ...) (checking err == TransactionError::OK) so
the JSONRPCTransactionError message accurately reports the number of successful
broadcasts, or remove num_submitted entirely and change the thrown
JSONRPCTransactionError to a simpler message that omits the success count;
update references to num_submitted and the error string accordingly
(functions/idents: BroadcastTransaction, TransactionError::OK,
JSONRPCTransactionError, num_submitted, txns).
In @test/functional/mempool_packages.py:
- Around line 231-239: The loop that builds chain/tx_children compares
utxo['txid'] to parent_transaction using identity (`is`), which is incorrect for
string values; update the comparison in the for-loop so that utxo['txid'] ==
parent_transaction is used (ensuring string equality) so tx_children is
populated correctly when txids match; locate the comparison involving
utxo['txid'], parent_transaction and tx_children in the transaction-package loop
and replace the identity check with an equality check.
In @test/functional/rpc_packages.py:
- Around line 306-323: The child transaction lookup and broadcast checks use
integer .hash values instead of txid strings; update the child_result lookup to
use tx_child["txid"] when indexing submitpackage_result["tx-results"] (matching
rich_parent_result/poor_parent_result usage) and pass the list of txid strings
(e.g., [tx["txid"] for tx in package_txns]) to peer.wait_for_broadcast so it
expects txid strings rather than integer hashes.
- Around line 268-293: The code incorrectly uses the internal integer tx.hash
for lookups and broadcast waits; change the membership check, lookup key, and
the list passed to peer.wait_for_broadcast to use the txid hex string (e.g.
package_txn["txid"] or tx.get_txid()/txid string from the package_txn dict)
instead of tx.hash or integer hashes so submitpackage_result["tx-results"]
lookups succeed and P2PTxInvStore.wait_for_broadcast receives hex txid strings.
In @test/functional/wallet_fast_rescan.py:
- Line 52: The log call using self.log.info currently uses an unnecessary
f-string with no placeholders; update the string in the self.log.info(...) call
in test/functional/wallet_fast_rescan.py (the line calling "Create txs sending
to end range address of each descriptor, triggering top-ups") by removing the
leading f so it becomes a plain string literal.
🧹 Nitpick comments (3)
test/functional/wallet_listsinceblock.py (1)
44-44: LGTM! OP_RETURN test coverage is valuable.The new
test_op_returnmethod correctly verifies that OP_RETURN transactions inlistsinceblockresponses do not contain anaddressfield, ensuring proper handling of data-only outputs.Optional: Consider using next() for safer list access
Line 413 uses a list comprehension with
[0]indexing which could raiseIndexErrorif the transaction is not found. Thenext()function with a default or explicit check would be more Pythonic:- op_ret_tx = [tx for tx in self.nodes[2].listsinceblock(blockhash=block_hash)["transactions"] if tx['txid'] == tx_id][0] + op_ret_tx = next((tx for tx in self.nodes[2].listsinceblock(blockhash=block_hash)["transactions"] if tx['txid'] == tx_id), None) + assert op_ret_tx is not None, f"Transaction {tx_id} not found in listsinceblock"Also applies to: 404-416
test/functional/wallet_listtransactions.py (1)
170-179: Consider usingnext()for safer iteration.The test logic correctly verifies that OP_RETURN outputs don't have an address field. However, Line 177 uses list comprehension with indexing that could raise
IndexErrorif no matching transaction is found.🔎 Suggested improvement using next()
-op_ret_tx = [tx for tx in self.nodes[0].listtransactions() if tx['txid'] == tx_id][0] +op_ret_tx = next(tx for tx in self.nodes[0].listtransactions() if tx['txid'] == tx_id)This provides clearer intent and will raise
StopIteration(which can be caught or defaulted) rather thanIndexErrorif the transaction isn't found.test/functional/wallet_fast_rescan.py (1)
47-47: Replaceprint()withself.log.debug()orself.log.info()Using
print()is inconsistent with the test framework's logging conventions used elsewhere in this file (e.g.,self.log.info()on lines 42, 52, 54, etc.).Proposed fix
- print(w.importdescriptors([{"desc": descsum_create(f"wpkh({fixed_key.privkey})"), "timestamp": "now"}])) + self.log.debug(w.importdescriptors([{"desc": descsum_create(f"wpkh({fixed_key.privkey})"), "timestamp": "now"}]))
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (82)
ci/dash/lint-tidy.shci/test/00_setup_env_mac_native_arm64.shci/test/04_install.shdoc/descriptors.mddoc/release-notes-25957.mdsrc/Makefile.amsrc/bench/addrman.cppsrc/bench/base58.cppsrc/bench/bech32.cppsrc/bench/bench.hsrc/bench/bip324_ecdh.cppsrc/bench/block_assemble.cppsrc/bench/bls.cppsrc/bench/bls_dkg.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/ccoins_caching.cppsrc/bench/chacha20.cppsrc/bench/checkblock.cppsrc/bench/checkqueue.cppsrc/bench/coin_selection.cppsrc/bench/crypto_hash.cppsrc/bench/duplicate_inputs.cppsrc/bench/ecdsa.cppsrc/bench/ellswift.cppsrc/bench/examples.cppsrc/bench/gcs_filter.cppsrc/bench/hashpadding.cppsrc/bench/load_external.cppsrc/bench/lockedpool.cppsrc/bench/logging.cppsrc/bench/mempool_eviction.cppsrc/bench/mempool_stress.cppsrc/bench/merkle_root.cppsrc/bench/peer_eviction.cppsrc/bench/poly1305.cppsrc/bench/pool.cppsrc/bench/pow_hash.cppsrc/bench/prevector.cppsrc/bench/rollingbloom.cppsrc/bench/rpc_blockchain.cppsrc/bench/rpc_mempool.cppsrc/bench/strencodings.cppsrc/bench/string_cast.cppsrc/bench/util_time.cppsrc/bench/verify_script.cppsrc/bench/wallet_balance.cppsrc/bench/wallet_create.cppsrc/bench/wallet_loading.cppsrc/bitcoin-cli.cppsrc/bitcoin-wallet.cppsrc/bitcoind.cppsrc/common/url.cppsrc/common/url.hsrc/interfaces/chain.hsrc/logging.cppsrc/logging.hsrc/node/interfaces.cppsrc/qt/main.cppsrc/rpc/client.cppsrc/rpc/mempool.cppsrc/test/fuzz/rpc.cppsrc/test/fuzz/string.cppsrc/test/util/setup_common.cppsrc/util/error.cppsrc/util/error.hsrc/wallet/rpc/backup.cppsrc/wallet/rpc/transactions.cppsrc/wallet/rpc/util.cppsrc/wallet/rpc/wallet.cppsrc/wallet/scriptpubkeyman.cppsrc/wallet/scriptpubkeyman.hsrc/wallet/wallet.cpptest/functional/mempool_package_limits.pytest/functional/mempool_packages.pytest/functional/rpc_getblockfrompeer.pytest/functional/rpc_packages.pytest/functional/test_framework/util.pytest/functional/test_framework/wallet.pytest/functional/test_runner.pytest/functional/wallet_fast_rescan.pytest/functional/wallet_listsinceblock.pytest/functional/wallet_listtransactions.py
💤 Files with no reviewable changes (1)
- test/functional/test_framework/util.py
✅ Files skipped from review due to trivial changes (1)
- doc/release-notes-25957.md
🚧 Files skipped from review as they are similar to previous changes (41)
- src/logging.h
- src/qt/main.cpp
- src/bench/util_time.cpp
- src/bench/bip324_ecdh.cpp
- src/bench/duplicate_inputs.cpp
- src/bench/ellswift.cpp
- src/wallet/rpc/util.cpp
- src/util/error.cpp
- src/wallet/rpc/wallet.cpp
- src/bench/strencodings.cpp
- src/bench/poly1305.cpp
- src/bitcoin-cli.cpp
- src/bench/rpc_blockchain.cpp
- src/bitcoin-wallet.cpp
- ci/test/04_install.sh
- src/bench/verify_script.cpp
- src/bench/rpc_mempool.cpp
- src/bitcoind.cpp
- src/bench/chacha20.cpp
- src/wallet/rpc/backup.cpp
- src/bench/pow_hash.cpp
- src/bench/mempool_eviction.cpp
- src/bench/block_assemble.cpp
- src/bench/load_external.cpp
- doc/descriptors.md
- src/bench/bls.cpp
- ci/test/00_setup_env_mac_native_arm64.sh
- src/wallet/wallet.cpp
- src/bench/merkle_root.cpp
- src/bench/prevector.cpp
- src/bench/string_cast.cpp
- src/bench/gcs_filter.cpp
- src/bench/bls_dkg.cpp
- src/bench/wallet_balance.cpp
- src/wallet/scriptpubkeyman.cpp
- src/bench/crypto_hash.cpp
- ci/dash/lint-tidy.sh
- src/test/fuzz/rpc.cpp
- src/wallet/rpc/transactions.cpp
- src/test/fuzz/string.cpp
- src/common/url.cpp
🧰 Additional context used
📓 Path-based instructions (6)
src/**/*.{cpp,h,hpp,cc}
📄 CodeRabbit inference engine (CLAUDE.md)
Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1
Files:
src/bench/bech32.cppsrc/bench/mempool_stress.cppsrc/bench/ecdsa.cppsrc/bench/base58.cppsrc/bench/hashpadding.cppsrc/bench/coin_selection.cppsrc/bench/addrman.cppsrc/wallet/scriptpubkeyman.hsrc/bench/pool.cppsrc/interfaces/chain.hsrc/bench/wallet_loading.cppsrc/bench/ccoins_caching.cppsrc/bench/checkqueue.cppsrc/bench/checkblock.cppsrc/util/error.hsrc/bench/rollingbloom.cppsrc/logging.cppsrc/bench/lockedpool.cppsrc/bench/bench.hsrc/common/url.hsrc/bench/examples.cppsrc/rpc/mempool.cppsrc/bench/wallet_create.cppsrc/rpc/client.cppsrc/bench/logging.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/peer_eviction.cppsrc/node/interfaces.cppsrc/test/util/setup_common.cpp
src/bench/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
Performance benchmarks in src/bench/ must use the nanobench library
Files:
src/bench/bech32.cppsrc/bench/mempool_stress.cppsrc/bench/ecdsa.cppsrc/bench/base58.cppsrc/bench/hashpadding.cppsrc/bench/coin_selection.cppsrc/bench/addrman.cppsrc/bench/pool.cppsrc/bench/wallet_loading.cppsrc/bench/ccoins_caching.cppsrc/bench/checkqueue.cppsrc/bench/checkblock.cppsrc/bench/rollingbloom.cppsrc/bench/lockedpool.cppsrc/bench/bench.hsrc/bench/examples.cppsrc/bench/wallet_create.cppsrc/bench/logging.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/peer_eviction.cpp
src/wallet/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
Wallet implementation must use Berkeley DB and SQLite
Files:
src/wallet/scriptpubkeyman.h
test/functional/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Functional tests in test/functional/ must be written in Python (minimum version specified in .python-version) and depend on dashd and dash-node
Files:
test/functional/rpc_packages.pytest/functional/mempool_packages.pytest/functional/wallet_listsinceblock.pytest/functional/wallet_listtransactions.pytest/functional/wallet_fast_rescan.pytest/functional/rpc_getblockfrompeer.pytest/functional/test_runner.pytest/functional/test_framework/wallet.pytest/functional/mempool_package_limits.py
src/node/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
NodeContext must be extended with Dash-specific managers for each subsystem during initialization
Files:
src/node/interfaces.cpp
src/{test,wallet/test}/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework
Files:
src/test/util/setup_common.cpp
🧠 Learnings (19)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: For backport PRs from bitcoin/bitcoin, bitcoin-core/gui, etc., backported changes should match the original upstream PRs even if they appear strange, modify vendored code, or seem to violate coding guidelines. Still flag genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures.
Learnt from: knst
Repo: dashpay/dash PR: 6883
File: src/rpc/rawtransaction.cpp:1088-1125
Timestamp: 2025-10-13T12:37:12.357Z
Learning: In backport pull requests (especially from Bitcoin Core), treat "moved" or refactored code as out-of-scope for content-level review. Focus validation on verifying that code is moved correctly: no fields added, no fields removed, no fields reordered, and no unexpected changes beyond whitespace adjustments. Pre-existing issues in the upstream code should be preserved to maintain fidelity to the original implementation.
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6786
File: ci/test/04_install.sh:99-101
Timestamp: 2025-08-01T07:46:37.840Z
Learning: In backport PRs like #6786, UdjinM6 prefers to defer non-critical fixes (such as shell command expansion issues) to separate commits/PRs to maintain focus on the primary backport objectives, consistent with the project's pattern of avoiding scope creep.
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/bench/**/*.{cpp,h} : Performance benchmarks in src/bench/ must use the nanobench library
Applied to files:
src/bench/bech32.cppsrc/bench/mempool_stress.cppsrc/bench/ecdsa.cppsrc/bench/base58.cppsrc/bench/hashpadding.cppsrc/bench/coin_selection.cppsrc/bench/addrman.cppsrc/bench/pool.cppsrc/bench/wallet_loading.cppsrc/bench/ccoins_caching.cppsrc/bench/checkqueue.cppsrc/bench/checkblock.cppsrc/bench/rollingbloom.cppsrc/bench/lockedpool.cppsrc/bench/bench.hsrc/bench/examples.cppsrc/bench/logging.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/peer_eviction.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs
Applied to files:
src/bench/coin_selection.cppsrc/node/interfaces.cpp
📚 Learning: 2025-12-22T15:42:48.595Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In C++/Qt codebases, use fail-fast asserts in setters to enforce invariants (e.g., ensuring internal maps contain necessary keys). Prefer assert() for programmer errors that should be caught in development and debugging, rather than defensive runtime checks with fallbacks. This helps catch invariant violations early during development. Apply to header and source files where invariant-driven state mutations occur, especially in setters like SetWeightBold/SetWeightNormal that assume established relationships or preconditions.
Applied to files:
src/wallet/scriptpubkeyman.hsrc/interfaces/chain.hsrc/util/error.hsrc/bench/bench.hsrc/common/url.h
📚 Learning: 2025-06-09T16:43:20.996Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
Applied to files:
test/functional/rpc_packages.pytest/functional/mempool_packages.pytest/functional/mempool_package_limits.py
📚 Learning: 2025-08-08T07:01:47.332Z
Learnt from: knst
Repo: dashpay/dash PR: 6805
File: src/wallet/rpc/wallet.cpp:357-357
Timestamp: 2025-08-08T07:01:47.332Z
Learning: In src/wallet/rpc/wallet.cpp, the upgradetohd RPC now returns a UniValue string message (RPCResult::Type::STR) instead of a boolean, including guidance about mnemonic backup and null-character passphrase handling; functional tests have been updated to assert returned strings in several cases.
Applied to files:
test/functional/rpc_packages.pysrc/bench/wallet_loading.cpptest/functional/mempool_packages.pysrc/rpc/mempool.cppsrc/rpc/client.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay
Applied to files:
src/interfaces/chain.htest/functional/mempool_packages.pysrc/bench/checkblock.cppsrc/Makefile.amsrc/rpc/mempool.cppsrc/node/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,consensus,net_processing}/**/*.{cpp,h} : ValidationInterface callbacks must be used for event-driven architecture to coordinate subsystems during block/transaction processing
Applied to files:
src/interfaces/chain.hsrc/rpc/mempool.cppsrc/node/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/node/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files
Applied to files:
src/interfaces/chain.hsrc/rpc/mempool.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite
Applied to files:
src/bench/wallet_loading.cppsrc/bench/wallet_create.cpp
📚 Learning: 2025-02-06T14:34:30.466Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Applied to files:
test/functional/mempool_packages.py
📚 Learning: 2025-06-20T23:32:16.225Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6726
File: test/functional/rpc_createmultisig.py:120-120
Timestamp: 2025-06-20T23:32:16.225Z
Learning: In the rpc_createmultisig.py test, the checkbalances() function correctly excludes 9 blocks from the balance calculation: 8 blocks from do_multisig() calls (2 blocks per call × 4 calls) plus 1 block from checkbalances() itself.
Applied to files:
test/functional/mempool_packages.py
📚 Learning: 2025-07-23T09:30:34.631Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.h:5-6
Timestamp: 2025-07-23T09:30:34.631Z
Learning: Dash Core uses BITCOIN_ prefix for header guards as the standard convention, inherited from Bitcoin Core. Only a few BLS-specific files in src/bls/ use DASH_ prefix. The vast majority of files (385+) use BITCOIN_ prefix.
Applied to files:
src/Makefile.am
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Dash extends Bitcoin Core through composition with minimal changes to the Bitcoin Core foundation
Applied to files:
src/Makefile.am
📚 Learning: 2025-10-25T07:08:51.918Z
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: The univalue library (in src/univalue/) is no longer a vendored external dependency but is now part of the Bitcoin Core codebase and can be modified as needed during backports.
Applied to files:
src/common/url.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features
Applied to files:
src/rpc/mempool.cppsrc/bench/bls_pubkey_agg.cppsrc/node/interfaces.cppsrc/test/util/setup_common.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : ChainLocks implementation must prevent reorganizations and provide block finality through 51% attack prevention
Applied to files:
src/rpc/mempool.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/governance/**/*.{cpp,h} : Governance implementation must support governance objects (proposals, triggers, superblock management) and on-chain voting with tallying
Applied to files:
src/node/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data
Applied to files:
src/node/interfaces.cpp
🧬 Code graph analysis (6)
src/wallet/scriptpubkeyman.h (1)
src/wallet/scriptpubkeyman.cpp (6)
GetScriptPubKeys(2516-2519)GetScriptPubKeys(2516-2516)GetScriptPubKeys(2521-2531)GetScriptPubKeys(2521-2521)GetEndRange(2533-2536)GetEndRange(2533-2533)
src/interfaces/chain.h (2)
src/node/interfaces.cpp (14)
filter_type(1072-1075)filter_type(1072-1072)filter_type(1076-1085)filter_type(1076-1076)block_hash(1056-1062)block_hash(1056-1056)block_hash(1124-1134)block_hash(1124-1124)block_hash(1135-1143)block_hash(1135-1135)block_hash(1159-1163)block_hash(1159-1159)block_hash(1164-1182)block_hash(1164-1164)src/wallet/wallet.cpp (2)
block_hash(319-322)block_hash(319-319)
test/functional/rpc_getblockfrompeer.py (2)
test/functional/test_framework/p2p.py (1)
send_and_ping(750-752)test/functional/test_framework/messages.py (1)
msg_headers(2050-2068)
src/common/url.h (1)
src/common/url.cpp (2)
urlDecode(12-22)urlDecode(12-12)
test/functional/test_framework/wallet.py (1)
test/functional/test_framework/util.py (2)
assert_greater_than_or_equal(82-84)assert_equal(69-74)
src/node/interfaces.cpp (2)
src/wallet/wallet.cpp (2)
block_hash(319-322)block_hash(319-319)src/index/blockfilterindex.cpp (1)
filter(274-274)
🪛 Cppcheck (2.19.0)
src/bench/bls_pubkey_agg.cpp
[error] 95-95: failed to evaluate #if condition, undefined function-like macro invocation
(syntaxError)
src/bench/peer_eviction.cpp
[error] 148-148: Buffer is accessed out of bounds
(bufferAccessOutOfBounds)
src/node/interfaces.cpp
[error] 22-22: failed to evaluate #if condition, undefined function-like macro invocation
(syntaxError)
src/test/util/setup_common.cpp
[error] 10-10: failed to evaluate #if condition, undefined function-like macro invocation
(syntaxError)
🪛 Flake8 (7.3.0)
test/functional/rpc_packages.py
[error] 51-51: continuation line over-indented for hanging indent
(E126)
[error] 56-56: continuation line under-indented for hanging indent
(E121)
[error] 101-101: continuation line under-indented for visual indent
(E128)
test/functional/wallet_fast_rescan.py
[error] 52-52: f-string is missing placeholders
(F541)
🪛 Ruff (0.14.10)
test/functional/rpc_packages.py
120-120: Consider [tx_high_fee["hex"], *self.independent_txns_hex] instead of concatenation
Replace with [tx_high_fee["hex"], *self.independent_txns_hex]
(RUF005)
197-197: Consider [*package_hex, child_tx['hex']] instead of concatenation
Replace with [*package_hex, child_tx['hex']]
(RUF005)
202-202: Consider [*package_hex, child_tx["hex"]] instead of concatenation
Replace with [*package_hex, child_tx["hex"]]
(RUF005)
245-245: Unnecessary key check before dictionary access
Replace with dict.get
(RUF019)
260-260: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
test/functional/wallet_listsinceblock.py
413-413: Prefer next(...) over single element slice
Replace with next(...)
(RUF015)
test/functional/wallet_listtransactions.py
177-177: Prefer next(...) over single element slice
Replace with next(...)
(RUF015)
test/functional/wallet_fast_rescan.py
52-52: f-string without any placeholders
Remove extraneous f prefix
(F541)
test/functional/test_framework/wallet.py
290-290: zip() without an explicit strict= parameter
Add explicit value for parameter strict=
(B905)
🔇 Additional comments (46)
test/functional/rpc_getblockfrompeer.py (1)
95-95: Excellent fix for the race condition.Replacing
send_messagewithsend_and_pingensures the header is fully processed by node 1 before the test proceeds to callgetblockfrompeeron line 104. This eliminates the intermittent timing-dependent failure where the RPC could execute before header processing completed.src/wallet/scriptpubkeyman.h (1)
644-645: LGTM! Clean API additions for fast wallet rescan.The new methods correctly extend the
DescriptorScriptPubKeyManAPI to support index-aware scriptPubKey retrieval and range queries, which are essential for the BIP157 block filter-based fast rescan feature. The implementations (verified in the .cpp file) properly useLOCK(cs_desc_man)for thread safety.src/logging.cpp (2)
182-182: LGTM: SCAN log category descriptor added correctly.The new log category descriptor follows the established pattern and is correctly positioned before the
ALLentries.
298-299: LGTM: LogCategoryToStr case added correctly.The switch case for SCAN is properly implemented and consistent with the LogCategories array entry, ensuring correct bidirectional conversion between the log flag and its string representation.
src/common/url.h (1)
5-6: LGTM! Header guard correctly updated for file relocation.The header guard macro renaming from
BITCOIN_UTIL_URL_HtoBITCOIN_COMMON_URL_Hcorrectly reflects the file's new location in thecommon/directory.Also applies to: 14-14
src/test/util/setup_common.cpp (1)
10-10: LGTM! Include path correctly updated.The header include path is properly updated to reflect the relocation of URL utilities from
util/url.htocommon/url.h.src/Makefile.am (3)
190-190: LGTM! Core header list correctly updated.The addition of
common/url.htoBITCOIN_CORE_His appropriate for the URL utilities relocation fromutil/tocommon/.
960-963: LGTM! Conditional compilation correctly configured.The conditional inclusion of
common/url.cppunderUSE_LIBEVENTis correct sinceurlDecodeusesevhttp_uridecodefrom libevent. TheEVENT_CFLAGSaddition ensures proper header visibility.
1084-1084: LGTM! Linkage dependency correctly added.Adding
LIBBITCOIN_COMMONtodash_cli_LDADDis necessary because dash-cli now depends on URL utilities fromcommon/url.hwhich are compiled intolibbitcoin_common.src/interfaces/chain.h (1)
8-8: LGTM! Well-designed interface additions for block filter support.The new interface methods are cleanly designed:
hasBlockFilterIndexprovides a simple availability checkblockFilterMatchesAnyappropriately usesstd::optional<bool>to distinguish between "filter unavailable" (std::nullopt) and "no match" (false)The documentation clearly explains the purpose and behavior of these methods for BIP 157 block filter-based fast rescans.
Also applies to: 143-149
src/node/interfaces.cpp (1)
9-9: LGTM! Correct and thread-safe implementation.The implementation properly handles all edge cases:
- Returns
std::nulloptwhen the block filter index is unavailable- Uses
WITH_LOCK(::cs_main, ...)to safely lookup the block index- Returns
std::nulloptwhen the block is not found or filter lookup fails- Successfully returns the match result when all lookups succeed
Thread safety is correctly maintained for the block index access, and all error conditions are appropriately handled.
Also applies to: 22-22, 1072-1085
test/functional/test_runner.py (1)
163-163: LGTM!The new test scripts
rpc_packages.pyandwallet_fast_rescan.py --descriptorsare properly added toBASE_SCRIPTS. The placement in the ~30s section is appropriate for their expected runtime.Also applies to: 170-170
test/functional/mempool_package_limits.py (3)
24-38: LGTM!The
check_package_limitsdecorator cleanly centralizes the common test pattern: verifying empty mempool, running the test to get package hex, checking thattestmempoolacceptfails withpackage-mempool-limits, then clearing mempool and verifying the package passes. This reduces duplication across all decorated test methods.
46-62: LGTM!The test setup correctly initializes MiniWallet, generates sufficient mature UTXOs (35 blocks + COINBASE_MATURITY for maturity), and appropriately restarts the node with
-datacarriersize=100000before the size-limit tests that require large OP_RETURN outputs.
64-131: LGTM!The test methods are cleanly refactored to use MiniWallet's
send_self_transfer_chainandcreate_self_transferhelpers. The test logic for chain limits remains intact while the code becomes more maintainable.src/bench/examples.cpp (1)
21-21: LGTM!The benchmark registration correctly adopts the new two-argument macro format with
benchmark::PriorityLevel::HIGH, aligning with the PR's benchmark framework priority level support.src/bench/bech32.cpp (1)
35-36: LGTM!Both
Bech32EncodeandBech32Decodebenchmark registrations correctly updated with the explicit priority level parameter.src/bench/checkqueue.cpp (1)
73-73: LGTM!The benchmark registration correctly updated with the explicit priority level parameter.
src/bench/lockedpool.cpp (1)
42-42: LGTM!The benchmark registration correctly updated with the explicit priority level parameter.
src/rpc/client.cpp (1)
142-142: LGTM! Correct parameter conversion entry for submitpackage RPC.The entry correctly registers the "package" parameter at index 0 for the new regtest-only submitpackage RPC, enabling proper JSON parsing of the package argument. The format and placement are consistent with other RPC parameter conversion rules in the table.
src/bench/wallet_create.cpp (1)
52-53: LGTM! Benchmark priority levels correctly added.The BENCHMARK registrations have been properly updated to include explicit
benchmark::PriorityLevel::HIGHpriority, consistent with the benchmark framework changes across the codebase. The benchmark logic remains unchanged.src/bench/ccoins_caching.cpp (1)
53-53: LGTM! Benchmark priority level correctly added.The BENCHMARK registration has been properly updated to include explicit
benchmark::PriorityLevel::HIGHpriority, consistent with the benchmark framework updates. No changes to the benchmark implementation itself.src/util/error.h (1)
35-35: LGTM! New error enum value correctly added.The
INVALID_PACKAGEenum value is properly added to theTransactionErrorenum to support package validation errors in the new submitpackage RPC. Placement at the end of the enum maintains compatibility with existing code.src/bench/peer_eviction.cpp (1)
144-155: LGTM! All benchmark priority levels correctly added.All six BENCHMARK registrations (for 0/1/2/3-network eviction protection scenarios with varying candidate counts) have been properly updated to include explicit
benchmark::PriorityLevel::HIGHpriority, consistent with the benchmark framework changes. The benchmark implementations remain unchanged.Note: The static analysis warning at line 148 is a false positive—the line contains only a BENCHMARK registration macro with no buffer access.
src/bench/wallet_loading.cpp (1)
121-121: LGTM! Benchmark priority levels added correctly.The explicit priority level assignments to both
WalletLoadingLegacyandWalletLoadingDescriptorsbenchmarks align with the framework enhancement to support prioritized benchmark execution.Also applies to: 126-126
src/bench/pool.cpp (1)
48-49: LGTM! Benchmark priority levels added correctly.Both pool allocator benchmarks now explicitly specify
benchmark::PriorityLevel::HIGH, consistent with the framework enhancement for prioritized benchmark execution.src/bench/coin_selection.cpp (1)
121-122: LGTM! Benchmark priority levels added correctly.Both coin selection benchmarks (
CoinSelectionandBnBExhaustion) now explicitly specifybenchmark::PriorityLevel::HIGH, aligning with the framework enhancement to support prioritized benchmark execution.src/bench/rollingbloom.cpp (1)
35-36: LGTM! Benchmark priority levels added correctly.Both rolling bloom filter benchmarks (
RollingBloomandRollingBloomReset) now explicitly specifybenchmark::PriorityLevel::HIGH, consistent with the framework enhancement for prioritized benchmark execution.src/bench/hashpadding.cpp (1)
29-29: LGTM!The benchmark registrations have been correctly updated to include explicit priority levels. This aligns with the benchmark framework enhancement across the codebase.
Also applies to: 47-47
src/bench/ecdsa.cpp (1)
87-89: LGTM!All three benchmark registrations correctly updated with explicit priority levels.
src/bench/checkblock.cpp (1)
59-60: LGTM!Both benchmark registrations correctly updated with explicit priority levels.
src/bench/mempool_stress.cpp (1)
115-116: LGTM!Both benchmark registrations correctly updated with explicit priority levels.
src/bench/addrman.cpp (1)
170-175: LGTM: Benchmark priority levels added correctly.All six benchmark registrations have been updated to include the explicit
benchmark::PriorityLevel::HIGHparameter, consistent with the updated BENCHMARK macro signature in bench.h.src/bench/base58.cpp (1)
53-55: LGTM: Benchmark priority levels added correctly.All three benchmark registrations now include
benchmark::PriorityLevel::HIGH, matching the updated macro signature.src/rpc/mempool.cpp (4)
8-8: LGTM: Required include for regtest check.The
chainparams.hinclude is necessary for theParams().IsMockableChain()check in the newsubmitpackageRPC at line 807.
240-240: LGTM: Simplified vsize description.The description was simplified from a detailed note about high-sigop transactions to a concise "Transaction size."
769-894: LGTM: Regtest-only submitpackage RPC implementation is well-structured.The new
submitpackageRPC is properly gated to regtest-only mode, includes comprehensive error handling for package validation results, and provides detailed transaction results. The implementation correctly:
- Validates the environment (regtest-only)
- Decodes and validates transaction inputs
- Processes the package through
ProcessNewPackage- Handles various error cases (PCKG_POLICY, PCKG_MEMPOOL_ERROR, PCKG_TX)
- Returns structured results with transaction fees and optional package feerate
908-908: LGTM: Correct registration as hidden RPC.The
submitpackageRPC is appropriately registered under the "hidden" category, consistent with its experimental regtest-only status.src/bench/logging.cpp (1)
44-48: LGTM: Benchmark priority levels added correctly.All five benchmark registrations now include
benchmark::PriorityLevel::HIGH, consistent with the updated macro signature.src/bench/bench.h (1)
79-80: LGTM: BENCHMARK macro signature updated to support priority levels.The macro now correctly accepts two parameters
(n, priority_level)and passes the priority level to theBenchRunnerconstructor. This foundational change is consistently applied across all benchmark registrations in the codebase.test/functional/wallet_fast_rescan.py (1)
37-99: LGTM!The test logic is well-structured, covering four rescan scenarios (fast/slow × active/non-active descriptors) and properly validating that all variants discover the same transaction set. The use of
assert_debug_logto verify the correct rescan path is taken is a good practice.test/functional/mempool_packages.py (1)
43-70: LGTM on wallet migration!The refactoring to use MiniWallet for transaction creation is clean. The conditional
is_specified_wallet_compiled()check for watch wallet creation properly handles cases where the wallet module isn't compiled in.test/functional/test_framework/wallet.py (3)
96-106: LGTM on_bulk_tximplementationThe padding logic using OP_RETURN is correct. The weight bounds assertions appropriately account for the encoding overhead (up to 3 bytes for lower bound, +12 for length encoding on upper bound).
342-366: LGTM on chain creation methodsThe
create_self_transfer_chainandsend_self_transfer_chainmethods provide clean abstractions for creating dependent transaction chains, which simplifies the test code in mempool_packages.py and other tests.
315-335: LGTM ontarget_weightparameter additionThe
target_weightparameter enables exact weight targeting for bulk transactions. The conditional vsize assertion bypass whentarget_weightis specified is correct since the padded transaction will have a different size.test/functional/rpc_packages.py (1)
234-250: LGTM onassert_equal_package_resultshelperThis helper provides clean validation that submitpackage results are consistent with testmempoolaccept and getmempoolentry data. The conditional check for "allowed" key handles the case where a tx was already in the mempool.
| BENCHMARK(BLS_PubKeyAggregate_Iterative_5, benchmark::PriorityLevel::HIGH) | ||
| BENCHMARK(BLS_PubKeyAggregate_Batch_5, benchmark::PriorityLevel::HIGH) | ||
| BENCHMARK(BLS_PubKeyAggregate_Iterative_25, benchmark::PriorityLevel::HIGH) | ||
| BENCHMARK(BLS_PubKeyAggregate_Batch_25, benchmark::PriorityLevel::HIGH) | ||
| BENCHMARK(BLS_PubKeyAggregate_Iterative_50, benchmark::PriorityLevel::HIGH) | ||
| BENCHMARK(BLS_PubKeyAggregate_Batch_50, benchmark::PriorityLevel::HIGH) | ||
| BENCHMARK(BLS_PubKeyAggregate_Iterative_100, benchmark::PriorityLevel::HIGH) | ||
| BENCHMARK(BLS_PubKeyAggregate_Batch_100, benchmark::PriorityLevel::HIGH) | ||
| BENCHMARK(BLS_PubKeyAggregate_Iterative_200, benchmark::PriorityLevel::HIGH) | ||
| BENCHMARK(BLS_PubKeyAggregate_Batch_200, benchmark::PriorityLevel::HIGH) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Missing semicolons after BENCHMARK macro invocations.
The BENCHMARK macro invocations on lines 90-99 are missing trailing semicolons. Comparing with other benchmark files in this PR (e.g., examples.cpp line 21, bech32.cpp lines 35-36, checkqueue.cpp line 73), all use semicolons after the macro call.
🔎 Proposed fix
-BENCHMARK(BLS_PubKeyAggregate_Iterative_5, benchmark::PriorityLevel::HIGH)
-BENCHMARK(BLS_PubKeyAggregate_Batch_5, benchmark::PriorityLevel::HIGH)
-BENCHMARK(BLS_PubKeyAggregate_Iterative_25, benchmark::PriorityLevel::HIGH)
-BENCHMARK(BLS_PubKeyAggregate_Batch_25, benchmark::PriorityLevel::HIGH)
-BENCHMARK(BLS_PubKeyAggregate_Iterative_50, benchmark::PriorityLevel::HIGH)
-BENCHMARK(BLS_PubKeyAggregate_Batch_50, benchmark::PriorityLevel::HIGH)
-BENCHMARK(BLS_PubKeyAggregate_Iterative_100, benchmark::PriorityLevel::HIGH)
-BENCHMARK(BLS_PubKeyAggregate_Batch_100, benchmark::PriorityLevel::HIGH)
-BENCHMARK(BLS_PubKeyAggregate_Iterative_200, benchmark::PriorityLevel::HIGH)
-BENCHMARK(BLS_PubKeyAggregate_Batch_200, benchmark::PriorityLevel::HIGH)
+BENCHMARK(BLS_PubKeyAggregate_Iterative_5, benchmark::PriorityLevel::HIGH);
+BENCHMARK(BLS_PubKeyAggregate_Batch_5, benchmark::PriorityLevel::HIGH);
+BENCHMARK(BLS_PubKeyAggregate_Iterative_25, benchmark::PriorityLevel::HIGH);
+BENCHMARK(BLS_PubKeyAggregate_Batch_25, benchmark::PriorityLevel::HIGH);
+BENCHMARK(BLS_PubKeyAggregate_Iterative_50, benchmark::PriorityLevel::HIGH);
+BENCHMARK(BLS_PubKeyAggregate_Batch_50, benchmark::PriorityLevel::HIGH);
+BENCHMARK(BLS_PubKeyAggregate_Iterative_100, benchmark::PriorityLevel::HIGH);
+BENCHMARK(BLS_PubKeyAggregate_Batch_100, benchmark::PriorityLevel::HIGH);
+BENCHMARK(BLS_PubKeyAggregate_Iterative_200, benchmark::PriorityLevel::HIGH);
+BENCHMARK(BLS_PubKeyAggregate_Batch_200, benchmark::PriorityLevel::HIGH);Note: The Cppcheck static analysis error is likely a false positive caused by its inability to resolve the macro expansion context.
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| BENCHMARK(BLS_PubKeyAggregate_Iterative_5, benchmark::PriorityLevel::HIGH) | |
| BENCHMARK(BLS_PubKeyAggregate_Batch_5, benchmark::PriorityLevel::HIGH) | |
| BENCHMARK(BLS_PubKeyAggregate_Iterative_25, benchmark::PriorityLevel::HIGH) | |
| BENCHMARK(BLS_PubKeyAggregate_Batch_25, benchmark::PriorityLevel::HIGH) | |
| BENCHMARK(BLS_PubKeyAggregate_Iterative_50, benchmark::PriorityLevel::HIGH) | |
| BENCHMARK(BLS_PubKeyAggregate_Batch_50, benchmark::PriorityLevel::HIGH) | |
| BENCHMARK(BLS_PubKeyAggregate_Iterative_100, benchmark::PriorityLevel::HIGH) | |
| BENCHMARK(BLS_PubKeyAggregate_Batch_100, benchmark::PriorityLevel::HIGH) | |
| BENCHMARK(BLS_PubKeyAggregate_Iterative_200, benchmark::PriorityLevel::HIGH) | |
| BENCHMARK(BLS_PubKeyAggregate_Batch_200, benchmark::PriorityLevel::HIGH) | |
| BENCHMARK(BLS_PubKeyAggregate_Iterative_5, benchmark::PriorityLevel::HIGH); | |
| BENCHMARK(BLS_PubKeyAggregate_Batch_5, benchmark::PriorityLevel::HIGH); | |
| BENCHMARK(BLS_PubKeyAggregate_Iterative_25, benchmark::PriorityLevel::HIGH); | |
| BENCHMARK(BLS_PubKeyAggregate_Batch_25, benchmark::PriorityLevel::HIGH); | |
| BENCHMARK(BLS_PubKeyAggregate_Iterative_50, benchmark::PriorityLevel::HIGH); | |
| BENCHMARK(BLS_PubKeyAggregate_Batch_50, benchmark::PriorityLevel::HIGH); | |
| BENCHMARK(BLS_PubKeyAggregate_Iterative_100, benchmark::PriorityLevel::HIGH); | |
| BENCHMARK(BLS_PubKeyAggregate_Batch_100, benchmark::PriorityLevel::HIGH); | |
| BENCHMARK(BLS_PubKeyAggregate_Iterative_200, benchmark::PriorityLevel::HIGH); | |
| BENCHMARK(BLS_PubKeyAggregate_Batch_200, benchmark::PriorityLevel::HIGH); |
🧰 Tools
🪛 Cppcheck (2.19.0)
[error] 95-95: failed to evaluate #if condition, undefined function-like macro invocation
(syntaxError)
🤖 Prompt for AI Agents
In @src/bench/bls_pubkey_agg.cpp around lines 90 - 99, Each BENCHMARK macro
invocation in this snippet is missing the trailing semicolon; update every
BENCHMARK line (e.g., BENCHMARK(BLS_PubKeyAggregate_Iterative_5,
benchmark::PriorityLevel::HIGH), BENCHMARK(BLS_PubKeyAggregate_Batch_5, ...),
BENCHMARK(BLS_PubKeyAggregate_Iterative_25, ...), etc.) to end with a semicolon
so the macros are treated as statements and match the style used elsewhere.
| for _ in range(DEFAULT_DESCENDANT_LIMIT - 1): | ||
| utxo = transaction_package.pop(0) | ||
| (txid, sent_value) = chain_transaction(self.nodes[0], [utxo['txid']], [utxo['vout']], utxo['amount'], fee, 10) | ||
| new_tx = self.wallet.send_self_transfer_multi(from_node=self.nodes[0], num_outputs=10, utxos_to_spend=[utxo]) | ||
| txid = new_tx["txid"] | ||
| chain.append(txid) | ||
| if utxo['txid'] is parent_transaction: | ||
| tx_children.append(txid) | ||
| for j in range(10): | ||
| transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value}) | ||
| transaction_package.extend(new_tx["new_utxos"]) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use equality (==) instead of identity (is) for txid comparison
The comparison utxo['txid'] is parent_transaction uses identity check (is) instead of equality (==). For string comparison, this is unreliable and can cause tx_children to be empty or incomplete, breaking the descendant/spentby checks below.
Proposed fix
- if utxo['txid'] is parent_transaction:
+ if utxo['txid'] == parent_transaction:
tx_children.append(txid)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| for _ in range(DEFAULT_DESCENDANT_LIMIT - 1): | |
| utxo = transaction_package.pop(0) | |
| (txid, sent_value) = chain_transaction(self.nodes[0], [utxo['txid']], [utxo['vout']], utxo['amount'], fee, 10) | |
| new_tx = self.wallet.send_self_transfer_multi(from_node=self.nodes[0], num_outputs=10, utxos_to_spend=[utxo]) | |
| txid = new_tx["txid"] | |
| chain.append(txid) | |
| if utxo['txid'] is parent_transaction: | |
| tx_children.append(txid) | |
| for j in range(10): | |
| transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value}) | |
| transaction_package.extend(new_tx["new_utxos"]) | |
| for _ in range(DEFAULT_DESCENDANT_LIMIT - 1): | |
| utxo = transaction_package.pop(0) | |
| new_tx = self.wallet.send_self_transfer_multi(from_node=self.nodes[0], num_outputs=10, utxos_to_spend=[utxo]) | |
| txid = new_tx["txid"] | |
| chain.append(txid) | |
| if utxo['txid'] == parent_transaction: | |
| tx_children.append(txid) | |
| transaction_package.extend(new_tx["new_utxos"]) |
🤖 Prompt for AI Agents
In @test/functional/mempool_packages.py around lines 231 - 239, The loop that
builds chain/tx_children compares utxo['txid'] to parent_transaction using
identity (`is`), which is incorrect for string values; update the comparison in
the for-loop so that utxo['txid'] == parent_transaction is used (ensuring string
equality) so tx_children is populated correctly when txids match; locate the
comparison involving utxo['txid'], parent_transaction and tx_children in the
transaction-package loop and replace the identity check with an equality check.
| # Check that each result is present, with the correct size and fees | ||
| for package_txn in package_txns: | ||
| tx = package_txn["tx"] | ||
| assert tx.hash in submitpackage_result["tx-results"] | ||
| tx_result = submitpackage_result["tx-results"][tx.hash] | ||
| assert_equal(tx_result, { | ||
| "txid": package_txn["txid"], | ||
| "size": tx.get_vsize(), | ||
| "fees": { | ||
| "base": DEFAULT_FEE, | ||
| } | ||
| }) | ||
|
|
||
| # submitpackage result should be consistent with testmempoolaccept and getmempoolentry | ||
| self.assert_equal_package_results(node, testmempoolaccept_result, submitpackage_result) | ||
|
|
||
| # Package feerate is calculated for the remaining transactions after deduplication and | ||
| # individual submission. If only 0 or 1 transaction is left, e.g. because all transactions | ||
| # had high-feerates or were already in the mempool, no package feerate is provided. | ||
| # In this case, since all of the parents have high fees, each is accepted individually. | ||
| assert "package-feerate" not in submitpackage_result | ||
|
|
||
| # The node should announce each transaction. No guarantees for propagation. | ||
| self.bump_mocktime(30) | ||
| peer.wait_for_broadcast([tx["tx"].hash for tx in package_txns]) | ||
| self.generate(node, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use txid strings instead of tx.hash for result lookups and broadcast wait
There are two issues here:
-
submitpackage_result["tx-results"]is keyed by txid strings, buttx.hashis an internal integer. The membership check and lookup will fail. -
P2PTxInvStore.wait_for_broadcastexpects hex txid strings and callsint(tx, 16)on each element. Passing integer hashes will raise aTypeError.
Proposed fix
# Check that each result is present, with the correct size and fees
for package_txn in package_txns:
tx = package_txn["tx"]
- assert tx.hash in submitpackage_result["tx-results"]
- tx_result = submitpackage_result["tx-results"][tx.hash]
+ assert package_txn["txid"] in submitpackage_result["tx-results"]
+ tx_result = submitpackage_result["tx-results"][package_txn["txid"]]
assert_equal(tx_result, {
"txid": package_txn["txid"],
"size": tx.get_vsize(),
@@ -289,7 +289,7 @@
# The node should announce each transaction. No guarantees for propagation.
self.bump_mocktime(30)
- peer.wait_for_broadcast([tx["tx"].hash for tx in package_txns])
+ peer.wait_for_broadcast([tx["txid"] for tx in package_txns])
self.generate(node, 1)🤖 Prompt for AI Agents
In @test/functional/rpc_packages.py around lines 268 - 293, The code incorrectly
uses the internal integer tx.hash for lookups and broadcast waits; change the
membership check, lookup key, and the list passed to peer.wait_for_broadcast to
use the txid hex string (e.g. package_txn["txid"] or tx.get_txid()/txid string
from the package_txn dict) instead of tx.hash or integer hashes so
submitpackage_result["tx-results"] lookups succeed and
P2PTxInvStore.wait_for_broadcast receives hex txid strings.
| submitpackage_result = node.submitpackage([tx["hex"] for tx in package_txns]) | ||
|
|
||
| rich_parent_result = submitpackage_result["tx-results"][tx_rich["txid"]] | ||
| poor_parent_result = submitpackage_result["tx-results"][tx_poor["txid"]] | ||
| child_result = submitpackage_result["tx-results"][tx_child["tx"].hash] | ||
| assert_equal(rich_parent_result["fees"]["base"], DEFAULT_FEE) | ||
| assert_equal(poor_parent_result["fees"]["base"], 0) | ||
| assert_equal(child_result["fees"]["base"], DEFAULT_FEE) | ||
| # Package feerate is calculated for the remaining transactions after deduplication and | ||
| # individual submission. Since this package had a 0-fee parent, package feerate must have | ||
| # been used and returned. | ||
| assert "package-feerate" in submitpackage_result | ||
| assert_fee_amount(DEFAULT_FEE, rich_parent_result["size"] + child_result["size"], submitpackage_result["package-feerate"]) | ||
|
|
||
| # The node will broadcast each transaction, still abiding by its peer's fee filter | ||
| self.bump_mocktime(30) | ||
| peer.wait_for_broadcast([tx["tx"].hash for tx in package_txns]) | ||
| self.generate(node, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same tx.hash vs txid issue in CPFP test
The child result lookup uses tx_child["tx"].hash (integer) instead of tx_child["txid"] (string), and wait_for_broadcast receives integer hashes instead of txid strings.
Proposed fix
submitpackage_result = node.submitpackage([tx["hex"] for tx in package_txns])
rich_parent_result = submitpackage_result["tx-results"][tx_rich["txid"]]
poor_parent_result = submitpackage_result["tx-results"][tx_poor["txid"]]
- child_result = submitpackage_result["tx-results"][tx_child["tx"].hash]
+ child_result = submitpackage_result["tx-results"][tx_child["txid"]]
assert_equal(rich_parent_result["fees"]["base"], DEFAULT_FEE)
@@ -319,7 +319,7 @@
# The node will broadcast each transaction, still abiding by its peer's fee filter
self.bump_mocktime(30)
- peer.wait_for_broadcast([tx["tx"].hash for tx in package_txns])
+ peer.wait_for_broadcast([tx["txid"] for tx in package_txns])
self.generate(node, 1)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| submitpackage_result = node.submitpackage([tx["hex"] for tx in package_txns]) | |
| rich_parent_result = submitpackage_result["tx-results"][tx_rich["txid"]] | |
| poor_parent_result = submitpackage_result["tx-results"][tx_poor["txid"]] | |
| child_result = submitpackage_result["tx-results"][tx_child["tx"].hash] | |
| assert_equal(rich_parent_result["fees"]["base"], DEFAULT_FEE) | |
| assert_equal(poor_parent_result["fees"]["base"], 0) | |
| assert_equal(child_result["fees"]["base"], DEFAULT_FEE) | |
| # Package feerate is calculated for the remaining transactions after deduplication and | |
| # individual submission. Since this package had a 0-fee parent, package feerate must have | |
| # been used and returned. | |
| assert "package-feerate" in submitpackage_result | |
| assert_fee_amount(DEFAULT_FEE, rich_parent_result["size"] + child_result["size"], submitpackage_result["package-feerate"]) | |
| # The node will broadcast each transaction, still abiding by its peer's fee filter | |
| self.bump_mocktime(30) | |
| peer.wait_for_broadcast([tx["tx"].hash for tx in package_txns]) | |
| self.generate(node, 1) | |
| submitpackage_result = node.submitpackage([tx["hex"] for tx in package_txns]) | |
| rich_parent_result = submitpackage_result["tx-results"][tx_rich["txid"]] | |
| poor_parent_result = submitpackage_result["tx-results"][tx_poor["txid"]] | |
| child_result = submitpackage_result["tx-results"][tx_child["txid"]] | |
| assert_equal(rich_parent_result["fees"]["base"], DEFAULT_FEE) | |
| assert_equal(poor_parent_result["fees"]["base"], 0) | |
| assert_equal(child_result["fees"]["base"], DEFAULT_FEE) | |
| # Package feerate is calculated for the remaining transactions after deduplication and | |
| # individual submission. Since this package had a 0-fee parent, package feerate must have | |
| # been used and returned. | |
| assert "package-feerate" in submitpackage_result | |
| assert_fee_amount(DEFAULT_FEE, rich_parent_result["size"] + child_result["size"], submitpackage_result["package-feerate"]) | |
| # The node will broadcast each transaction, still abiding by its peer's fee filter | |
| self.bump_mocktime(30) | |
| peer.wait_for_broadcast([tx["txid"] for tx in package_txns]) | |
| self.generate(node, 1) |
🤖 Prompt for AI Agents
In @test/functional/rpc_packages.py around lines 306 - 323, The child
transaction lookup and broadcast checks use integer .hash values instead of txid
strings; update the child_result lookup to use tx_child["txid"] when indexing
submitpackage_result["tx-results"] (matching
rich_parent_result/poor_parent_result usage) and pass the list of txid strings
(e.g., [tx["txid"] for tx in package_txns]) to peer.wait_for_broadcast so it
expects txid strings rather than integer hashes.
|
This pull request has conflicts, please rebase. |
…r descriptor wallets 0582932 test: add test for fast rescan using block filters (top-up detection) (Sebastian Falbesoner) ca48a46 rpc: doc: mention rescan speedup using `blockfilterindex=1` in affected wallet RPCs (Sebastian Falbesoner) 3449880 wallet: fast rescan: show log message for every non-skipped block (Sebastian Falbesoner) 935c6c4 wallet: take use of `FastWalletRescanFilter` (Sebastian Falbesoner) 70b3513 wallet: add `FastWalletRescanFilter` class for speeding up rescans (Sebastian Falbesoner) c051026 wallet: add method for retrieving the end range for a ScriptPubKeyMan (Sebastian Falbesoner) 8452791 wallet: support fetching scriptPubKeys with minimum descriptor range index (Sebastian Falbesoner) 088e38d add chain interface methods for using BIP 157 block filters (Sebastian Falbesoner) Pull request description: ## Description This PR is another take of using BIP 157 block filters (enabled by `-blockfilterindex=1`) for faster wallet rescans and is a modern revival of bitcoin#15845. For reviewers new to this topic I can highly recommend to read the corresponding PR review club (https://bitcoincore.reviews/15845). The basic idea is to skip blocks for deeper inspection (i.e. looking at every single tx for matches) if our block filter doesn't match any of the block's spent or created UTXOs are relevant for our wallet. Note that there can be false-positives (see https://bitcoincore.reviews/15845#l-199 for a PR review club discussion about false-positive rates), but no false-negatives, i.e. it is safe to skip blocks if the filter doesn't match; if the filter *does* match even though there are no wallet-relevant txs in the block, no harm is done, only a little more time is spent extra. In contrast to bitcoin#15845, this solution only supports descriptor wallets, which are way more widespread now than back in the time >3 years ago. With that approach, we don't have to ever derive the relevant scriptPubKeys ourselves from keys before populating the filter, and can instead shift the full responsibility to that to the `DescriptorScriptPubKeyMan` which already takes care of that automatically. Compared to legacy wallets, the `IsMine` logic for descriptor wallets is as trivial as checking if a scriptPubKey is included in the ScriptPubKeyMan's set of scriptPubKeys (`m_map_script_pub_keys`): https://github.com/bitcoin/bitcoin/blob/e191fac4f3c37820f0618f72f0a8e8b524531ab8/src/wallet/scriptpubkeyman.cpp#L1703-L1710 One of the unaddressed issues of bitcoin#15845 was that [the filter was only created once outside the loop](bitcoin#15845 (comment)) and as such didn't take into account possible top-ups that have happened. This is solved here by keeping a state of ranged `DescriptorScriptPubKeyMan`'s descriptor end ranges and check at each iteration whether that range has increased since last time. If yes, we update the filter with all scriptPubKeys that have been added since the last filter update with a range index equal or higher than the last end range. Note that finding new scriptPubKeys could be made more efficient than linearly iterating through the whole `m_script_pub_keys` map (e.g. by introducing a bidirectional map), but this would mean introducing additional complexity and state and it's probably not worth it at this time, considering that the performance gain is already significant. Output scripts from non-ranged `DescriptorScriptPubKeyMan`s (i.e. ones with a fixed set of output scripts that is never extended) are added only once when the filter is created first. ## Benchmark results Obviously, the speed-up indirectly correlates with the wallet tx frequency in the scanned range: the more blocks contain wallet-related transactions, the less blocks can be skipped due to block filter detection. In a [simple benchmark](https://github.com/theStack/bitcoin/blob/fast_rescan_functional_test_benchmark/test/functional/pr25957_benchmark.py), a regtest chain with 1008 blocks (corresponding to 1 week) is mined with 20000 scriptPubKeys contained (25 txs * 800 outputs) each. The blocks each have a weight of ~2500000 WUs and hence are about 62.5% full. A global constant `WALLET_TX_BLOCK_FREQUENCY` defines how often wallet-related txs are included in a block. The created descriptor wallet (default setting of `keypool=1000`, we have 8*1000 = 8000 scriptPubKeys at the start) is backuped via the `backupwallet` RPC before the mining starts and imported via `restorewallet` RPC after. The measured time for taking this import process (which involves a rescan) once with block filters (`-blockfilterindex=1`) and once without block filters (`-blockfilterindex=0`) yield the relevant result numbers for the benchmark. The following table lists the results, sorted from worst-case (all blocks contain wallte-relevant txs, 0% can be skipped) to best-case (no blocks contain walltet-relevant txs, 100% can be skipped) where the frequencies have been picked arbitrarily: wallet-related tx frequency; 1 tx per... | ratio of irrelevant blocks | w/o filters | with filters | speed gain --------------------------------------------|-----------------------------|-------------|--------------|------------- ~ 10 minutes (every block) | 0% | 56.806s | 63.554s | ~0.9x ~ 20 minutes (every 2nd block) | 50% (1/2) | 58.896s | 36.076s | ~1.6x ~ 30 minutes (every 3rd block) | 66.67% (2/3) | 56.781s | 25.430s | ~2.2x ~ 1 hour (every 6th block) | 83.33% (5/6) | 58.193s | 15.786s | ~3.7x ~ 6 hours (every 36th block) | 97.22% (35/36) | 57.500s | 6.935s | ~8.3x ~ 1 day (every 144th block) | 99.31% (143/144) | 68.881s | 6.107s | ~11.3x (no txs) | 100% | 58.529s | 5.630s | ~10.4x Since even the (rather unrealistic) worst-case scenario of having wallet-related txs in _every_ block of the rescan range obviously doesn't take significantly longer, I'd argue it's reasonable to always take advantage of block filters if they are available and there's no need to provide an option for the user. Feedback about the general approach (but also about details like naming, where I struggled a lot) would be greatly appreciated. Thanks fly out to furszy for discussing this subject and patiently answering basic question about descriptor wallets! ACKs for top commit: achow101: ACK 0582932 Sjors: re-utACK 0582932 aureleoules: ACK 0582932 - minor changes, documentation and updated test since last review w0xlt: re-ACK bitcoin@0582932 Tree-SHA512: 3289ba6e4572726e915d19f3e8b251d12a4cec8c96d041589956c484b5575e3708b14f6e1e121b05fe98aff1c8724de4564a5a9123f876967d33343cbef242e1
…llet rescan) 7832883 doc: add release note for bitcoin#25957 (fast wallet rescan) (Sebastian Falbesoner) Pull request description: This PR adds a missing release note for bitcoin#25957. ACKs for top commit: Sjors: ACK 7832883 Tree-SHA512: 817aa3d27b3f839de3975ace7c8ec59bcc4dbe4b5628bf64153e503cd143599d8923bd7e181ad5b196dacf1a9078347825bc40d4de5c6e2df9ed12e752217094
…mework BACKPORT NOTE: missing changes are in: - src/bench/addrman.cpp - src/bench/verify_script.cpp - src/bench/chacha_poly_aead.cpp - src/bench/descriptors.cpp - src/bench/chacha20.cpp - src/bench/crypto_hash.cpp But backport is not partial because adding these files without these changes will cause compilation error 3e9d0be build: only run high priority benchmarks in 'make check' (furszy) 466b54b bench: surround main() execution with try/catch (furszy) 3da7cd2 bench: explicitly make all current benchmarks "high" priority (furszy) 05b8c76 bench: add "priority level" to the benchmark framework (furszy) f159378 bench: place benchmark implementation inside benchmark namespace (furszy) Pull request description: This is from today's meeting, a simple "priority level" for the benchmark framework. Will allow us to run certain benchmarks while skip non-prioritized ones in `make check`. By default, `bench_bitcoin` will run all the benchmarks. `make check`will only run the high priority ones, and have marked all the existent benchmarks as "high priority" to retain the current behavior. Could test it by modifying any benchmark priority to something different from "high", and run `bench_bitcoin -priority-level=high` and/or `bench_bitcoin -priority-level=medium,low` (the first command will skip the modified bench while the second one will include it). Note: the second commit could be avoided by having a default arg value for the priority level but.. an explicit set in every `BENCHMARK` macro call makes it less error-prone. ACKs for top commit: kouloumos: re-ACK 3e9d0be achow101: ACK 3e9d0be theStack: re-ACK 3e9d0be stickies-v: re-ACK bitcoin@3e9d0be Tree-SHA512: ece59bf424c5fc1db335f84caa507476fb8ad8c6151880f1f8289562e17023aae5b5e7de03e8cbba6337bf09215f9be331e9ef51c791c43bce43f7446813b054 fixup bench
…cOS native" task da16893 ci: Use `macos-ventura-xcode:14.1` image for "macOS native" task (Hennadii Stepanov) 7028365 ci: Make `getopt` path architecture agnostic (Hennadii Stepanov) Pull request description: The "macOS native" CI task always uses the recent OS image. This PR updates it up to the recent macOS release. Cirrus Labs [stopped](bitcoin#25160 (comment)) updating macOS images for `x86_64`, therefore, an `arm64` image been used. Also `make test-security-check` has been dropped as it ["isn't even expected to pass"](bitcoin#26386 (comment)) on `arm64` in CI. ACKs for top commit: Sjors: utACK da16893 Tree-SHA512: 36785d33b7f11b3cdbc53bcfbf97d88bf821fad248c825982dd9f8e3413809a4ef11190eaf950e60fdf479b62ff66920c35d9ea42d534723f015742eec7e19b6
…tions, sinceblock}` response eb679a7 rpc: make `address` field optional (w0xlt) Pull request description: Close bitcoin#26338. This PR makes optional the `address` field in the response of `listtransactions` and `listsinceblock` RPC. And adds two tests that fail on master, but not on this branch. ACKs for top commit: achow101: ACK eb679a7 aureleoules: ACK eb679a7 Tree-SHA512: b267439626e2ec3134ae790c849949a4c40ef0cebd20092e8187be3db0a61941b2da10bbbba92ca880b8369f46c1aaa806d057eaa5159325f65cbec7cb33c52f
…ompeer.py 8a9f1e4 test: fix intermittent failure in rpc_getblockfrompeer.py (Martin Zumsande) Pull request description: Fixes an intermittent failure in `rpc_getblockfrompeer.py` observed in https://cirrus-ci.com/task/6610115527704576 by adding a sync to make sure the node has processed the header we sent it before we query it for the corresponding block. Fixes bitcoin#26412 ACKs for top commit: jonatack: ACK 8a9f1e4 Tree-SHA512: f6188ab3cfd863034e44e9806d0d99a8781462bec94141501aefc71589153481ffb144e126326ab81807c2b2c93de7f4aac5d09dbcf26c4512a176e06fc6e5f8
0f38524 doc: correct deriveaddresses RPC name (Bitcoin Hodler) Pull request description: There never was a `deriveaddress` RPC, from what I can tell. It was always called `deriveaddresses` (plural). ACKs for top commit: theStack: ACK 0f38524 Zero-1729: ACK 0f38524 Tree-SHA512: 3f405f5479a0d39cf150fd80b4d854ffe4eef718a358202c619e34a08d98c1252b82fc70d106cdf2215dc5a50c6f6cd5e26fe7ed87156f6b08f8e97d963affb7
3a0b352 refactor: move url.h/cpp from lib util to lib common (fanquake) 058eb69 build: add missing event cflags to libbitcoin_util (fanquake) Pull request description: Move `util/url` to `common/url`. Also add missing `event_*` flags to `libbitcoin_util`. bitcoin#26293 + the commit dropping boost cppflags from `libbitcoin_util` shows this issue. i.e: ```bash CXX util/libbitcoin_util_a-url.o util/url.cpp:7:10: fatal error: 'event2/http.h' file not found #include <event2/http.h> ^~~~~~~~~~~~~~~ 1 error generated. ``` ACKs for top commit: hebasto: ACK 3a0b352 ryanofsky: Code review ACK 3a0b352 Tree-SHA512: 600a76fd334267a02d332df9b67891a38d3fd7f5baf8a82b2447879b3bc65eab2552d2c081c0a5f1ec927bf80df7fc1f0cbbdda4cb76994b46dadf260b8e1cb3
e866f0d [functional test] submitrawpackage RPC (glozow) fa07651 [rpc] add new submitpackage RPC (glozow) Pull request description: It would be nice for LN/wallet/app devs to test out package policy, package RBF, etc., but the only interface to do so right now is through unit tests. This PR adds a `-regtest` only RPC interface so people can test by submitting raw transaction data. It is regtest-only, as it would be unsafe/confusing to create an actual mainnet interface while package relay doesn't exist. Note that the functional tests are there to ensure the RPC interface is working properly; they aren't for testing policy itself. See src/test/txpackage_tests.cpp. ACKs for top commit: t-bast: Tested ACK against eclair bitcoin@e866f0d ariard: Code Review ACK e866f0d instagibbs: code review ACK e866f0d Tree-SHA512: 824a26b10d2240e0fd85e5dd25bf499ee3dd9ba8ef4f522533998fcf767ddded9f001f7a005fe3ab07ec95e696448484e26599803e6034ed2733125c8c376c84
…_limits.py tests f2f6068 test: MiniWallet: add `send_self_transfer_chain` to create chain of txns (Andreas Kouloumos) 1d6b438 test: use MiniWallet to simplify mempool_package_limits.py tests (Andreas Kouloumos) Pull request description: While `wallet.py` includes the MiniWallet class and some helper methods, it also includes some methods that have been moved there without having any direct relation with the MiniWallet class. Specifically `make_chain`, `create_child_with_parents` and `create_raw_chain` methods that were extracted from `rpc_packages.py` at f8253d6 in order to be used on both `mempool_package_limits.py` and `rpc_packages.py`. Since that change, due to the introduction of additional methods in MiniWallet, the functionality of those methods can now be replicated with the existing MiniWallet methods and simultaneously simplify those tests by using the MiniWallet. This PR's goals are - to simplify the `mempool_package_limits.py` functional tests with usage of the MiniWallet. - to make progress towards the removal of the `make_chain`, `create_child_with_parents` and `create_raw_chain` methods of `wallet.py`. For the purpose of the aforementioned goals, a helper method `MiniWallet.send_self_transfer_chain` is introduced and method `bulk_transaction` has been integrated in `create_self_transfer*` methods using an optional `target_weight` option. ACKs for top commit: MarcoFalke: ACK f2f6068 👜 Tree-SHA512: 3ddfa0046168cbf7904ec6b1ca233b3fdd4f30db6aefae108b6d7fb69f34ef6fb2cf4fa7cef9473ce1434a0cc8149d236441a685352fef35359a2b7ba0d951eb
Otherwise this error appears:
test_framework.authproxy.JSONRPCException: min relay fee not met, 25500 < 30332 (-26)
fa2537c test: Target exact weight in MiniWallet _bulk_tx (MacroFake) Pull request description: Seems better to target the exact weight than a weight that is up to more than 2000 WU larger. Also, replace a broad `-acceptnonstdtxn=1` with `-datacarriersize=100000` to document the test assumptions better. ACKs for top commit: theStack: Code-review ACK fa2537c Tree-SHA512: cf02c3082a13195b8aa730866aeaf2575ce01974ae2b0244739d8cfc12e60c66312729ed703bb3214651744166a3b560bfaa8dc302ef46ed79fc4d1fe7fcc214
…let` 17cad44 test: refactor `RPCPackagesTest` to use `MiniWallet` (w0xlt) Pull request description: This PR refactors `RPCPackagesTest` to use `MiniWallet` and removes `create_child_with_parents`, `make_chain`, and `create_raw_chain` from `test_framework/wallet`, as requested in bitcoin#25965. Close bitcoin#25965. ACKs for top commit: glozow: ACK 17cad44 pablomartin4btc: tested ACK 17cad44; went thru all changes and recommendations from @kouloumos & @glozow; also went up to bitcoin#20833 to get a bit of background of the origin and purpose of these tests. kouloumos: ACK 17cad44 Tree-SHA512: 9228c532afaecedd577019dbc56f8749046d66f904dd69eb23e7ca3d7806e2132d90af29be276c7635fefb37ef348ae781eb3b225cd6741b20300e6f381041c3
fa6b402 test: Run mempool_packages.py with MiniWallet (MarcoFalke) fa448c2 test: Return fee from MiniWallet (MarcoFalke) faec09f test: Return chain of MiniWallet txs from MiniWallet chain method (MarcoFalke) faa12d4 test: Refactor MiniWallet sign_tx (MarcoFalke) fa2d821 test: Return wtxid from create_self_transfer_multi (MarcoFalke) Pull request description: This allows to run the test even when no wallet is compiled in. Also, it is a lot nicer to read now. ACKs for top commit: glozow: reACK fa6b402 Tree-SHA512: de0338068fd51db01d64ce270f94fd2982a63a6de597325cd1e1f11127e9075bd4aeacace0ed76d09a2db8b962b27237cf11edb4c1fe1a01134d397f8a11bd05
…subtests via decorator e669833 test: dedup package limit checks via decorator in mempool_package_limits.py (Sebastian Falbesoner) 72f25e2 test: refactor: use Satoshis for fees in mempool_package_limits.py (Sebastian Falbesoner) Pull request description: The subtests in the functional test mempool_package_limits.py all follow the same pattern: 1. first, check that the mempool is currently empty 2. create and submit certain single txs to the mempool, prepare list of hex transactions 3. check that `testmempoolaccept` on the package hex fails with a "package-mempool-limits" error on each tx result 4. after mining a block, check that submitting the package succeeds Note that steps 1,3,4 are identical for each of the subtests and only step 2 varies, so this might be a nice opportunity to deduplicate code by using a newly introduced decorator which executes the necessary before and after the essential part of the subtest. This also makes it easier to add new subtests without having to copy-paste those parts once again. In addition, the first commit switches the fee unit from BTC to Satoshis, which allows to get rid of some imports (`COIN` and `Decimal`) and a comment for the `test_desc_size_limits` subtest is fixed (s/25KvB/21KvB/). ACKs for top commit: ismaelsadeeq: ACK e669833 glozow: utACK e669833 Tree-SHA512: 84a85e739de7387391c13bd46aeb015a74302ea7c6f0ca3d4e2b1b487d38df390dc118eb5b1c11d3e4206bff316a4dab60ef6b25d8feced672345d4e36ffd205
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 5
🤖 Fix all issues with AI agents
In @src/rpc/mempool.cpp:
- Around line 861-870: The variable num_submitted is declared inside the loop in
the transaction broadcast block and never incremented, so the error message
always reports 0; move the declaration of num_submitted outside the for loop (so
it accumulates across iterations), increment it whenever
BroadcastTransaction(node, tx, ...) returns TransactionError::OK, and then use
that accumulated num_submitted in the JSONRPCTransactionError message; update
references around BroadcastTransaction and the surrounding loop to ensure
num_submitted reflects the count of successfully broadcast transactions.
In @test/functional/mempool_packages.py:
- Around line 223-239: The loop that builds chained child transactions
incorrectly uses identity comparison when checking utxo['txid'] is
parent_transaction, which can miss matches; update that conditional in the
for-loop (where utxo, parent_transaction, tx_children, chain and
transaction_package are used) to use equality (==) instead of is so string txid
comparisons correctly detect children and populate tx_children for downstream
descendant/spentby checks.
In @test/functional/rpc_packages.py:
- Around line 295-323: In test_submit_cpfp, the child transaction is being
referenced by tx_child["tx"].hash and peer.wait_for_broadcast is given integer
hashes, but submitpackage_result["tx-results"] and P2PTxInvStore expect txid
strings; change the child lookup to use tx_child["txid"] (matching
rich_parent_result/poor_parent_result) and call peer.wait_for_broadcast with the
list [tx["txid"] for tx in package_txns] so both the submitpackage_result access
and the broadcast check consistently use txid strings.
- Around line 234-293: The test uses internal integer tx.hash values where
submitpackage_result and P2PTxInvStore expect hex txid strings; update all
lookups and waits in test_submit_child_with_parents to use the
package_txn["txid"] string (e.g., when asserting membership in
submitpackage_result["tx-results"], when fetching tx_result, and when calling
peer.wait_for_broadcast) instead of tx.hash; ensure any places that compare or
index by txid use the same string key from package_txn["txid"] so
submitpackage_result lookups and broadcast waits use the correct hex txid type.
In @test/functional/wallet_fast_rescan.py:
- Line 52: The log call uses an unnecessary f-string prefix in the message
inside the self.log.info call; remove the leading 'f' so the string becomes a
normal literal in the self.log.info(...) invocation (locate the call to
self.log.info that currently reads f"Create txs sending to end range address of
each descriptor, triggering top-ups" and change it to a plain string without the
f prefix).
🧹 Nitpick comments (1)
test/functional/wallet_fast_rescan.py (1)
23-50: Replaceprint()withself.log.debug()for consistent logging.Line 47 uses
print()to output the result ofimportdescriptors, which should use the test framework's logging instead.Proposed fix
- print(w.importdescriptors([{"desc": descsum_create(f"wpkh({fixed_key.privkey})"), "timestamp": "now"}])) + self.log.debug(w.importdescriptors([{"desc": descsum_create(f"wpkh({fixed_key.privkey})"), "timestamp": "now"}]))
📜 Review details
Configuration used: Repository UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (82)
ci/dash/lint-tidy.shci/test/00_setup_env_mac_native_arm64.shci/test/04_install.shdoc/descriptors.mddoc/release-notes-25957.mdsrc/Makefile.amsrc/bench/addrman.cppsrc/bench/base58.cppsrc/bench/bech32.cppsrc/bench/bench.hsrc/bench/bip324_ecdh.cppsrc/bench/block_assemble.cppsrc/bench/bls.cppsrc/bench/bls_dkg.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/ccoins_caching.cppsrc/bench/chacha20.cppsrc/bench/checkblock.cppsrc/bench/checkqueue.cppsrc/bench/coin_selection.cppsrc/bench/crypto_hash.cppsrc/bench/duplicate_inputs.cppsrc/bench/ecdsa.cppsrc/bench/ellswift.cppsrc/bench/examples.cppsrc/bench/gcs_filter.cppsrc/bench/hashpadding.cppsrc/bench/load_external.cppsrc/bench/lockedpool.cppsrc/bench/logging.cppsrc/bench/mempool_eviction.cppsrc/bench/mempool_stress.cppsrc/bench/merkle_root.cppsrc/bench/peer_eviction.cppsrc/bench/poly1305.cppsrc/bench/pool.cppsrc/bench/pow_hash.cppsrc/bench/prevector.cppsrc/bench/rollingbloom.cppsrc/bench/rpc_blockchain.cppsrc/bench/rpc_mempool.cppsrc/bench/strencodings.cppsrc/bench/string_cast.cppsrc/bench/util_time.cppsrc/bench/verify_script.cppsrc/bench/wallet_balance.cppsrc/bench/wallet_create.cppsrc/bench/wallet_loading.cppsrc/bitcoin-cli.cppsrc/bitcoin-wallet.cppsrc/bitcoind.cppsrc/common/url.cppsrc/common/url.hsrc/interfaces/chain.hsrc/logging.cppsrc/logging.hsrc/node/interfaces.cppsrc/qt/main.cppsrc/rpc/client.cppsrc/rpc/mempool.cppsrc/test/fuzz/rpc.cppsrc/test/fuzz/string.cppsrc/test/util/setup_common.cppsrc/util/error.cppsrc/util/error.hsrc/wallet/rpc/backup.cppsrc/wallet/rpc/transactions.cppsrc/wallet/rpc/util.cppsrc/wallet/rpc/wallet.cppsrc/wallet/scriptpubkeyman.cppsrc/wallet/scriptpubkeyman.hsrc/wallet/wallet.cpptest/functional/mempool_package_limits.pytest/functional/mempool_packages.pytest/functional/rpc_getblockfrompeer.pytest/functional/rpc_packages.pytest/functional/test_framework/util.pytest/functional/test_framework/wallet.pytest/functional/test_runner.pytest/functional/wallet_fast_rescan.pytest/functional/wallet_listsinceblock.pytest/functional/wallet_listtransactions.py
💤 Files with no reviewable changes (1)
- test/functional/test_framework/util.py
✅ Files skipped from review due to trivial changes (1)
- doc/descriptors.md
🚧 Files skipped from review as they are similar to previous changes (35)
- doc/release-notes-25957.md
- src/wallet/scriptpubkeyman.cpp
- src/qt/main.cpp
- src/bench/util_time.cpp
- src/bench/lockedpool.cpp
- src/bitcoin-wallet.cpp
- ci/dash/lint-tidy.sh
- src/bench/poly1305.cpp
- src/bench/rpc_blockchain.cpp
- src/wallet/rpc/backup.cpp
- src/bench/strencodings.cpp
- src/common/url.h
- src/logging.h
- src/util/error.cpp
- src/wallet/rpc/wallet.cpp
- src/bench/chacha20.cpp
- src/bench/ellswift.cpp
- src/bench/bls.cpp
- src/bench/block_assemble.cpp
- src/bench/verify_script.cpp
- src/bench/checkqueue.cpp
- src/bench/examples.cpp
- src/bench/checkblock.cpp
- src/bench/rollingbloom.cpp
- src/bench/pool.cpp
- src/bench/addrman.cpp
- src/test/fuzz/rpc.cpp
- ci/test/04_install.sh
- src/bitcoind.cpp
- src/bitcoin-cli.cpp
- src/bench/duplicate_inputs.cpp
- src/logging.cpp
- src/wallet/rpc/util.cpp
- src/bench/hashpadding.cpp
- test/functional/test_runner.py
🧰 Additional context used
📓 Path-based instructions (7)
src/**/*.{cpp,h,hpp,cc}
📄 CodeRabbit inference engine (CLAUDE.md)
Dash Core implementation must be written in C++20, requiring at least Clang 16 or GCC 11.1
Files:
src/bench/rpc_mempool.cppsrc/bench/bench.hsrc/util/error.hsrc/bench/coin_selection.cppsrc/bench/mempool_stress.cppsrc/wallet/scriptpubkeyman.hsrc/bench/load_external.cppsrc/interfaces/chain.hsrc/bench/base58.cppsrc/bench/ccoins_caching.cppsrc/bench/gcs_filter.cppsrc/wallet/wallet.cppsrc/bench/string_cast.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/bech32.cppsrc/test/fuzz/string.cppsrc/common/url.cppsrc/rpc/mempool.cppsrc/bench/bip324_ecdh.cppsrc/bench/wallet_create.cppsrc/bench/logging.cppsrc/bench/ecdsa.cppsrc/bench/crypto_hash.cppsrc/test/util/setup_common.cppsrc/rpc/client.cppsrc/bench/wallet_loading.cppsrc/bench/wallet_balance.cppsrc/bench/prevector.cppsrc/wallet/rpc/transactions.cppsrc/bench/bls_dkg.cppsrc/bench/merkle_root.cppsrc/bench/mempool_eviction.cppsrc/bench/pow_hash.cppsrc/bench/peer_eviction.cppsrc/node/interfaces.cpp
src/bench/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
Performance benchmarks in src/bench/ must use the nanobench library
Files:
src/bench/rpc_mempool.cppsrc/bench/bench.hsrc/bench/coin_selection.cppsrc/bench/mempool_stress.cppsrc/bench/load_external.cppsrc/bench/base58.cppsrc/bench/ccoins_caching.cppsrc/bench/gcs_filter.cppsrc/bench/string_cast.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/bech32.cppsrc/bench/bip324_ecdh.cppsrc/bench/wallet_create.cppsrc/bench/logging.cppsrc/bench/ecdsa.cppsrc/bench/crypto_hash.cppsrc/bench/wallet_loading.cppsrc/bench/wallet_balance.cppsrc/bench/prevector.cppsrc/bench/bls_dkg.cppsrc/bench/merkle_root.cppsrc/bench/mempool_eviction.cppsrc/bench/pow_hash.cppsrc/bench/peer_eviction.cpp
src/wallet/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
Wallet implementation must use Berkeley DB and SQLite
Files:
src/wallet/scriptpubkeyman.hsrc/wallet/wallet.cppsrc/wallet/rpc/transactions.cpp
{guix-build*,releases,**/guix-build*,releases/**,.github/**,depends/**,ci/**,contrib/**,doc/**}
📄 CodeRabbit inference engine (CLAUDE.md)
Do not make changes to build system files (guix-build*), release artifacts, or avoid changes to .github, depends, ci, contrib, and doc directories unless specifically prompted
Files:
ci/test/00_setup_env_mac_native_arm64.sh
test/functional/**/*.py
📄 CodeRabbit inference engine (CLAUDE.md)
Functional tests in test/functional/ must be written in Python (minimum version specified in .python-version) and depend on dashd and dash-node
Files:
test/functional/wallet_fast_rescan.pytest/functional/test_framework/wallet.pytest/functional/rpc_packages.pytest/functional/mempool_packages.pytest/functional/rpc_getblockfrompeer.pytest/functional/mempool_package_limits.pytest/functional/wallet_listsinceblock.pytest/functional/wallet_listtransactions.py
src/{test,wallet/test}/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework
Files:
src/test/fuzz/string.cppsrc/test/util/setup_common.cpp
src/node/**/*.{cpp,h}
📄 CodeRabbit inference engine (CLAUDE.md)
NodeContext must be extended with Dash-specific managers for each subsystem during initialization
Files:
src/node/interfaces.cpp
🧠 Learnings (27)
📓 Common learnings
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Learnt from: knst
Repo: dashpay/dash PR: 6916
File: src/univalue/include/univalue.h:81-88
Timestamp: 2025-10-25T07:08:51.918Z
Learning: For backport PRs from bitcoin/bitcoin, bitcoin-core/gui, etc., backported changes should match the original upstream PRs even if they appear strange, modify vendored code, or seem to violate coding guidelines. Still flag genuine issues like bugs, undefined behavior, crashes, compilation errors, or linter failures.
Learnt from: knst
Repo: dashpay/dash PR: 6883
File: src/rpc/rawtransaction.cpp:1088-1125
Timestamp: 2025-10-13T12:37:12.357Z
Learning: In backport pull requests (especially from Bitcoin Core), treat "moved" or refactored code as out-of-scope for content-level review. Focus validation on verifying that code is moved correctly: no fields added, no fields removed, no fields reordered, and no unexpected changes beyond whitespace adjustments. Pre-existing issues in the upstream code should be preserved to maintain fidelity to the original implementation.
Learnt from: knst
Repo: dashpay/dash PR: 6871
File: contrib/guix/libexec/build.sh:358-360
Timestamp: 2025-10-05T20:38:28.457Z
Learning: In the Dash repository, when backporting code from Bitcoin Core, typos and minor issues in comments should be kept as-is to reduce merge conflicts in future backports, even if they remain unfixed in Bitcoin Core's master branch.
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6786
File: ci/test/04_install.sh:99-101
Timestamp: 2025-08-01T07:46:37.840Z
Learning: In backport PRs like #6786, UdjinM6 prefers to defer non-critical fixes (such as shell command expansion issues) to separate commits/PRs to maintain focus on the primary backport objectives, consistent with the project's pattern of avoiding scope creep.
Learnt from: PastaPastaPasta
Repo: dashpay/dash PR: 6804
File: src/qt/proposalwizard.cpp:40-42
Timestamp: 2025-08-11T17:16:36.654Z
Learning: In the Dash repository, when a PR adds new files that are not from Bitcoin backports, these files must be added to the list in test/util/data/non-backported.txt. This applies to newly created files like qt/proposalwizard.{h,cpp} and forms/proposalwizard.ui. Limited exemptions may exist for subtrees and similar cases.
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay
Learnt from: knst
Repo: dashpay/dash PR: 6805
File: src/wallet/rpc/wallet.cpp:357-357
Timestamp: 2025-08-08T07:01:47.332Z
Learning: In src/wallet/rpc/wallet.cpp, the upgradetohd RPC now returns a UniValue string message (RPCResult::Type::STR) instead of a boolean, including guidance about mnemonic backup and null-character passphrase handling; functional tests have been updated to assert returned strings in several cases.
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/bench/**/*.{cpp,h} : Performance benchmarks in src/bench/ must use the nanobench library
Applied to files:
src/bench/rpc_mempool.cppsrc/bench/bench.hsrc/bench/coin_selection.cppsrc/bench/mempool_stress.cppsrc/bench/load_external.cppsrc/bench/base58.cppsrc/bench/ccoins_caching.cppsrc/bench/gcs_filter.cppsrc/bench/string_cast.cppsrc/bench/bls_pubkey_agg.cppsrc/bench/bech32.cppsrc/bench/logging.cppsrc/bench/ecdsa.cppsrc/bench/crypto_hash.cppsrc/bench/wallet_loading.cppsrc/bench/wallet_balance.cppsrc/bench/prevector.cppsrc/bench/merkle_root.cppsrc/bench/mempool_eviction.cppsrc/bench/pow_hash.cppsrc/bench/peer_eviction.cpp
📚 Learning: 2025-12-22T15:42:48.595Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7068
File: src/qt/guiutil_font.h:68-77
Timestamp: 2025-12-22T15:42:48.595Z
Learning: In C++/Qt codebases, use fail-fast asserts in setters to enforce invariants (e.g., ensuring internal maps contain necessary keys). Prefer assert() for programmer errors that should be caught in development and debugging, rather than defensive runtime checks with fallbacks. This helps catch invariant violations early during development. Apply to header and source files where invariant-driven state mutations occur, especially in setters like SetWeightBold/SetWeightNormal that assume established relationships or preconditions.
Applied to files:
src/bench/bench.hsrc/util/error.hsrc/wallet/scriptpubkeyman.hsrc/interfaces/chain.h
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/coinjoin/**/*.{cpp,h} : CoinJoin implementation must use masternode-coordinated mixing sessions with uniform denomination outputs
Applied to files:
src/bench/coin_selection.cppsrc/wallet/wallet.cppsrc/node/interfaces.cpp
📚 Learning: 2025-01-02T08:33:26.751Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6516
File: ci/test/00_setup_env_mac.sh:11-11
Timestamp: 2025-01-02T08:33:26.751Z
Learning: The removal of DMG support in the macOS packaging process eliminates the need for python-based scripts or python3-setuptools in the build environment. The PACKAGES variable in ci/test/00_setup_env_mac.sh is vestigial due to the use of a general-purpose Docker container defined in contrib/containers/ci/Dockerfile.
Applied to files:
ci/test/00_setup_env_mac_native_arm64.sh
📚 Learning: 2025-07-23T09:30:34.631Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6761
File: src/chainlock/signing.h:5-6
Timestamp: 2025-07-23T09:30:34.631Z
Learning: Dash Core uses BITCOIN_ prefix for header guards as the standard convention, inherited from Bitcoin Core. Only a few BLS-specific files in src/bls/ use DASH_ prefix. The vast majority of files (385+) use BITCOIN_ prefix.
Applied to files:
src/Makefile.amsrc/bench/crypto_hash.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Dash extends Bitcoin Core through composition with minimal changes to the Bitcoin Core foundation
Applied to files:
src/Makefile.am
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,txmempool}/**/*.{cpp,h} : Block validation and mempool handling must use extensions to Bitcoin Core mechanisms for special transaction validation and enhanced transaction relay
Applied to files:
src/interfaces/chain.hsrc/wallet/wallet.cpptest/functional/mempool_packages.pysrc/rpc/mempool.cppsrc/wallet/rpc/transactions.cppsrc/node/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{validation,consensus,net_processing}/**/*.{cpp,h} : ValidationInterface callbacks must be used for event-driven architecture to coordinate subsystems during block/transaction processing
Applied to files:
src/interfaces/chain.hsrc/rpc/mempool.cppsrc/node/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/node/chainstate.{cpp,h} : Chainstate initialization must be separated into dedicated src/node/chainstate.* files
Applied to files:
src/interfaces/chain.hsrc/rpc/mempool.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : ChainLocks implementation must prevent reorganizations and provide block finality through 51% attack prevention
Applied to files:
src/interfaces/chain.hsrc/rpc/mempool.cpp
📚 Learning: 2025-08-08T07:01:47.332Z
Learnt from: knst
Repo: dashpay/dash PR: 6805
File: src/wallet/rpc/wallet.cpp:357-357
Timestamp: 2025-08-08T07:01:47.332Z
Learning: In src/wallet/rpc/wallet.cpp, the upgradetohd RPC now returns a UniValue string message (RPCResult::Type::STR) instead of a boolean, including guidance about mnemonic backup and null-character passphrase handling; functional tests have been updated to assert returned strings in several cases.
Applied to files:
test/functional/rpc_packages.pytest/functional/mempool_packages.pysrc/rpc/mempool.cppsrc/rpc/client.cppsrc/bench/wallet_balance.cppsrc/wallet/rpc/transactions.cpp
📚 Learning: 2025-06-09T16:43:20.996Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6718
File: test/functional/test_framework/test_framework.py:2102-2102
Timestamp: 2025-06-09T16:43:20.996Z
Learning: In the test framework consolidation PR (#6718), user kwvg prefers to limit functional changes to those directly related to MasternodeInfo, avoiding scope creep even for minor improvements like error handling consistency.
Applied to files:
test/functional/rpc_packages.pytest/functional/mempool_packages.pytest/functional/mempool_package_limits.py
📚 Learning: 2025-12-17T13:58:26.891Z
Learnt from: kwvg
Repo: dashpay/dash PR: 7072
File: src/qt/walletcontroller.cpp:520-528
Timestamp: 2025-12-17T13:58:26.891Z
Learning: In Dash Qt wallet code, when leveraging upstream Bitcoin Core wallet capabilities (especially for operations like rescanning), prefer using the inherited signal-based mechanisms (e.g., ShowProgress signals) over adding explicit Qt progress dialogs to minimize upstream deviation and simplify future backports.
Applied to files:
src/wallet/wallet.cpp
📚 Learning: 2025-02-14T15:19:17.218Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/wallet/rpcwallet.cpp:3002-3003
Timestamp: 2025-02-14T15:19:17.218Z
Learning: The `GetWallet()` function calls in `src/wallet/rpcwallet.cpp` are properly validated with null checks that throw appropriate RPC errors, making additional validation unnecessary.
Applied to files:
src/wallet/wallet.cppsrc/wallet/rpc/transactions.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/wallet/**/*.{cpp,h} : Wallet implementation must use Berkeley DB and SQLite
Applied to files:
src/wallet/wallet.cppsrc/bench/wallet_create.cppsrc/bench/wallet_loading.cpp
📚 Learning: 2025-11-04T18:23:28.175Z
Learnt from: UdjinM6
Repo: dashpay/dash PR: 6933
File: src/governance/classes.cpp:147-154
Timestamp: 2025-11-04T18:23:28.175Z
Learning: In src/governance/classes.cpp, CSuperblock::GetPaymentsLimit intentionally uses synthetic difficulty constants (nBits = 1 for mainnet, powLimit for networks with min difficulty) and simple height-based V20 activation checks instead of actual chain block data. This is by design because superblocks themselves are "synthetic" governance payment blocks, not regular mined blocks.
Applied to files:
src/wallet/wallet.cpp
📚 Learning: 2025-06-20T23:32:16.225Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6726
File: test/functional/rpc_createmultisig.py:120-120
Timestamp: 2025-06-20T23:32:16.225Z
Learning: In the rpc_createmultisig.py test, the checkbalances() function correctly excludes 9 blocks from the balance calculation: 8 blocks from do_multisig() calls (2 blocks per call × 4 calls) plus 1 block from checkbalances() itself.
Applied to files:
test/functional/mempool_packages.py
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq}/**/*.{cpp,h} : BLS integration must be used for cryptographic foundation of advanced masternode features
Applied to files:
src/bench/bls_pubkey_agg.cppsrc/rpc/mempool.cppsrc/test/util/setup_common.cppsrc/node/interfaces.cpp
📚 Learning: 2025-02-14T15:15:58.165Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6529
File: src/rpc/governance.cpp:1074-1089
Timestamp: 2025-02-14T15:15:58.165Z
Learning: Code blocks marked with `// clang-format off` and `// clang-format on` directives should be excluded from clang-format suggestions as they are intentionally formatted manually for better readability.
Applied to files:
src/bench/bls_pubkey_agg.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,evo,llmq,governance,coinjoin}/**/*.{cpp,h} : Use Dash-specific database implementations: CFlatDB for persistent storage (MasternodeMetaStore, GovernanceStore, SporkStore, NetFulfilledRequestStore) and CDBWrapper extensions for Evolution/DKG/InstantSend/Quorum/RecoveredSigs data
Applied to files:
src/bench/crypto_hash.cppsrc/node/interfaces.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{masternode,llmq,evo,coinjoin,governance}/**/*.{cpp,h} : Use unordered_lru_cache for efficient caching with LRU eviction in Dash-specific data structures
Applied to files:
src/bench/crypto_hash.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/{test,wallet/test}/**/*.{cpp,h} : Unit tests in src/test/ and src/wallet/test/ must use Boost::Test framework
Applied to files:
src/bench/wallet_balance.cpp
📚 Learning: 2025-02-06T14:34:30.466Z
Learnt from: kwvg
Repo: dashpay/dash PR: 6543
File: src/wallet/receive.cpp:240-251
Timestamp: 2025-02-06T14:34:30.466Z
Learning: Pull request #6543 is focused on move-only changes and refactoring, specifically backporting from Bitcoin. Behavior changes should be proposed in separate PRs.
Applied to files:
src/wallet/rpc/transactions.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : LLMQ quorums must support multiple configurations (50/60, 400/60, 400/85) for different services (ChainLocks, InstantSend, governance voting)
Applied to files:
src/bench/bls_dkg.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/llmq/**/*.{cpp,h} : InstantSend implementation must provide distributed key generation for secure transaction locking with quorum consensus
Applied to files:
src/bench/bls_dkg.cpp
📚 Learning: 2025-11-24T16:41:22.457Z
Learnt from: CR
Repo: dashpay/dash PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-11-24T16:41:22.457Z
Learning: Applies to src/governance/**/*.{cpp,h} : Governance implementation must support governance objects (proposals, triggers, superblock management) and on-chain voting with tallying
Applied to files:
src/node/interfaces.cpp
🧬 Code graph analysis (7)
src/wallet/scriptpubkeyman.h (1)
src/wallet/scriptpubkeyman.cpp (6)
GetScriptPubKeys(2516-2519)GetScriptPubKeys(2516-2516)GetScriptPubKeys(2521-2531)GetScriptPubKeys(2521-2521)GetEndRange(2533-2536)GetEndRange(2533-2533)
test/functional/test_framework/wallet.py (2)
test/functional/test_framework/script.py (1)
CScript(420-593)test/functional/test_framework/util.py (1)
assert_greater_than_or_equal(82-84)
test/functional/rpc_getblockfrompeer.py (2)
test/functional/test_framework/p2p.py (1)
send_and_ping(750-752)test/functional/test_framework/messages.py (1)
msg_headers(2050-2068)
test/functional/mempool_package_limits.py (2)
test/functional/test_framework/util.py (1)
assert_equal(69-74)test/functional/test_framework/wallet.py (4)
MiniWallet(73-363)create_self_transfer(312-332)create_self_transfer_multi(257-310)sendrawtransaction(334-337)
src/node/interfaces.cpp (2)
src/wallet/wallet.cpp (2)
block_hash(319-322)block_hash(319-319)src/index/blockfilterindex.cpp (1)
filter(274-274)
test/functional/wallet_listsinceblock.py (1)
src/wallet/rpc/transactions.cpp (2)
listsinceblock(554-692)listsinceblock(554-554)
test/functional/wallet_listtransactions.py (2)
test/functional/wallet_listsinceblock.py (1)
test_op_return(404-415)src/wallet/rpc/transactions.cpp (2)
listtransactions(442-552)listtransactions(442-442)
🪛 Cppcheck (2.19.0)
src/bench/bls_pubkey_agg.cpp
[error] 95-95: failed to evaluate #if condition, undefined function-like macro invocation
(syntaxError)
src/test/util/setup_common.cpp
[error] 10-10: failed to evaluate #if condition, undefined function-like macro invocation
(syntaxError)
src/bench/peer_eviction.cpp
[error] 148-148: Buffer is accessed out of bounds
(bufferAccessOutOfBounds)
src/node/interfaces.cpp
[error] 22-22: failed to evaluate #if condition, undefined function-like macro invocation
(syntaxError)
🪛 Flake8 (7.3.0)
test/functional/wallet_fast_rescan.py
[error] 52-52: f-string is missing placeholders
(F541)
test/functional/rpc_packages.py
[error] 51-51: continuation line over-indented for hanging indent
(E126)
[error] 56-56: continuation line under-indented for hanging indent
(E121)
[error] 101-101: continuation line under-indented for visual indent
(E128)
🪛 Ruff (0.14.10)
test/functional/wallet_fast_rescan.py
52-52: f-string without any placeholders
Remove extraneous f prefix
(F541)
test/functional/test_framework/wallet.py
287-287: zip() without an explicit strict= parameter
Add explicit value for parameter strict=
(B905)
test/functional/rpc_packages.py
120-120: Consider [tx_high_fee["hex"], *self.independent_txns_hex] instead of concatenation
Replace with [tx_high_fee["hex"], *self.independent_txns_hex]
(RUF005)
197-197: Consider [*package_hex, child_tx['hex']] instead of concatenation
Replace with [*package_hex, child_tx['hex']]
(RUF005)
202-202: Consider [*package_hex, child_tx["hex"]] instead of concatenation
Replace with [*package_hex, child_tx["hex"]]
(RUF005)
245-245: Unnecessary key check before dictionary access
Replace with dict.get
(RUF019)
260-260: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
test/functional/wallet_listsinceblock.py
413-413: Prefer next(...) over single element slice
Replace with next(...)
(RUF015)
test/functional/wallet_listtransactions.py
177-177: Prefer next(...) over single element slice
Replace with next(...)
(RUF015)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (10)
- GitHub Check: Lint / Run linters
- GitHub Check: linux64_tsan-build / Build source
- GitHub Check: linux64_nowallet-build / Build source
- GitHub Check: win64-build / Build source
- GitHub Check: linux64_ubsan-build / Build source
- GitHub Check: linux64_fuzz-build / Build source
- GitHub Check: linux64_sqlite-build / Build source
- GitHub Check: linux64-build / Build source
- GitHub Check: arm-linux-build / Build source
- GitHub Check: mac-build / Build source
🔇 Additional comments (62)
test/functional/rpc_getblockfrompeer.py (1)
95-95: LGTM: Proper synchronization added to fix intermittent test failure.Replacing
send_messagewithsend_and_pingensures the header is fully processed before the test attempts to fetch the block at line 104, eliminating the race condition that caused intermittent failures.src/bench/wallet_create.cpp (1)
52-53: LGTM! Priority level correctly added to benchmark registrations.The changes correctly add
benchmark::PriorityLevel::HIGHto both wallet creation benchmarks, consistent with the PR's objective to add priority level support to the benchmark framework.src/wallet/scriptpubkeyman.h (1)
644-645: LGTM! New accessor methods for descriptor wallet fast rescan.The new
GetScriptPubKeys(int32_t minimum_index)overload andGetEndRange()method correctly extend the DescriptorScriptPubKeyMan interface to support index-aware filtering of script public keys. The declarations are const-correct, use appropriate types (int32_t matching the ScriptPubKeyMap index type), and match their implementations in scriptpubkeyman.cpp which properly handle thread safety withcs_desc_manlocking.These additions enable the fast rescan feature to efficiently query descriptor ranges when using BIP157 block filters.
src/util/error.h (1)
35-35: LGTM! Clean enum addition for package validation.The new
INVALID_PACKAGEerror type is correctly positioned and aligns with the PR's objective to add package submission support via the regtest-onlysubmitpackageRPC.src/bench/rpc_mempool.cpp (1)
42-42: LGTM! Benchmark priority registration updated correctly.The explicit priority level addition aligns with the benchmark framework enhancement in this backport.
src/bench/bip324_ecdh.cpp (1)
51-51: LGTM! Benchmark priority registration updated correctly.The explicit priority level addition aligns with the benchmark framework enhancement in this backport.
src/bench/coin_selection.cpp (1)
121-122: LGTM! Benchmark priority registrations updated correctly.Both benchmark registrations now include the explicit priority level, consistent with the framework enhancement in this backport.
src/bench/wallet_balance.cpp (1)
58-61: LGTM! Benchmark priority registrations updated correctly.All four benchmark registrations now include the explicit priority level, consistent with the framework enhancement in this backport.
src/bench/wallet_loading.cpp (2)
121-121: LGTM! Benchmark priority registration updated correctly.The explicit priority level addition for the legacy wallet loading benchmark aligns with the framework enhancement in this backport.
126-126: LGTM! Benchmark priority registration updated correctly.The explicit priority level addition for the descriptor wallet loading benchmark aligns with the framework enhancement in this backport.
src/bench/ccoins_caching.cpp (1)
53-53: LGTM! Benchmark priority level addition is correct.The addition of
benchmark::PriorityLevel::HIGHto the benchmark registration is consistent with the framework enhancement across the repository. The benchmark body remains unchanged, and this metadata allows the benchmark runner to prioritize execution appropriately.src/bench/bech32.cpp (1)
35-36: LGTM! Benchmark priority level additions are correct.Both benchmark registrations have been properly updated to include
benchmark::PriorityLevel::HIGH. The benchmark implementations remain unchanged, and the priority metadata enables selective benchmark execution in the test suite.src/bench/load_external.cpp (1)
63-63: LGTM! Benchmark priority level addition is correct.The benchmark registration has been properly updated to include the priority parameter. The benchmark logic remains unchanged, and this addition aligns with the framework enhancement for prioritized benchmark execution.
src/bench/peer_eviction.cpp (1)
144-155: LGTM! All benchmark priority level additions are correct.All six peer eviction benchmark registrations have been consistently updated to include
benchmark::PriorityLevel::HIGH. The benchmark implementations remain unchanged, and these metadata additions enable the benchmark framework to selectively run high-priority benchmarks duringmake check.src/bench/gcs_filter.cpp (1)
84-88: LGTM! All benchmark priority level additions are correct.All five GCS filter benchmark registrations have been properly updated to include
benchmark::PriorityLevel::HIGH. The benchmark implementations are unchanged, and these additions support the enhanced benchmark framework for prioritized execution.src/bench/merkle_root.cpp (1)
26-26: LGTM!The benchmark registration correctly adopts the new two-argument
BENCHMARKmacro withPriorityLevel::HIGH.src/bench/ecdsa.cpp (1)
87-89: LGTM!All three ECDSA benchmark registrations correctly updated with
PriorityLevel::HIGH. The benchmark bodies remain unchanged and continue to use the nanobench library correctly.src/bench/bls_dkg.cpp (1)
134-139: LGTM!All four BLS DKG benchmark macro definitions correctly updated to include
benchmark::PriorityLevel::HIGHin their internalBENCHMARKinvocations. The macro structure and benchmark logic remain intact.Also applies to: 152-157, 159-172, 174-187
src/bench/mempool_eviction.cpp (1)
125-125: LGTM!The mempool eviction benchmark registration correctly updated with
PriorityLevel::HIGH.src/bench/mempool_stress.cpp (1)
115-116: LGTM!Both mempool stress benchmarks (
ComplexMemPoolandMempoolCheck) correctly updated withPriorityLevel::HIGH.src/bench/base58.cpp (1)
53-55: LGTM!All three Base58 benchmarks correctly updated with
PriorityLevel::HIGH.src/bench/prevector.cpp (2)
136-146: LGTM!The
PREVECTOR_TESTmacro correctly updated to register bothNontrivialandTrivialbenchmark variants withPriorityLevel::HIGH.
153-154: LGTM!Standalone prevector benchmarks (
PrevectorAssignandPrevectorAssignTo) correctly updated withPriorityLevel::HIGH.src/bench/string_cast.cpp (1)
70-75: LGTM!The benchmark registrations correctly use the updated
BENCHMARKmacro signature with explicitbenchmark::PriorityLevel::HIGHpriority. The changes align with the benchmark framework enhancement in this backport.src/bench/logging.cpp (1)
44-48: LGTM!The logging benchmark registrations correctly adopt the new priority-level parameter. All five benchmarks are appropriately marked as
HIGHpriority.src/bench/bench.h (1)
79-80: LGTM!The
BENCHMARKmacro signature update correctly requires an explicitpriority_levelparameter. The macro expansion already includes the trailing semicolon, so invocation sites should omit it (as they correctly do throughout the codebase).src/bench/crypto_hash.cpp (2)
261-285: LGTM!All Bitcoin Core cryptographic hash benchmarks correctly adopt the new priority-level parameter with
HIGHpriority.
353-360: LGTM!The Dash-specific DSHA256 benchmarks are consistently updated to match the new
BENCHMARKmacro signature.src/bench/pow_hash.cpp (1)
265-359: LGTM! Consistent priority level update across all PoW benchmarks.All 77 benchmark registrations have been correctly updated to include
benchmark::PriorityLevel::HIGH, aligning with the new BENCHMARK macro signature. The changes are mechanical, consistent, and appropriate for these critical PoW hash function benchmarks.ci/test/00_setup_env_mac_native_arm64.sh (3)
10-10: LGTM: Correct ARM64 architecture target.The HOST triplet correctly specifies the ARM64 architecture for native macOS builds.
11-11: The lief package removal is safe and intentional for ARM64 macOS native builds.The
liefpackage is not required for the ARM64 native macOS build configuration. Security tests (RUN_SECURITY_TESTS) default to false and are not explicitly enabled in the ARM64 setup, so the test-security-check tools (which require lief) will not run. The lief package is installed separately in the ci/lint phase for static analysis checks, not in the test phase. This change matches the pattern used for regular macOS builds, which also do not include lief in PIP_PACKAGES.
13-13: Do not modify ci/ directory files without explicit justification. Per coding guidelines, changes toci/directories should be avoided unless specifically prompted. If this change is intentional, clarify the business requirement and whether it aligns with upstream Bitcoin Core's macOS ARM64 configuration.The
--with-miniupnpcand--with-natpmpadditions are valid for native ARM64 macOS builds, but they belong in the core build configuration, not CI setup files. Verify this configuration matches the upstream Bitcoin Core macOS ARM64 CI setup before approving.src/test/fuzz/string.cpp (1)
7-7: LGTM! Header path updated correctly.The include path change from
<util/url.h>to<common/url.h>is consistent with the broader refactoring to move URL utilities to the common directory.src/Makefile.am (3)
190-190: LGTM! Header moved to common directory.The addition of
common/url.htoBITCOIN_CORE_Hcorrectly reflects the relocation of URL utilities from the util directory to the common directory.
960-963: LGTM! Proper handling of libevent dependency.The conditional compilation under
USE_LIBEVENTcorrectly:
- Adds
EVENT_CFLAGStolibbitcoin_common_a_CPPFLAGS(required becausecommon/url.cppincludesevent2/http.h)- Adds
common/url.cpptolibbitcoin_common_a_SOURCESThis ensures the URL implementation is only compiled when libevent is available.
1084-1084: LGTM! Correct linkage for dash-cli.Adding
LIBBITCOIN_COMMONtodash_cli_LDADDis necessary because dash-cli uses URL functions that are now part of the common library.src/common/url.cpp (1)
5-5: LGTM! Self-referential header path updated.The include path correctly references the new location of the header file in the common directory.
src/test/util/setup_common.cpp (1)
10-10: LGTM! Header path updated correctly.The include path change from
<util/url.h>to<common/url.h>is consistent with the URL utilities relocation.Note: The cppcheck error about "undefined function-like macro invocation" appears to be a false positive related to conditional compilation directives in the broader codebase.
src/rpc/client.cpp (1)
142-142: LGTM! Parameter conversion added for new RPC.The addition of the
submitpackageRPC parameter conversion entry is correctly formatted and consistent with the existing pattern. This enables proper JSON parsing for thepackageparameter (index 0) when calling the regtest-only submitpackage RPC.test/functional/wallet_listsinceblock.py (2)
44-44: LGTM!The integration of
test_op_returninto the test run flow is correct and follows the existing pattern of other test method invocations.
403-415: LGTM!The new
test_op_returnmethod correctly tests that OP_RETURN transactions don't include anaddressfield in thelistsinceblockresponse, which aligns with the RPC changes making the address field optional for outputs without addresses (e.g., OP_RETURN null data).Note: Static analysis suggests using
next(...)instead of the list comprehension with[0], but this is backported code matching upstream Bitcoin Core style.test/functional/wallet_listtransactions.py (2)
107-107: LGTM!Correctly integrates the OP_RETURN test into the test flow after the parameter validity tests.
170-179: LGTM!The
test_op_returnmethod correctly verifies that OP_RETURN outputs don't include anaddressfield inlisttransactionsresults. This provides complementary coverage to the parallel test inwallet_listsinceblock.py.Note: Static analysis suggests using
next(...)instead of the list comprehension with[0], but this is backported code matching upstream Bitcoin Core style.src/wallet/rpc/transactions.cpp (3)
460-461: LGTM!The
addressfield is correctly marked asoptional=truewith updated documentation explaining it's omitted for move transactions or outputs without addresses (e.g., OP_RETURN null data). This matches the functional test coverage added inwallet_listtransactions.py.
575-575: LGTM!The
addressfield is correctly marked asoptional=truewith updated documentation forlistsinceblock, consistent with thelisttransactionschanges.
850-852: LGTM!Good documentation update for
rescanblockchainthat informs users about the faster descriptor wallet rescan capability when block filters are available via-blockfilterindex=1.src/interfaces/chain.h (3)
8-8: LGTM!Required include for
BlockFilterTypeandGCSFilter::ElementSettypes used in the new interface methods.
143-148: LGTM!Well-designed Chain interface extensions for block filter support:
hasBlockFilterIndexprovides a simple availability checkblockFilterMatchesAnyreturnsstd::optional<bool>which correctly handles three states: filter unavailable (nullopt), no match (false), or match (true)These methods enable the fast descriptor wallet rescan feature.
158-158: LGTM!Minor formatting adjustment.
src/node/interfaces.cpp (2)
9-9: LGTM!Required includes for the block filter index implementation -
blockfilter.hforBlockFilterandBlockFilterType, andindex/blockfilterindex.hforGetBlockFilterIndex()andBlockFilterIndex.Also applies to: 22-22
1072-1085: LGTM!Solid implementation of the Chain interface methods:
hasBlockFilterIndex: Simple and correct null checkblockFilterMatchesAny: Properly handles all failure cases by returningstd::nullopt(missing index, missing block, failed filter lookup), and returns the actual match result otherwiseThe locking pattern with
WITH_LOCK(::cs_main, ...)for the block index lookup is correct.src/rpc/mempool.cpp (5)
8-8: LGTM!Required include for
Params().IsMockableChain()used in the regtest-only check forsubmitpackage.
240-240: LGTM!Minor documentation refinement for the
vsizefield description.
769-860: LGTM!The
submitpackageRPC implementation is well-structured:
- Correctly restricted to regtest via
Params().IsMockableChain()- Proper input validation for package size limits
- Comprehensive error handling for all
PackageValidationResultcases- Correct use of
ProcessNewPackagewithtest_accept=falsefor actual submissionThe help text appropriately warns that this is experimental and that individual transaction broadcast may not propagate packages effectively until package relay is implemented.
871-894: LGTM!The result construction correctly builds the response with transaction results including txid, size, and fees for valid/mempool-entry transactions, plus optional package-feerate when available.
908-908: LGTM!Correctly registers
submitpackageas a hidden command, appropriate for a regtest-only experimental RPC.test/functional/wallet_fast_rescan.py (3)
1-21: LGTM!Good test file structure with clear constants defining the test parameters. The docstring accurately describes the test purpose - verifying that fast rescan using block filters correctly handles top-ups and finds the same transactions as the slow variant.
53-99: LGTM!Excellent test coverage for fast rescan functionality:
- Tests four scenarios: fast/slow × backup restore/non-active descriptors
- Uses
assert_debug_logto verify the correct rescan variant is used- Validates that all rescan methods find exactly
NUM_DESCRIPTORS * NUM_BLOCKStransactions- Confirms fast and slow variants produce identical sorted transaction lists
The test correctly exercises the top-up mechanism by sending to end-range addresses.
100-102: LGTM!Standard test entry point.
src/wallet/wallet.cpp (1)
9-10: Fast rescan filter wiring and block-filter–based ScanForWalletTransactions look correctThe new
FastWalletRescanFilterclass and its usage inScanForWalletTransactionsare consistent and self‑contained:
- Filter construction only for non‑legacy wallets when a BASIC_FILTER index is available, matching the intended descriptor‑wallet optimization.
- Descriptor SPK managers are located via
GetAllScriptPubKeyMans()/GetScriptPubKeyMan(id)and safely downcast; non‑HD managers are handled once at construction without range tracking.- Per‑block logic cleanly gates
fetch_blockbased onblockFilterMatchesAnyand updateslast_scanned_block/heightwhether the block was actually read or safely skipped.- Reorg handling, failure reporting (
last_failed_block/ScanResult::FAILURE), and progress saving (WriteBestBlockvia locator) remain correct and are only triggered after blocks are confirmed active.AttachChainstill invokesScanForWalletTransactionsin the same way, so existing rescan semantics are preserved, with the filter path as a pure speedup.This matches the upstream design and doesn’t appear to affect Dash‑specific wallet behavior.
Also applies to: 285-341, 1886-2011, 3414-3424
test/functional/mempool_package_limits.py (1)
9-15: Decorator and MiniWallet-based package limit tests look consistentThe new
check_package_limitsdecorator plus MiniWallet-based transaction generation cleanly restructures these tests:
- Each subtest starts with an empty mempool, creates the intended mempool+package topology, then confirms
testmempoolacceptfails withpackage-mempool-limitsbefore mining and re-checking successful acceptance.- MiniWallet is initialized with sufficient mature UTXOs and is only used to send the mempool transactions; returned hex payloads are exclusively used as the package under test.
- The refactors preserve the previous scenarios (chains, A/V/Y-shaped graphs, bushy trees, size-based cases) while centralizing the common assertions.
No functional issues stand out here; behavior should match the upstream tests once MiniWallet’s
_bulk_txis correct.If you haven’t already, it’s worth running
test/functional/mempool_package_limits.pyafter these changes to confirm the decorator and MiniWallet integration behave as expected.Also applies to: 24-38, 46-63, 64-77, 95-132, 134-171, 173-210, 212-246, 248-277, 279-311, 313-345
test/functional/test_framework/wallet.py (1)
29-32: MiniWallet padding and chain helpers are wired correctly; please verify_bulk_txsizing in your test run
sign_txnow iterates overtx.vinrather than by index and still assigns fixed-size scriptSigs per input for RAW modes; behaviour is equivalent and simpler.create_self_transfer_multi/create_self_transferproperly propagatetarget_weightand return a"fee"field consistent withinputs_value_total - outputs_value_total._bulk_txpads transactions using an OP_RETURN output and asserts the finaltx.get_weight()falls within a small window abovetarget_weight, which is then exercised by mempool size–limit tests.- New
create_self_transfer_chainandsend_self_transfer_chainhelpers correctly build linear dependency chains and are used by the updated functional tests.Given the interplay between
target_weightandCTransaction.get_weight(), it’s worth re-running the size‑sensitive tests (notablymempool_package_limits.py) to ensure the padding assertions in_bulk_txhold with Dash’s test framework implementation. No code changes are needed here if the behaviour matches upstream.Also applies to: 42-47, 95-106, 145-163, 251-255, 257-307, 312-333, 339-364
| for (const auto& tx : txns) { | ||
| size_t num_submitted{0}; | ||
| bilingual_str err_string; | ||
| const auto err = BroadcastTransaction(node, tx, err_string, 0, true, true); | ||
| if (err != TransactionError::OK) { | ||
| throw JSONRPCTransactionError(err, | ||
| strprintf("transaction broadcast failed: %s (all transactions were submitted, %d transactions were broadcast successfully)", | ||
| err_string.original, num_submitted)); | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unused variable num_submitted always reports 0 in error message.
The variable num_submitted is declared inside the loop at line 862, initialized to 0, and never incremented. The error message will always report "0 transactions were broadcast successfully" even if multiple transactions were successfully broadcast before one fails.
🤖 Prompt for AI Agents
In @src/rpc/mempool.cpp around lines 861 - 870, The variable num_submitted is
declared inside the loop in the transaction broadcast block and never
incremented, so the error message always reports 0; move the declaration of
num_submitted outside the for loop (so it accumulates across iterations),
increment it whenever BroadcastTransaction(node, tx, ...) returns
TransactionError::OK, and then use that accumulated num_submitted in the
JSONRPCTransactionError message; update references around BroadcastTransaction
and the surrounding loop to ensure num_submitted reflects the count of
successfully broadcast transactions.
| tx_children = [] | ||
| # First create one parent tx with 10 children | ||
| (txid, sent_value) = chain_transaction(self.nodes[0], [txid], [vout], value, fee, 10) | ||
| parent_transaction = txid | ||
| for i in range(10): | ||
| transaction_package.append({'txid': txid, 'vout': i, 'amount': sent_value}) | ||
| tx_with_children = self.wallet.send_self_transfer_multi(from_node=self.nodes[0], num_outputs=10) | ||
| parent_transaction = tx_with_children["txid"] | ||
| transaction_package = tx_with_children["new_utxos"] | ||
|
|
||
| # Sign and send up to MAX_DESCENDANT transactions chained off the parent tx | ||
| chain = [] # save sent txs for the purpose of checking node1's mempool later (see below) | ||
| for _ in range(DEFAULT_DESCENDANT_LIMIT - 1): | ||
| utxo = transaction_package.pop(0) | ||
| (txid, sent_value) = chain_transaction(self.nodes[0], [utxo['txid']], [utxo['vout']], utxo['amount'], fee, 10) | ||
| new_tx = self.wallet.send_self_transfer_multi(from_node=self.nodes[0], num_outputs=10, utxos_to_spend=[utxo]) | ||
| txid = new_tx["txid"] | ||
| chain.append(txid) | ||
| if utxo['txid'] is parent_transaction: | ||
| tx_children.append(txid) | ||
| for j in range(10): | ||
| transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value}) | ||
| transaction_package.extend(new_tx["new_utxos"]) | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix is vs == when matching UTXO txids to the parent transaction
utxo['txid'] is parent_transaction is using identity comparison on Python strings. This is unreliable and can cause children not to be associated with their parent correctly, breaking the descendant/spentby checks.
Use equality instead:
Proposed fix
- if utxo['txid'] is parent_transaction:
+ if utxo['txid'] == parent_transaction:
tx_children.append(txid)📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| tx_children = [] | |
| # First create one parent tx with 10 children | |
| (txid, sent_value) = chain_transaction(self.nodes[0], [txid], [vout], value, fee, 10) | |
| parent_transaction = txid | |
| for i in range(10): | |
| transaction_package.append({'txid': txid, 'vout': i, 'amount': sent_value}) | |
| tx_with_children = self.wallet.send_self_transfer_multi(from_node=self.nodes[0], num_outputs=10) | |
| parent_transaction = tx_with_children["txid"] | |
| transaction_package = tx_with_children["new_utxos"] | |
| # Sign and send up to MAX_DESCENDANT transactions chained off the parent tx | |
| chain = [] # save sent txs for the purpose of checking node1's mempool later (see below) | |
| for _ in range(DEFAULT_DESCENDANT_LIMIT - 1): | |
| utxo = transaction_package.pop(0) | |
| (txid, sent_value) = chain_transaction(self.nodes[0], [utxo['txid']], [utxo['vout']], utxo['amount'], fee, 10) | |
| new_tx = self.wallet.send_self_transfer_multi(from_node=self.nodes[0], num_outputs=10, utxos_to_spend=[utxo]) | |
| txid = new_tx["txid"] | |
| chain.append(txid) | |
| if utxo['txid'] is parent_transaction: | |
| tx_children.append(txid) | |
| for j in range(10): | |
| transaction_package.append({'txid': txid, 'vout': j, 'amount': sent_value}) | |
| transaction_package.extend(new_tx["new_utxos"]) | |
| tx_children = [] | |
| # First create one parent tx with 10 children | |
| tx_with_children = self.wallet.send_self_transfer_multi(from_node=self.nodes[0], num_outputs=10) | |
| parent_transaction = tx_with_children["txid"] | |
| transaction_package = tx_with_children["new_utxos"] | |
| # Sign and send up to MAX_DESCENDANT transactions chained off the parent tx | |
| chain = [] # save sent txs for the purpose of checking node1's mempool later (see below) | |
| for _ in range(DEFAULT_DESCENDANT_LIMIT - 1): | |
| utxo = transaction_package.pop(0) | |
| new_tx = self.wallet.send_self_transfer_multi(from_node=self.nodes[0], num_outputs=10, utxos_to_spend=[utxo]) | |
| txid = new_tx["txid"] | |
| chain.append(txid) | |
| if utxo['txid'] == parent_transaction: | |
| tx_children.append(txid) | |
| transaction_package.extend(new_tx["new_utxos"]) |
🤖 Prompt for AI Agents
In @test/functional/mempool_packages.py around lines 223 - 239, The loop that
builds chained child transactions incorrectly uses identity comparison when
checking utxo['txid'] is parent_transaction, which can miss matches; update that
conditional in the for-loop (where utxo, parent_transaction, tx_children, chain
and transaction_package are used) to use equality (==) instead of is so string
txid comparisons correctly detect children and populate tx_children for
downstream descendant/spentby checks.
| def assert_equal_package_results(self, node, testmempoolaccept_result, submitpackage_result): | ||
| """Assert that a successful submitpackage result is consistent with testmempoolaccept | ||
| results and getmempoolentry info. Note that the result structs are different and, due to | ||
| policy differences between testmempoolaccept and submitpackage (i.e. package feerate), | ||
| some information may be different. | ||
| """ | ||
| for testres_tx in testmempoolaccept_result: | ||
| # Grab this result from the submitpackage_result | ||
| submitres_tx = submitpackage_result["tx-results"][testres_tx["txid"]] | ||
| assert_equal(submitres_tx["txid"], testres_tx["txid"]) | ||
| # No "allowed" if the tx was already in the mempool | ||
| if "allowed" in testres_tx and testres_tx["allowed"]: | ||
| assert_equal(submitres_tx["size"], testres_tx["vsize"]) | ||
| assert_equal(submitres_tx["fees"]["base"], testres_tx["fees"]["base"]) | ||
| entry_info = node.getmempoolentry(submitres_tx["txid"]) | ||
| assert_equal(submitres_tx["size"], entry_info["vsize"]) | ||
| assert_equal(submitres_tx["fees"]["base"], entry_info["fees"]["base"]) | ||
|
|
||
| def test_submit_child_with_parents(self, num_parents, partial_submit): | ||
| node = self.nodes[0] | ||
| peer = node.add_p2p_connection(P2PTxInvStore()) | ||
|
|
||
| package_txns = [] | ||
| for _ in range(num_parents): | ||
| parent_tx = self.wallet.create_self_transfer(fee=DEFAULT_FEE) | ||
| package_txns.append(parent_tx) | ||
| if partial_submit and random.choice([True, False]): | ||
| node.sendrawtransaction(parent_tx["hex"]) | ||
| child_tx = self.wallet.create_self_transfer_multi(utxos_to_spend=[tx["new_utxo"] for tx in package_txns], fee_per_output=10000) #DEFAULT_FEE | ||
| package_txns.append(child_tx) | ||
|
|
||
| testmempoolaccept_result = node.testmempoolaccept(rawtxs=[tx["hex"] for tx in package_txns]) | ||
| submitpackage_result = node.submitpackage(package=[tx["hex"] for tx in package_txns]) | ||
|
|
||
| # Check that each result is present, with the correct size and fees | ||
| for package_txn in package_txns: | ||
| tx = package_txn["tx"] | ||
| assert tx.hash in submitpackage_result["tx-results"] | ||
| tx_result = submitpackage_result["tx-results"][tx.hash] | ||
| assert_equal(tx_result, { | ||
| "txid": package_txn["txid"], | ||
| "size": tx.get_vsize(), | ||
| "fees": { | ||
| "base": DEFAULT_FEE, | ||
| } | ||
| }) | ||
|
|
||
| # submitpackage result should be consistent with testmempoolaccept and getmempoolentry | ||
| self.assert_equal_package_results(node, testmempoolaccept_result, submitpackage_result) | ||
|
|
||
| # Package feerate is calculated for the remaining transactions after deduplication and | ||
| # individual submission. If only 0 or 1 transaction is left, e.g. because all transactions | ||
| # had high-feerates or were already in the mempool, no package feerate is provided. | ||
| # In this case, since all of the parents have high fees, each is accepted individually. | ||
| assert "package-feerate" not in submitpackage_result | ||
|
|
||
| # The node should announce each transaction. No guarantees for propagation. | ||
| self.bump_mocktime(30) | ||
| peer.wait_for_broadcast([tx["tx"].hash for tx in package_txns]) | ||
| self.generate(node, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use txid strings instead of tx.hash for submitpackage results and broadcast waits
In test_submit_child_with_parents:
submitpackage_result["tx-results"]is keyed by txid strings, not the internal integertx.hash.P2PTxInvStore.wait_for_broadcastexpects hex txid strings and currently receives integer hashes.
This will cause incorrect lookups and can raise type errors. Index and wait using txid fields instead:
Proposed fix
- for package_txn in package_txns:
- tx = package_txn["tx"]
- assert tx.hash in submitpackage_result["tx-results"]
- tx_result = submitpackage_result["tx-results"][tx.hash]
+ for package_txn in package_txns:
+ tx = package_txn["tx"]
+ assert package_txn["txid"] in submitpackage_result["tx-results"]
+ tx_result = submitpackage_result["tx-results"][package_txn["txid"]]
@@
- self.bump_mocktime(30)
- peer.wait_for_broadcast([tx["tx"].hash for tx in package_txns])
+ self.bump_mocktime(30)
+ peer.wait_for_broadcast([tx["txid"] for tx in package_txns])🧰 Tools
🪛 Ruff (0.14.10)
245-245: Unnecessary key check before dictionary access
Replace with dict.get
(RUF019)
260-260: Standard pseudo-random generators are not suitable for cryptographic purposes
(S311)
🤖 Prompt for AI Agents
In @test/functional/rpc_packages.py around lines 234 - 293, The test uses
internal integer tx.hash values where submitpackage_result and P2PTxInvStore
expect hex txid strings; update all lookups and waits in
test_submit_child_with_parents to use the package_txn["txid"] string (e.g., when
asserting membership in submitpackage_result["tx-results"], when fetching
tx_result, and when calling peer.wait_for_broadcast) instead of tx.hash; ensure
any places that compare or index by txid use the same string key from
package_txn["txid"] so submitpackage_result lookups and broadcast waits use the
correct hex txid type.
| def test_submit_cpfp(self): | ||
| node = self.nodes[0] | ||
| peer = node.add_p2p_connection(P2PTxInvStore()) | ||
|
|
||
| tx_poor = self.wallet.create_self_transfer(fee=0, fee_rate=0) | ||
| tx_rich = self.wallet.create_self_transfer(fee=DEFAULT_FEE) | ||
| package_txns = [tx_rich, tx_poor] | ||
| coins = [tx["new_utxo"] for tx in package_txns] | ||
| tx_child = self.wallet.create_self_transfer_multi(utxos_to_spend=coins, fee_per_output=10000) #DEFAULT_FEE | ||
| package_txns.append(tx_child) | ||
|
|
||
| submitpackage_result = node.submitpackage([tx["hex"] for tx in package_txns]) | ||
|
|
||
| rich_parent_result = submitpackage_result["tx-results"][tx_rich["txid"]] | ||
| poor_parent_result = submitpackage_result["tx-results"][tx_poor["txid"]] | ||
| child_result = submitpackage_result["tx-results"][tx_child["tx"].hash] | ||
| assert_equal(rich_parent_result["fees"]["base"], DEFAULT_FEE) | ||
| assert_equal(poor_parent_result["fees"]["base"], 0) | ||
| assert_equal(child_result["fees"]["base"], DEFAULT_FEE) | ||
| # Package feerate is calculated for the remaining transactions after deduplication and | ||
| # individual submission. Since this package had a 0-fee parent, package feerate must have | ||
| # been used and returned. | ||
| assert "package-feerate" in submitpackage_result | ||
| assert_fee_amount(DEFAULT_FEE, rich_parent_result["size"] + child_result["size"], submitpackage_result["package-feerate"]) | ||
|
|
||
| # The node will broadcast each transaction, still abiding by its peer's fee filter | ||
| self.bump_mocktime(30) | ||
| peer.wait_for_broadcast([tx["tx"].hash for tx in package_txns]) | ||
| self.generate(node, 1) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Align CPFP submitpackage test with txid-based keys and broadcasts
In test_submit_cpfp:
- The child result is indexed with
tx_child["tx"].hash, buttx-resultsis keyed by txid strings. peer.wait_for_broadcastis again called with integer hashes.
To be consistent with the parent lookups and the P2PTxInvStore API, this should use txid strings:
Proposed fix
- rich_parent_result = submitpackage_result["tx-results"][tx_rich["txid"]]
- poor_parent_result = submitpackage_result["tx-results"][tx_poor["txid"]]
- child_result = submitpackage_result["tx-results"][tx_child["tx"].hash]
+ rich_parent_result = submitpackage_result["tx-results"][tx_rich["txid"]]
+ poor_parent_result = submitpackage_result["tx-results"][tx_poor["txid"]]
+ child_result = submitpackage_result["tx-results"][tx_child["txid"]]
@@
- self.bump_mocktime(30)
- peer.wait_for_broadcast([tx["tx"].hash for tx in package_txns])
+ self.bump_mocktime(30)
+ peer.wait_for_broadcast([tx["txid"] for tx in package_txns])This keeps all indexing and broadcast checks consistently based on txid strings.
🤖 Prompt for AI Agents
In @test/functional/rpc_packages.py around lines 295 - 323, In test_submit_cpfp,
the child transaction is being referenced by tx_child["tx"].hash and
peer.wait_for_broadcast is given integer hashes, but
submitpackage_result["tx-results"] and P2PTxInvStore expect txid strings; change
the child lookup to use tx_child["txid"] (matching
rich_parent_result/poor_parent_result) and call peer.wait_for_broadcast with the
list [tx["txid"] for tx in package_txns] so both the submitpackage_result access
and the broadcast check consistently use txid strings.
| assert_equal(len(descriptors), NUM_DESCRIPTORS) | ||
| w.backupwallet(WALLET_BACKUP_FILENAME) | ||
|
|
||
| self.log.info(f"Create txs sending to end range address of each descriptor, triggering top-ups") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove extraneous f prefix from string literal.
This f-string has no placeholders, as flagged by static analysis.
🧰 Tools
🪛 Flake8 (7.3.0)
[error] 52-52: f-string is missing placeholders
(F541)
🪛 Ruff (0.14.10)
52-52: f-string without any placeholders
Remove extraneous f prefix
(F541)
🤖 Prompt for AI Agents
In @test/functional/wallet_fast_rescan.py at line 52, The log call uses an
unnecessary f-string prefix in the message inside the self.log.info call; remove
the leading 'f' so the string becomes a normal literal in the self.log.info(...)
invocation (locate the call to self.log.info that currently reads f"Create txs
sending to end range address of each descriptor, triggering top-ups" and change
it to a plain string without the f prefix).
What was done?
Regular backports from bitcoin core v25
How Has This Been Tested?
Run unit & functional tests
Breaking Changes
N/A
Checklist: