Skip to content
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

backport: bitcoin#25383, 25535, 25337 #6524

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

vijaydasmp
Copy link

bitcoin backports

Copy link

github-actions bot commented Feb 6, 2025

This pull request has conflicts, please rebase.

Copy link

This pull request has conflicts, please rebase.

@vijaydasmp vijaydasmp changed the title backport: bitcoin#25383, 25471, 25535, 19393, 25337 backport: bitcoin#25383, 25535, 19393, 25337 Feb 22, 2025
@vijaydasmp vijaydasmp force-pushed the Jan_2025_04 branch 6 times, most recently from 007a285 to f246628 Compare March 1, 2025 15:18
@vijaydasmp vijaydasmp changed the title backport: bitcoin#25383, 25535, 19393, 25337 backport: bitcoin#25383, 25535, 25337 Mar 1, 2025
…letBatch' is created

c318211 walletdb: fix last client version update (furszy)
bda8ebe wallet: don't read db every time that a new WalletBatch is created (furszy)

Pull request description:

  Found it while was working on bitcoin#25297.

  We are performing a db read operation every time that a new `WalletBatch` is created, inside the constructor, just to check if the client version field is inside the db or not.

  As the client version field does not change in the entire db lifecycle, this operation can be done only once: The first time that the db is accessed/opened and the client version value can be cached.

ACKs for top commit:
  achow101:
    ACK c318211
  w0xlt:
    reACK bitcoin@c318211

Tree-SHA512: 7fb780c656e169e8eb21e7212242494a647f6506d6da2cca828703713d440d29c82bec9e7d2c410f37b49361226ccd80846d3eeb8168383d0c2a11d85d73bee2
@vijaydasmp vijaydasmp marked this pull request as ready for review March 2, 2025 01:08
Copy link

coderabbitai bot commented Mar 2, 2025

Walkthrough

The changes update several aspects of wallet functionality and its testing. In wallet interfaces, the getAddresses method has been modified to include the const qualifier, indicating that it does not modify state. The address book system has been restructured by removing the GetLabelAddresses method and introducing a new filtering structure (AddrBookFilter), along with three new methods: ForEachAddrBookEntry, ListAddrBookAddresses, and ListAddrBookLabels to handle address data more generically. In the Berkeley and wallet database components, initialization and version-handling routines have been streamlined, including the removal of specific version-setting logic. The RPC code has been refactored by eliminating deprecated functions, updating collection types from sets to vectors, and enhancing address processing logic. Additionally, test scripts have been modified to update node configurations (switching from non-standard transaction acceptance to a zero dust relay fee) and include extra verifications for address classifications.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bfd640c and 7beb411.

📒 Files selected for processing (8)
  • src/interfaces/wallet.h (1 hunks)
  • src/wallet/interfaces.cpp (1 hunks)
  • src/wallet/rpcwallet.cpp (9 hunks)
  • src/wallet/wallet.cpp (1 hunks)
  • src/wallet/wallet.h (1 hunks)
  • test/functional/feature_dbcrash.py (2 hunks)
  • test/functional/wallet_basic.py (1 hunks)
  • test/functional/wallet_listreceivedby.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/functional/wallet_listreceivedby.py
  • test/functional/wallet_basic.py
  • src/interfaces/wallet.h
🧰 Additional context used
🪛 Cppcheck (2.10-2)
src/wallet/interfaces.cpp

[error] 225-225: Syntax Error

(internalAstError)

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build container / Build container
🔇 Additional comments (25)
test/functional/feature_dbcrash.py (1)

65-66: Parameter change to standardize dust handling.

The change from -acceptnonstdtxn to -dustrelayfee=0 is a more precise approach for handling "dust" outputs. Rather than broadly accepting non-standard transactions, it specifically sets a zero dust relay fee, which allows transactions with very small outputs to be relayed while maintaining other standard transaction rules.

src/wallet/interfaces.cpp (4)

208-210: Improved address lookup with early return.

The change to use FindAddressBookEntry with explicit allow_change=false and an early return for not found addresses improves code clarity and performance. This approach clearly indicates the intent to exclude change addresses from the lookup and avoids unnecessary code execution when an address isn't found.


211-212: Simplified label access.

Directly accessing the label via entry->GetLabel() rather than through an iterator simplifies the code and makes the intent clearer.


217-218: Simplified purpose access.

Directly accessing the purpose via entry->purpose rather than through an iterator simplifies the code and makes the intent clearer.


221-230: Enhanced getAddresses implementation with const qualifier.

The getAddresses method has been improved in two ways:

  1. Added the const qualifier, correctly indicating that this method doesn't modify state
  2. Replaced manual iteration with ForEachAddrBookEntry, which provides a more abstracted and maintainable approach to processing address book entries

The new implementation elegantly filters out change addresses and constructs the result vector directly in the callback, making the code more concise and easier to understand.

🧰 Tools
🪛 Cppcheck (2.10-2)

[error] 225-225: Syntax Error

(internalAstError)

src/wallet/wallet.cpp (3)

2903-2909: Efficient abstraction for address book iteration.

The new ForEachAddrBookEntry method implements a clean higher-order function pattern for address book iteration, allowing for more flexible processing of address book entries without exposing internal implementation details.


2911-2925: Well-designed filter-based address retrieval implementation.

This new ListAddrBookAddresses function effectively replaces the removed GetLabelAddresses method with a more flexible approach that uses an optional filter parameter. The implementation appropriately handles edge cases including null filters and leverages the new ForEachAddrBookEntry method for consistent iteration.


2927-2939: Good addition for label collection functionality.

The ListAddrBookLabels method provides a clean way to collect unique labels matching a specific purpose, which complements the other address book functions well. The implementation uses the same pattern as ListAddrBookAddresses for consistency.

src/wallet/wallet.h (4)

796-802: LGTM - New AddrBookFilter struct introduces flexible address filtering

The new AddrBookFilter struct provides a clear and extensible way to filter address book entries by label and type (change/non-change). The default behavior of ignoring change addresses makes sense for most use cases.


804-807: Approved: Vector return type is appropriate for address collection

This method replaces the removed GetLabelAddresses method with a more flexible approach using the new filter structure. The change from returning a std::set to std::vector is appropriate since it preserves ordering, which can be useful for UI presentation.


809-812: LGTM: New helper for retrieving address book labels

Good addition that complements the address book restructuring. The method signature is clear and returning a std::set makes sense for unique label values.


814-819: Update documentation for ForEachAddrBookEntry to correctly reflect its behavior

There is an inconsistency: the documentation claims that iteration stops when the callback returns false, yet the callback type is defined as void and the implementation iterates over all entries without checking any return value. Please update the comment to remove any reference to stopping on a false return value.

  • Location: src/wallet/wallet.h (Lines 814–819)
  • Action: Revise the documentation comment to remove any reference to stopping on a false return value.
src/wallet/rpcwallet.cpp (13)

543-544: Data structure change from set to vector

The collection type has been changed from std::set<CTxDestination> to std::vector<CTxDestination> for storing addresses. This is part of a larger refactoring pattern evident throughout the code changes.


548-548: Updated method for retrieving addresses by label

The code now uses wallet.ListAddrBookAddresses(CWallet::AddrBookFilter{label}) instead of the removed GetLabelAddresses(label) method. This aligns with the address book refactoring mentioned in the PR summary.


559-559: Changed address insertion method for vector

Changed from using address_set.insert(dest) to address_vector.emplace_back(dest) to match the container type change. Using emplace_back is also more efficient as it constructs the element in-place.


579-579: Updated check for address existence in vector

Changed from address_set.count(address) to std::find(address_vector.begin(), address_vector.end(), address) != address_vector.end() to match the container type change. This maintains the same functionality but with the different data structure.


954-980: Enhanced address filtering logic

Added support for address filtering using an optional CTxDestination parameter. The implementation now properly handles the filtering case with a cleaner, more structured approach.


1000-1009: Refactored address iteration with lambda function

Changed how addresses are processed by introducing a lambda function to be used with ForEachAddrBookEntry. This makes the code more maintainable and follows the iterator pattern approach of the refactored address book system.


1013-1017: Improved check for tally entries

Enhanced the condition to check if an address is in the tally map, improving code clarity and maintainability.


1024-1040: Updated address label handling

Refactored how address labels are processed and how the UniValue object is constructed. The logic remains the same, but the implementation is cleaner and more structured.


1042-1048: Address book entry filtering implementation

Added efficient address filtering using the wallet's address book. This implementation leverages the new ForEachAddrBookEntry method for better code organization and performance.


1050-1061: Label tally processing refactor

Updated how label tallies are processed with enhanced conditional logic that better handles the entry iteration.


3930-3947: Refactored getaddressesbylabel implementation

The implementation now uses the ForEachAddrBookEntry method with a lambda function instead of iterating through a collection directly. This change is consistent with the address book interface refactoring.


3994-3994: Updated method for retrieving address book labels

Now using ListAddrBookLabels instead of a direct collection iteration. This method is part of the refactored address book interface.


543-1065: ⚠️ Potential issue

Missing changes in ListReceived function

The updates to ListReceived function have been implemented correctly, but I noticed that they align with the previous reviewer's comment about "missing changes in UniValue ListReceived()". The implementation now properly uses the new address book interfaces.

This addresses UdjinM6's comment about the missing changes. The function now properly uses the new interfaces such as ForEachAddrBookEntry and FindAddressBookEntry consistently with the rest of the refactored code.

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

🧹 Nitpick comments (2)
src/wallet/wallet.cpp (2)

2903-2910: Add documentation about concurrency

This method relies on the wallet lock being held but does not explicitly mention it in the function signature or comments. Consider clarifying that the caller must hold cs_wallet to avoid confusion.


2927-2940: Clarify handling of empty “purpose” argument

When the “purpose” parameter is empty, the logic adds all non-change labels to the returned set. Consider documenting this fallback scenario or validating that it matches the intended design for filtering address labels by purpose.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 26ea618 and 2573d09.

📒 Files selected for processing (10)
  • src/interfaces/wallet.h (1 hunks)
  • src/wallet/bdb.cpp (0 hunks)
  • src/wallet/interfaces.cpp (1 hunks)
  • src/wallet/rpcwallet.cpp (6 hunks)
  • src/wallet/wallet.cpp (1 hunks)
  • src/wallet/wallet.h (1 hunks)
  • src/wallet/walletdb.cpp (2 hunks)
  • test/functional/feature_dbcrash.py (2 hunks)
  • test/functional/wallet_basic.py (1 hunks)
  • test/functional/wallet_listreceivedby.py (1 hunks)
💤 Files with no reviewable changes (1)
  • src/wallet/bdb.cpp
🧰 Additional context used
🪛 Cppcheck (2.10-2)
src/wallet/interfaces.cpp

[error] 225-225: Syntax Error

(internalAstError)

🔇 Additional comments (20)
src/interfaces/wallet.h (1)

137-137: Excellent improvement for const-correctness.

Adding the const qualifier to the getAddresses() method properly indicates that it doesn't modify the wallet's state. This follows C++ best practices and enables calling the method on const instances of the Wallet interface.

test/functional/wallet_listreceivedby.py (1)

65-68: Good test enhancement for address classification.

This addition improves test coverage by validating that no addresses returned by listreceivedbyaddress() are change addresses. This helps ensure that the address filtering logic properly distinguishes between receiving addresses and change addresses, which is crucial for accurate wallet display and accounting.

test/functional/wallet_basic.py (1)

30-30: Improved test configuration with more specific parameter.

Replacing -acceptnonstdtxn=1 with -dustrelayfee=0 is a good refinement that:

  1. Uses a more targeted approach to handling small-value outputs
  2. Maintains other transaction standardness rules while specifically addressing dust handling
  3. Provides better alignment with how small outputs are handled in production environments

This change makes the tests more precise without broadly bypassing all standardness checks.

Also applies to: 34-34

src/wallet/walletdb.cpp (2)

883-885: Enhanced wallet version handling.

The addition of the has_last_client variable properly tracks whether the last client version was successfully read from the database. This improves logging clarity by showing both the wallet version and client version in a single message.


907-907: More robust version update logic.

The revised condition !has_last_client || last_client != CLIENT_VERSION ensures the version is properly updated both when it's missing from the database and when it differs from the current client version. This provides better handling for new wallets and migration scenarios.

test/functional/feature_dbcrash.py (3)

65-66: Improved documentation clarity for node configuration

The comment has been updated to better clarify that node3 will handle "dust" outputs, which aligns with the parameter change below.


66-66: Configuration parameter update from -acceptnonstdtxn to -dustrelayfee=0

The change replaces the older non-standard transaction acceptance flag with a more specific dust relay fee setting. This provides a more targeted approach for testing with small value outputs by explicitly setting a zero dust threshold rather than broadly accepting non-standard transactions.


220-224: Improved UTXO creation strategy and verification

The UTXO creation process has been refactored from a single large batch of 5000 UTXOs to 5 smaller batches of 1000 each. This approach:

  1. Keeps the same total number of UTXOs (5000)
  2. Provides more granular control over the creation process
  3. Adds a verification step to ensure the mempool is empty after UTXO generation

This change improves test robustness by breaking the work into smaller chunks and adding explicit verification.

src/wallet/wallet.h (3)

797-802: Added a flexible filtering structure for address book operations

The new AddrBookFilter structure provides a clean way to filter address book entries by label and whether to include change addresses. The default behavior (ignoring change addresses) is sensible as change addresses are typically not relevant for most user-facing operations.


804-813: Added flexible method for retrieving filtered address book data

The ListAddrBookAddresses method enables more flexible retrieval of address data by accepting an optional filter parameter. This is a good improvement over the removed GetLabelAddresses method as it provides more powerful filtering capabilities.


814-819: Added utility methods for address book operations

The new methods ListAddrBookLabels and ForEachAddrBookEntry provide a clean interface for:

  1. Retrieving all labels for a specific purpose
  2. Iterating through address book entries with a callback function

These additions follow good programming practices by:

  • Using a callback pattern for iteration that avoids exposing internal data structures
  • Providing specific functionality for common address book operations
  • Making the code more maintainable and easier to understand
src/wallet/interfaces.cpp (2)

208-219: Updated address lookup to use the new FindAddressBookEntry method

The implementation of getAddress has been simplified by using FindAddressBookEntry instead of manually checking the address book. This change improves code maintainability by:

  1. Reducing duplicate code
  2. Centralizing the logic for finding address book entries
  3. Using a consistent approach for address book access across the codebase

221-230: Added const qualifier and improved address retrieval implementation

Two key improvements in this change:

  1. The getAddresses method is now marked as const, correctly indicating that it doesn't modify the wallet state
  2. The implementation now uses the new ForEachAddrBookEntry callback method instead of direct iteration

This implementation:

  • Is more concise and easier to understand
  • Properly filters out change addresses
  • Uses a consistent pattern for address book access
  • Correctly constructs the result vector in a single operation
🧰 Tools
🪛 Cppcheck (2.10-2)

[error] 225-225: Syntax Error

(internalAstError)

src/wallet/wallet.cpp (1)

2911-2926: Verify behavior for empty labels

The filter logic correctly handles both ignore-change and optional label matching. However, if the label filter is set but the address has an empty label, the function will skip it. Verify if this is intended or if an empty label should be handled differently (e.g., treat empty label as a valid match).

src/wallet/rpcwallet.cpp (6)

543-543: Data structure change from set to vector

This change from std::set<CTxDestination> to std::vector<CTxDestination> alters the fundamental container type for addresses. While vectors offer better cache locality, be aware that checking for address existence now has O(n) complexity instead of O(log n) that sets provide.


548-548: API migration to more flexible address filtering

The code now uses the new ListAddrBookAddresses method with AddrBookFilter instead of the older GetLabelAddresses. This is part of a broader refactoring to provide more versatile address book querying capabilities.


559-559: Switched from set insertion to vector append

Changed from address_set.insert(dest) to address_vector.emplace_back(dest), consistent with the container type change. Note that emplace_back is generally more efficient than push_back for complex objects as it constructs the element in-place.


579-579: Modified address existence check

The address lookup has changed from the efficient address_set.count(address) to the linear search std::find(address_vector.begin(), address_vector.end(), address) != address_vector.end(). This maintains the same functionality but may be less efficient for large address collections.


3949-3966: Refactored label-based address retrieval using ForEachAddrBookEntry

The implementation of getaddressesbylabel has been updated to use a lambda with the new ForEachAddrBookEntry method, replacing a direct loop over address book entries. This approach is more maintainable as it centralizes address book iteration logic and simplifies the calling code.

The lambda function now directly constructs and adds the value object to the results instead of using the removed AddressBookDataToJSON function.


4013-4013: Updated label retrieval to use new API

This line now uses pwallet->ListAddrBookLabels(purpose) rather than directly iterating through the address book entries, which is consistent with the address book API modernization.

Comment on lines 223 to 224
self.generate(self.nodes[3], 1, sync_fun=self.no_op)
assert_equal(len(self.nodes[3].getrawmempool()), 0)
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

22535: unrelated changes

Suggested change
self.generate(self.nodes[3], 1, sync_fun=self.no_op)
assert_equal(len(self.nodes[3].getrawmempool()), 0)

@@ -540,12 +540,12 @@ static RPCHelpMan listaddressbalances()

static CAmount GetReceived(const CWallet& wallet, const UniValue& params, bool by_label) EXCLUSIVE_LOCKS_REQUIRED(wallet.cs_wallet)
{
std::set<CTxDestination> address_set;
std::vector<CTxDestination> address_vector;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

25337: missing changes in UniValue ListReceived()

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (5)
src/wallet/interfaces.cpp (1)

217-218: Direct access to entry fields

While GetLabel() is used for the label field, direct access is used for the purpose field. Consider creating a getter method for purpose as well for consistency.

src/wallet/rpcwallet.cpp (4)

543-543: Consider potential performance implications of using a vector instead of a set.
If the size of address_vector grows large, membership checks with std::find operate in O(n) time, which might degrade performance compared to a set-based approach.


579-579: Watch out for repeated linear searches on address_vector.
Using std::find every time could introduce inefficiency if the vector grows large.


1000-1001: Lambda captures everything by reference; confirm no unintended captures.
Capturing [&] is convenient but requires careful maintenance if more external variables are used inside the lambda.


1041-1047: Consider extracting this filtered-address logic into its own function.
The nested if-else logic from lines 1041 to 1047 could be refactored for clarity.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 2573d09 and 6398dc8.

📒 Files selected for processing (8)
  • src/interfaces/wallet.h (1 hunks)
  • src/wallet/interfaces.cpp (1 hunks)
  • src/wallet/rpcwallet.cpp (9 hunks)
  • src/wallet/wallet.cpp (1 hunks)
  • src/wallet/wallet.h (1 hunks)
  • test/functional/feature_dbcrash.py (2 hunks)
  • test/functional/wallet_basic.py (1 hunks)
  • test/functional/wallet_listreceivedby.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (4)
  • src/interfaces/wallet.h
  • test/functional/wallet_basic.py
  • test/functional/wallet_listreceivedby.py
  • test/functional/feature_dbcrash.py
🧰 Additional context used
🪛 Cppcheck (2.10-2)
src/wallet/interfaces.cpp

[error] 225-225: Syntax Error

(internalAstError)

⏰ Context from checks skipped due to timeout of 90000ms (3)
  • GitHub Check: x86_64-apple-darwin / Build depends
  • GitHub Check: x86_64-pc-linux-gnu_multiprocess / Build depends
  • GitHub Check: arm-linux-gnueabihf / Build depends
🔇 Additional comments (14)
src/wallet/interfaces.cpp (3)

208-209: Clean implementation of address lookup

The switch to using FindAddressBookEntry with explicit allow_change=false parameter simplifies the code and makes the intent clearer.


211-212: Usage of accessor method for label

Good use of the GetLabel() accessor method rather than directly accessing the label field.


221-229: Improved implementation using ForEachAddrBookEntry

The refactoring makes good use of the new ForEachAddrBookEntry method to iterate over address book entries. The lambda function properly filters out change addresses and creates the result vector with all necessary information. The method is correctly marked as const to indicate it doesn't modify the wallet state.

The code properly declares exclusive lock requirements in the lambda to ensure proper concurrent access handling.

🧰 Tools
🪛 Cppcheck (2.10-2)

[error] 225-225: Syntax Error

(internalAstError)

src/wallet/wallet.h (3)

797-802: Well-designed filter structure

The AddrBookFilter struct is well-designed with appropriate use of std::optional for the label and sensible defaults. The comments clearly explain the purpose of each field.


804-807: Flexible address book filtering method

The ListAddrBookAddresses method provides a flexible way to filter address book entries with the optional filter parameter. It's correctly marked as const and requires the wallet lock.


809-812: Clear method for retrieving address labels

The ListAddrBookLabels method provides a clean way to retrieve unique labels associated with a specific purpose. Using a std::set for the return type appropriately ensures uniqueness.

src/wallet/wallet.cpp (3)

2903-2909: Well-structured iteration over address book entries.

This helper method cleanly encapsulates the iteration logic, allowing the caller to easily process each address book entry. The read-only usage (function is const) is safe, and there are no obvious correctness or performance issues.


2911-2923: Parameter-driven address filtering is effective.

The use of an optional filter object and a lambda to exclude change addresses or addresses not matching a specified label is straightforward and efficient. The AssertLockHeld(cs_wallet) precondition ensures thread safety for reading the address book. No issues are evident.


2927-2939: Appropriate label retrieval functionality.

This method correctly gathers distinct labels, ignoring change entries if specified, and matches a requested purpose if provided. Lock acquisition (AssertLockHeld(cs_wallet)) is properly enforced. Implementation appears correct with no security or performance concerns.

src/wallet/rpcwallet.cpp (5)

548-548: Verify correctness of the new ListAddrBookAddresses usage.
Ensure all call sites that previously expected addresses from GetLabelAddresses correctly handle the list returned by ListAddrBookAddresses.


559-559: Emplacing single destination into the vector looks correct.
No immediate issues spotted; consistent with the shift to a vector container.


954-954: Usage of std::optional<CTxDestination> is clear and self-explanatory.
This approach provides a robust way to handle the presence or absence of a filtered address.


1004-1004: Early return looks correct.
Prevents unnecessary processing when there is no matching tally entry and fIncludeEmpty is false.


1050-1051: Logic for label-based tally is straightforward.
This block nicely handles the aggregation of amounts by label.

Comment on lines +814 to +819
/**
* Walk-through the address book entries.
* Stops when the provided 'ListAddrBookFunc' returns false.
*/
using ListAddrBookFunc = std::function<void(const CTxDestination& dest, const std::string& label, const std::string& purpose, bool is_change)>;
void ForEachAddrBookEntry(const ListAddrBookFunc& func) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Potential inconsistency in ForEachAddrBookEntry documentation

The documentation comment states that iteration "Stops when the provided 'ListAddrBookFunc' returns false", but the function type is defined with a void return type, which can't return a boolean value to control iteration.

Verify that either:

  1. The callback function should return a boolean (in which case the function type should be changed), or
  2. The documentation should be updated to match the actual behavior

🏁 Script executed:

#!/bin/bash
# Check the implementation of ForEachAddrBookEntry to see if it expects a boolean return
grep -A 15 "void CWallet::ForEachAddrBookEntry" src/wallet/wallet.cpp

Length of output: 840


Update documentation for ForEachAddrBookEntry to correctly reflect its behavior

There is an inconsistency: the documentation claims that iteration stops when the callback returns false, yet the callback type is defined as void and the implementation iterates over all entries without checking any return value. Please update the comment to indicate that the address book is fully iterated without an early termination condition.

  • Location: src/wallet/wallet.h (Lines 814–819)
  • Action: Revise the documentation comment to remove any reference to stopping on a false return value.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

♻️ Duplicate comments (1)
src/wallet/wallet.h (1)

814-819: ⚠️ Potential issue

Update documentation for ForEachAddrBookEntry

There is an inconsistency in the documentation comment. It states that iteration "Stops when the provided 'ListAddrBookFunc' returns false", but the function type is defined with a void return type, which can't return a boolean to control iteration.

Please update the documentation to accurately reflect the behavior of the function. Either:

  1. Change the comment to indicate that all entries are always processed, or
  2. Modify the ListAddrBookFunc type to return a boolean if early termination is desired
🧹 Nitpick comments (3)
src/wallet/wallet.cpp (1)

2903-2909: Consider asserting the wallet lock for consistency.
The function iterates over m_address_book, yet it does not explicitly assert cs_wallet is held. Other similar methods (ListAddrBookAddresses, ListAddrBookLabels) do so. To maintain consistency and clarity about concurrency requirements, consider adding the lock assertion here as well.

Here is a possible change:

 void CWallet::ForEachAddrBookEntry(const ListAddrBookFunc& func) const
+{
+    AssertLockHeld(cs_wallet);
     for (const auto& item : m_address_book) {
         ...
     }
 }
src/wallet/rpcwallet.cpp (2)

543-559: Consider potential performance trade-offs when using a vector instead of a set.

These lines replace the previous set-based structure with a vector (address_vector) for storing addresses. While vectors can be more cache-friendly and typically faster for small collections, lookups via std::find are O(n), which may be a concern for larger address lists. If lookups are expected to happen frequently on a large collection, consider using a suitable set-like container or caching lookups to maintain efficiency.


1000-1008: Consider renaming the lambda for clarity.

The introduced lambda function named func is correct, but giving it a more descriptive name (e.g., processAddressBookEntry) would improve readability.

-    const auto& func = [&](const CTxDestination& address, const std::string& label, const std::string& purpose, bool is_change) {
+    const auto& processAddressBookEntry = [&](const CTxDestination& address, const std::string& label, const std::string& purpose, bool is_change) {
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6398dc8 and bfd640c.

📒 Files selected for processing (6)
  • src/interfaces/wallet.h (1 hunks)
  • src/wallet/interfaces.cpp (1 hunks)
  • src/wallet/rpcwallet.cpp (9 hunks)
  • src/wallet/wallet.cpp (1 hunks)
  • src/wallet/wallet.h (1 hunks)
  • test/functional/wallet_listreceivedby.py (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/interfaces/wallet.h
  • test/functional/wallet_listreceivedby.py
🧰 Additional context used
🪛 Cppcheck (2.10-2)
src/wallet/interfaces.cpp

[error] 225-225: Syntax Error

(internalAstError)

⏰ Context from checks skipped due to timeout of 90000ms (6)
  • GitHub Check: x86_64-apple-darwin / Build depends
  • GitHub Check: arm-linux-gnueabihf / Build depends
  • GitHub Check: x86_64-pc-linux-gnu / Build depends
  • GitHub Check: x86_64-w64-mingw32 / Build depends
  • GitHub Check: x86_64-pc-linux-gnu_multiprocess / Build depends
  • GitHub Check: x86_64-pc-linux-gnu_nowallet / Build depends
🔇 Additional comments (14)
src/wallet/interfaces.cpp (3)

208-210: Improved address lookup with FindAddressBookEntry

The change from direct map access to the FindAddressBookEntry method provides better encapsulation and explicit handling of change addresses. This approach is more robust and maintainable.


211-218: Updated accessor pattern for address book entries

The switch from it->second.name to entry->GetLabel() aligns with the new address book structure. The method now properly handles the updated data structure while maintaining the same behavior.


221-228: Enhanced implementation with const qualifier and callback pattern

The addition of the const qualifier correctly indicates this method doesn't modify wallet state. The implementation is improved by replacing direct iteration with the ForEachAddrBookEntry callback pattern, which provides better encapsulation and cleaner code.

Note: The cppcheck error on line 225 appears to be a false positive related to the EXCLUSIVE_LOCKS_REQUIRED thread safety annotation.

🧰 Tools
🪛 Cppcheck (2.10-2)

[error] 225-225: Syntax Error

(internalAstError)

src/wallet/wallet.cpp (2)

2911-2925: Implementation looks correct.
This function properly locks the wallet (AssertLockHeld(cs_wallet)) and uses ForEachAddrBookEntry with a concise lambda to filter addresses by change status and optional label. The design is straightforward and appears robust.


2927-2939: Straightforward label filtering.
The method is clear, ignoring change addresses and collecting labels that match the specified purpose. This approach is consistent with the rest of the address-book-related methods.

src/wallet/wallet.h (3)

796-802: Clean and well-structured AddrBookFilter struct

Good addition of a filtering structure with sensible defaults. The optional label filter and the change address exclusion flag provide flexible querying capabilities for address book entries.


804-808: Good API design for ListAddrBookAddresses

This method introduces a more flexible way of retrieving address book entries with filtering capabilities. This is a good enhancement over the removed GetLabelAddresses method, allowing for more powerful queries.


809-813: Nicely implemented ListAddrBookLabels method

This method is well-designed to retrieve a set of unique labels for a given purpose. Using a std::set is the appropriate data structure for maintaining uniqueness of labels.

src/wallet/rpcwallet.cpp (6)

954-959: LGTM: Address filtering logic is well-structured.

The conditional checks (!by_label && params.size() > 4) and the subsequent decoding of params[4] ensure safe usage. The new filtering approach for a single filtered_address is straightforward and correct, and invalid addresses are robustly handled. No further changes required.


974-985: Clear conditional checks for filtered addresses and ownership.

This loop properly extracts the destination, checks it against the optional filtered_address, and verifies wallet ownership via (mine & filter). The flow guards against invalid or irrelevant outputs and should behave correctly in both the filtered and unfiltered scenarios.


1013-1013: Logic for tallying known addresses is clear.

The early check on it != mapTally.end() prevents erroneous lookups, and the subsequent else branch handles addresses not already added to the tally. The flow remains consistent, with no obvious logical or correctness issues.

Also applies to: 1024-1024


1032-1034: Good addition of transaction IDs to the response.

Collecting and pushing back the txids into the JSON array provides clear traceability of transactions associated with each address. Implementation looks correct and should not introduce performance concerns.


1040-1040: No issues with lambda closure.

This is simply the end brace for the lambda, and the closure is syntactically correct.


1042-1052: Well-handled branching for optional address filtering.

By either processing a single filtered_address or iterating over the entire address book, the code comprehensively covers both scenarios. The subsequent logic referencing label_tally and by_label is straightforward and consistent with the rest of the function.

MacroFake and others added 2 commits March 9, 2025 08:43
…ng dust (instead of `acceptnonstdtxn=1`)

1770be7 test: pass `dustrelayfee=0` option for tests using dust (instead of `acceptnonstdtxn=1`) (Sebastian Falbesoner)

Pull request description:

  By specifying the `dustrelayfee=0` option instead of the more generic `acceptnonstdtxn=1`, we can be more specific about what
  part of the transaction is non-standard and can be sure that all other aspects follow the standard policy.
  Note that for the test `feature_dbcrash.py`, the UTXO creation at the start of the test has to be split up to several txs to not exceed the tx standard size limit of 100k vbytes

  https://github.com/bitcoin/bitcoin/blob/4129c1375430dbfe8dd414868c43fceb3d091fc3/src/policy/policy.h#L26-L27

ACKs for top commit:
  MarcoFalke:
    review ACK 1770be7

Tree-SHA512: 5cb852a92883a7443ab7dc15b48efa76b5d1424b6b0da1fa6b075fbe9a83522e3ff60382d36c08d4b07143ed898c115614582474e37837332caaee73b0db0e47
d69045e test: add coverage for 'listreceivedbyaddress' no change addrs return (furszy)
324f00a refactor: 'ListReceived' use optional for filtered address (furszy)
b459fc1 refactor: RPC 'ListReceived', encapsulate m_address_book access (furszy)
fa9f2ab refactor: RPC 'listlabels', encapsulate 'CWallet::ListAddrBookLabels' functionality (furszy)
83e42c4 refactor: use 'ForEachAddrBookEntry' in RPC 'getaddressesbylabel' (furszy)
2b48642 refactor: use ForEachAddrBookEntry in interfaces::getAddresses (furszy)
032842a wallet: implement ForEachAddrBookEntry method (furszy)
09649bc refactor: implement general 'ListAddrBookAddresses' for addressbook destinations lookup (furszy)
192eb1e refactor: getAddress don't access m_address_book, use FindAddressEntry function (furszy)

Pull request description:

  ### Context

  The wallet's `m_address_book` field is being accessed directly from several places across the sources.

  ### Problem

  Code structure wise, we shouldn't be accessing it directly. It could end up being modified by mistake (from a place that has nothing to do with the wallet like an RPC command or the GUI) and cause a bigger issue: like an address book entry 'purpose' string change, which if done badly (from 'send' to 'receive'), could end up in a user sharing a "receive" address that he/she doesn't own.

  ### Solution

  Encapsulate `m_address_book` access inside the wallet.

  -------------------------------------------------------

  Extra Note:

  This is the initial step towards decoupling the address book functionality from the wallet's sources. In other words, the creation of the `AddressBookManager` (which will be coming in a follow-up PR).

ACKs for top commit:
  achow101:
    ACK d69045e
  theStack:
    ACK d69045e ✅
  w0xlt:
    ACK bitcoin@d69045e

Tree-SHA512: dba17acd86f171b4e9af0223bbbcad380048570f6a2f6a92732a51f01abe8806debaf65c9e9e5569fa76a541903cbb50adcb5f56ef77858151c698ae6b218e2a
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants