8000 fix: improve getTransactions in Wallet by HashEngineering · Pull Request #276 · dashpay/dashj · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix: improve getTransactions in Wallet #276

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

Merged
merged 6 commits into from
May 6, 2025

Conversation

HashEngineering
Copy link
Collaborator
@HashEngineering HashEngineering commented May 6, 2025

Issue being fixed or feature implemented

  • Improve getTransactions in Wallet
  • Add a test for coinjoin transactions
  • Fix RestoreFromSeedThenDump

What was done?

How Has This Been Tested?

Breaking Changes

Checklist:

  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have added or updated relevant unit/integration/functional/e2e tests
  • I have made corresponding changes to the documentation

For repository code-owners and collaborators only

  • I have assigned this pull request to a milestone

Summary by CodeRabbit

  • New Features

    • Added new methods to retrieve the transaction count and a list of transactions, with options to include or exclude certain transaction states.
    • Introduced a comprehensive test suite for large CoinJoin wallets, including performance benchmarks and detailed wallet functionality checks.
  • Improvements

    • Enhanced transaction retrieval methods for better consistency and performance.
  • Configuration

    • Updated run configurations for various WalletTool applications, including changes to module names, parameters, and debug logging options.
  • Examples

    • Updated example usage to utilize extended wallet features and initialize additional wallet components.

@HashEngineering HashEngineering requested a review from Syn-McJ May 6, 2025 15:41
@HashEngineering HashEngineering self-assigned this May 6, 2025
Copy link
coderabbitai bot commented May 6, 2025

Walkthrough

The changes introduce enhancements to wallet transaction retrieval in the core library, add a new large-scale CoinJoin wallet test, and update example and run configuration files to use new modules and parameters. Notable additions include new methods for transaction counting and listing, a performance-focused test class, and updated run parameters for various WalletTool configurations.

Changes

File(s) Change Summary
core/src/main/java/org/bitcoinj/wallet/Wallet.java Refactored getTransactions to pre-size sets, added getTransactionCount and getTransactionList methods for transaction retrieval, all supporting inclusion of dead transactions.
core/src/test/java/org/bitcoinj/wallet/LargeCoinJoinWalletTest.java Added a new public test class for performance and correctness testing of large CoinJoin wallets, including timing and validation of wallet operations.
examples/src/main/java/org/bitcoinj/examples/RestoreFromSeedThenDump.java Updated to use WalletEx instead of Wallet, and added a call to initializeCoinJoin(0) after setting up wallet extensions.
.run/WalletTool CJ Mix.run.xml
.run/WalletTool CJ Sync.run.xml
.run/WalletTool CJ address (devnet).run.xml
Updated run configurations: changed module names, adjusted program parameters (amount, sessions, flags), changed wallet and network parameters, and added debug log flag where applicable.

Sequence Diagram(s)

sequenceDiagram
    participant Test as LargeCoinJoinWalletTest
    participant Wallet as WalletEx
    participant File as coinjoin-large.wallet

    Test->>File: Load wallet data
    Test->>Wallet: Deserialize wallet
    Test->>Wallet: Retrieve CoinJoin rounds, key usage
    Test->>Wallet: Refresh unused keys
    Test->>Wallet: Get balances and mixing progress
    Test->>Wallet: Generate transaction reports
    Test->>Wallet: getTransactionCount(includeDead)
    Test->>Wallet: getTransactionList(includeDead)
    Wallet-->>Test: Return results for assertions and timing
Loading

Poem

In the warren of code, new methods appear,
Counting coins and listing them, quick as a hare’s ear.
A test hops in, large and bold,
To measure wallets, brave and cold.
Configs refreshed, the network anew—
This rabbit’s proud of what the team can do!
🐇✨

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ast-grep (0.31.1)
core/src/main/java/org/bitcoinj/wallet/Wallet.java
✨ Finishing Touches
  • 📝 Generate Docstrings

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.

❤️ Share
🪧 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 8000 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.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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 generate sequence diagram to generate a sequence diagram of the changes in 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: 4

🧹 Nitpick comments (6)
.run/WalletTool CJ address (devnet).run.xml (1)

4-5: Configuration updated to use test network and standardized module path.

The changes standardize this configuration to use the same module name and wallet file as other configurations, and switch from DEVNET to TEST network.

Consider renaming the file to reflect that it now uses the TEST network instead of DEVNET to avoid confusion.

core/src/test/java/org/bitcoinj/wallet/LargeCoinJoinWalletTest.java (5)

1-15: Copyright year needs to be corrected.

The copyright year is set to 2025, which is in the future. Please update it to the current year.

- * Copyright 2025 Dash Core Group
+ * Copyright 2023 Dash Core Group

43-46: Add proper resource handling in the setup method.

The try-with-resources statement is correctly used for the InputStream, but there's a potential issue with how the wallet is loaded that could lead to resource leaks if an exception occurs during serialization.

Consider adding a more robust error handling mechanism to ensure all resources are properly closed:

try (InputStream is = getClass().getResourceAsStream("coinjoin-large.wallet")) {
    Stopwatch watch = Stopwatch.createStarted();
+   if (is == null) {
+       throw new RuntimeException("Test wallet file 'coinjoin-large.wallet' not found in resources");
+   }
    wallet = (WalletEx) new WalletProtobufSerializer().readWallet(is);
    info("loading wallet: {}; {} transactions", watch, wallet.getTransactionCount(true));
}

129-148: Consider using SLF4J directly for logging.

The test implements a custom logging system that prints directly to standard output, despite importing SLF4J. Consider using the imported SLF4J logger directly for better integration with the project's logging configuration.

public static void info(String format, Object... args) {
-   log("INFO", format, args);
+   log.info(format, args);
}

public static void error(String format, Object... args) {
-   log("ERROR", format, args);
+   log.error(format, args);
}

- private static void log(String level, String format, Object... args) {
-     String timestamp = java.time.LocalDateTime.now().toString();
-     String message = formatMessage(format, args);
-     System.out.printf("%s [%s] %s%n", timestamp, level, message);
- }
-
- private static String formatMessage(String format, Object... args) {
-     for (Object arg : args) {
-         format = format.replaceFirst("\\{\\}", arg == null ? "null" : arg.toString());
-     }
-     return format;
- }

143-148: Improve string formatting efficiency.

The current implementation of formatMessage() uses regex replacement for each argument, which can be inefficient for multiple replacements. Consider using a more efficient approach or leveraging existing libraries.

If you decide to keep the custom logging:

private static String formatMessage(String format, Object... args) {
-   for (Object arg : args) {
-       format = format.replaceFirst("\\{\\}", arg == null ? "null" : arg.toString());
-   }
-   return format;
+   StringBuilder result = new StringBuilder(format);
+   for (Object arg : args) {
+       int index = result.indexOf("{}");
+       if (index != -1) {
+           result.replace(index, index + 2, arg == null ? "null" : arg.toString());
+       }
+   }
+   return result.toString();
}

34-149: Missing @after method for proper cleanup.

The test class is missing an @After method to properly clean up resources after tests. Consider adding one to release resources and reset the state.

+ import org.junit.After;
+ 
+ ...
+
+ @After
+ public void tearDown() {
+     // Clear any caches or connections that might be held by the wallet
+     if (wallet != null) {
+         wallet.shutdownAutosaveAndWait();
+         // Add any other necessary cleanup
+     }
+ }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 07d5be0 and 4af148d.

📒 Files selected for processing (6)
  • .run/WalletTool CJ Mix.run.xml (1 hunks)
  • .run/WalletTool CJ Sync.run.xml (1 hunks)
  • .run/WalletTool CJ address (devnet).run.xml (1 hunks)
  • core/src/main/java/org/bitcoinj/wallet/Wallet.java (1 hunks)
  • core/src/test/java/org/bitcoinj/wallet/LargeCoinJoinWalletTest.java (1 hunks)
  • examples/src/main/java/org/bitcoinj/examples/RestoreFromSeedThenDump.java (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (2)
  • GitHub Check: JAVA 11 OS macOS-latest Gradle
  • GitHub Check: Analyze (java)
🔇 Additional comments (10)
core/src/main/java/org/bitcoinj/wallet/Wallet.java (3)

3267-3277: Good performance optimization in getTransactions method!

Pre-allocating the HashSet capacity based on the combined size of all transaction pools is a nice performance improvement. This avoids expensive HashSet resizing operations when dealing with wallets that have many transactions.


3284-3291: Excellent addition of a lightweight transaction count method.

This new method provides an efficient way to get just the count of transactions without creating a collection. This is more performant than calling getTransactions().size() when only the count is needed.


3297-3311: Well-implemented transaction list retrieval method.

Adding a method that returns a List instead of a Set is a useful addition, especially when order matters or when working with APIs that expect lists. The pre-allocation of the ArrayList size is a good performance practice, consistent with the improvements to getTransactions().

.run/WalletTool CJ Sync.run.xml (1)

5-5: Added debug logging capability to wallet synchronization.

The addition of the --debuglog flag will provide more detailed logging during wallet synchronization, which is helpful for troubleshooting transaction retrieval issues.

.run/WalletTool CJ Mix.run.xml (1)

4-5: Updated module path and optimized CoinJoin mixing parameters.

The configuration has been standardized to use the common module path and the CoinJoin mixing parameters have been adjusted:

  • Increased mix amount from 0.15 to 0.50
  • Reduced sessions from 8 to 6
  • Removed the "--multi-session" flag
  • Added debug logging

These changes likely represent optimizations to the mixing process based on testing.

examples/src/main/java/org/bitcoinj/examples/RestoreFromSeedThenDump.java (3)

32-32: Added import for WalletEx to support CoinJoin functionality.

This import is necessary for using the extended wallet implementation with CoinJoin support.


88-88: Updated to use WalletEx instead of Wallet.

Switching to WalletEx enables enhanced wallet capabilities, particularly for CoinJoin operations, while maintaining the same initialization parameters.


94-94: Added CoinJoin initialization.

The new initializeCoinJoin(0) call properly sets up the wallet for CoinJoin functionality with account index 0, which is essential for the improved transaction handling mentioned in the PR objectives.

core/src/test/java/org/bitcoinj/wallet/LargeCoinJoinWalletTest.java (2)

34-38: The test class setup looks good.

The class correctly defines the necessary fields for testing a large CoinJoin wallet including the wallet instance, test parameters, and logging.


40-52:

✅ Verification successful

Verify the test wallet file availability.

The test depends on a resource file coinjoin-large.wallet which might not be included in the repository. Ensure this file is available or provide clear documentation on how to generate it.


🏁 Script executed:

#!/bin/bash
# Check if the test wallet file exists in resources

echo "Checking for test wallet file..."
WALLET_PATH=$(find . -name "coinjoin-large.wallet" -type f)

if [ -z "$WALLET_PATH" ]; then
  echo "WARNING: Test wallet file 'coinjoin-large.wallet' not found in resources."
  echo "This test will fail without this file."
else
  echo "Found test wallet file at: $WALLET_PATH"
  ls -la "$WALLET_PATH"
fi

Length of output: 679


Test Wallet Resource Verified
The coinjoin-large.wallet file is present at core/src/test/resources/org/bitcoinj/wallet/coinjoin-large.wallet, so the setup in LargeCoinJoinWalletTest will succeed as expected.

Comment on lines +54 to +63
@Test
public void coinJoinInfoTest() {
info("rounds: {}", wallet.coinjoin.rounds);

Stopwatch watch0 = Stopwatch.createStarted();
info("key usage: {}; time: {}", wallet.coinjoin.getKeyUsage(), watch0);
Stopwatch watch1 = Stopwatch.createStarted();
wallet.coinjoin.refreshUnusedKeys();
info("unused key count: {}; time: {}", wallet.coinjoin.getUnusedKeyCount(), watch1);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add assertions to validate CoinJoin information.

This test method executes operations but doesn't assert that the results meet any expected criteria. Without assertions, it functions more as a performance benchmark than a validation test.

@Test
public void coinJoinInfoTest() {
    info("rounds: {}", wallet.coinjoin.rounds);

    Stopwatch watch0 = Stopwatch.createStarted();
-   info("key usage: {}; time: {}", wallet.coinjoin.getKeyUsage(), watch0);
+   int keyUsage = wallet.coinjoin.getKeyUsage();
+   info("key usage: {}; time: {}", keyUsage, watch0);
+   // Assert expected key usage values
+   assertTrue("Key usage should be positive", keyUsage > 0);
    
    Stopwatch watch1 = Stopwatch.createStarted();
    wallet.coinjoin.refreshUnusedKeys();
-   info("unused key count: {}; time: {}", wallet.coinjoin.getUnusedKeyCount(), watch1);
+   int unusedKeyCount = wallet.coinjoin.getUnusedKeyCount();
+   info("unused key count: {}; time: {}", unusedKeyCount, watch1);
+   // Assert expected unused key count
+   assertTrue("Unused key count should be positive after refresh", unusedKeyCount > 0);
}
📝 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.

Suggested change
@Test
public void coinJoinInfoTest() {
info("rounds: {}", wallet.coinjoin.rounds);
Stopwatch watch0 = Stopwatch.createStarted();
info("key usage: {}; time: {}", wallet.coinjoin.getKeyUsage(), watch0);
Stopwatch watch1 = Stopwatch.createStarted();
wallet.coinjoin.refreshUnusedKeys();
info("unused key count: {}; time: {}", wallet.coinjoin.getUnusedKeyCount(), watch1);
}
@Test
public void coinJoinInfoTest() {
info("rounds: {}", wallet.coinjoin.rounds);
Stopwatch watch0 = Stopwatch.createStarted();
int keyUsage = wallet.coinjoin.getKeyUsage();
info("key usage: {}; time: {}", keyUsage, watch0);
// Assert expected key usage values
assertTrue("Key usage should be positive", keyUsage > 0);
Stopwatch watch1 = Stopwatch.createStarted();
wallet.coinjoin.refreshUnusedKeys();
int unusedKeyCount = wallet.coinjoin.getUnusedKeyCount();
info("unused key count: {}; time: {}", unusedKeyCount, watch1);
// Assert expected unused key count
assertTrue("Unused key count should be positive after refresh", unusedKeyCount > 0);
}

Comment on lines +80 to +89
@Test
public void transactionReportTest() {
Stopwatch watch0 = Stopwatch.createStarted();
wallet.getTransactionReport();
info("getTransactionReport: {}", watch0);

Stopwatch watch1 = Stopwatch.createStarted();
wallet.getTransactionReport();
info("getTransactionReport: {}", watch1);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add validation for transaction report test.

This test runs the transaction report twice but doesn't validate the output. Consider adding assertions to verify the report's correctness or at least checking for non-null results.

@Test
public void transactionReportTest() {
    Stopwatch watch0 = Stopwatch.createStarted();
-   wallet.getTransactionReport();
+   String report1 = wallet.getTransactionReport();
    info("getTransactionReport: {}", watch0);
+   
+   // Validate that the report is properly generated
+   assertNotNull("Transaction report should not be null", report1);
+   assertFalse("Transaction report should not be empty", report1.isEmpty());

    Stopwatch watch1 = Stopwatch.createStarted();
-   wallet.getTransactionReport();
+   String report2 = wallet.getTransactionReport();
    info("getTransactionReport: {}", watch1);
+   
+   // Ensure the reports are consistent
+   assertEquals("Transaction reports should be consistent", report1, report2);
}
📝 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.

Suggested change
@Test
public void transactionReportTest() {
Stopwatch watch0 = Stopwatch.createStarted();
wallet.getTransactionReport();
info("getTransactionReport: {}", watch0);
Stopwatch watch1 = Stopwatch.createStarted();
wallet.getTransactionReport();
info("getTransactionReport: {}", watch1);
}
@Test
public void transactionReportTest() {
Stopwatch watch0 = Stopwatch.createStarted();
String report1 = wallet.getTransactionReport();
info("getTransactionReport: {}", watch0);
// Validate that the report is properly generated
assertNotNull("Transaction report should not be null", report1);
assertFalse("Transaction report should not be empty", report1.isEmpty());
Stopwatch watch1 = Stopwatch.createStarted();
String report2 = wallet.getTransactionReport();
info("getTransactionReport: {}", watch1);
// Ensure the reports are consistent
assertEquals("Transaction reports should be consistent", report1, report2);
}

Comment on lines +110 to +127
@Test
public void getTransactionsTest() {
Stopwatch watch0 = Stopwatch.createStarted();
wallet.getTransactionCount(true);
info("wallet.getTransactionCount: {}", watch0);

Stopwatch watch1 = Stopwatch.createStarted();
wallet.getTransactions(true);
info("wallet.getTransactions: {}", watch1);

Stopwatch watch2 = Stopwatch.createStarted();
wallet.getTransactionList(true);
info("wallet.getTransactionList: {}", watch2);

Stopwatch watch3 = Stopwatch.createStarted();
wallet.getWalletTransactions();
info("wallet.getWalletTransactions(): {}", watch3);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add assertions to validate transaction retrieval methods.

This method tests the new transaction retrieval methods but doesn't verify their correctness. Add assertions to ensure the methods return the expected results.

@Test
public void getTransactionsTest() {
    Stopwatch watch0 = Stopwatch.createStarted();
-   wallet.getTransactionCount(true);
+   int transactionCount = wallet.getTransactionCount(true);
    info("wallet.getTransactionCount: {}", watch0);
+   assertTrue("Transaction count should be positive", transactionCount > 0);

    Stopwatch watch1 = Stopwatch.createStarted();
-   wallet.getTransactions(true);
+   Set<Transaction> transactions = wallet.getTransactions(true);
    info("wallet.getTransactions: {}", watch1);
+   assertNotNull("Transactions set should not be null", transactions);
+   assertEquals("Transaction count should match set size", transactionCount, transactions.size());

    Stopwatch watch2 = Stopwatch.createStarted();
-   wallet.getTransactionList(true);
+   List<Transaction> transactionList = wallet.getTransactionList(true);
    info("wallet.getTransactionList: {}", watch2);
+   assertNotNull("Transaction list should not be null", transactionList);
+   assertEquals("Transaction list size should match count", transactionCount, transactionList.size());

    Stopwatch watch3 = Stopwatch.createStarted();
-   wallet.getWalletTransactions();
+   Iterable<WalletTransaction> walletTransactions = wallet.getWalletTransactions();
    info("wallet.getWalletTransactions(): {}", watch3);
+   assertNotNull("Wallet transactions should not be null", walletTransactions);
+   
+   // Count the wallet transactions
+   int walletTransactionCount = 0;
+   for (WalletTransaction ignored : walletTransactions) {
+       walletTransactionCount++;
+   }
+   assertTrue("Wallet should contain transactions", walletTransactionCount > 0);
}
📝 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.

Suggested change
@Test
public void getTransactionsTest() {
Stopwatch watch0 = Stopwatch.createStarted();
wallet.getTransactionCount(true);
info("wallet.getTransactionCount: {}", watch0);
Stopwatch watch1 = Stopwatch.createStarted();
wallet.getTransactions(true);
info("wallet.getTransactions: {}", watch1);
Stopwatch watch2 = Stopwatch.createStarted();
wallet.getTransactionList(true);
info("wallet.getTransactionList: {}", watch2);
Stopwatch watch3 = Stopwatch.createStarted();
wallet.getWalletTransactions();
info("wallet.getWalletTransactions(): {}", watch3);
}
@Test
public void getTransactionsTest() {
Stopwatch watch0 = Stopwatch.createStarted();
int transactionCount = wallet.getTransactionCount(true);
info("wallet.getTransactionCount: {}", watch0);
assertTrue("Transaction count should be positive", transactionCount > 0);
Stopwatch watch1 = Stopwatch.createStarted();
Set<Transaction> transactions = wallet.getTransactions(true);
info("wallet.getTransactions: {}", watch1);
assertNotNull("Transactions set should not be null", transactions);
assertEquals("Transaction count should match set size", transactionCount, transactions.size());
Stopwatch watch2 = Stopwatch.createStarted();
List<Transaction> transactionList = wallet.getTransactionList(true);
info("wallet.getTransactionList: {}", watch2);
assertNotNull("Transaction list should not be null", transactionList);
assertEquals("Transaction list size should match count", transactionCount, transactionList.size());
Stopwatch watch3 = Stopwatch.createStarted();
Iterable<WalletTransaction> walletTransactions = wallet.getWalletTransactions();
info("wallet.getWalletTransactions(): {}", watch3);
assertNotNull("Wallet transactions should not be null", walletTransactions);
// Count the wallet transactions
int walletTransactionCount = 0;
for (WalletTransaction ignored : walletTransactions) {
walletTransactionCount++;
}
assertTrue("Wallet should contain transactions", walletTransactionCount > 0);
}

Comment on lines +91 to +108
public void walletToStringTest() {
@Test
Stopwatch watch0 = Stopwatch.createStarted();
wallet.toString(true, false, true, null);
info("wallet.toString: {}", watch0);

Stopwatch watch1 = Stopwatch.createStarted();
wallet.toString(true, false, true, null);
info("wallet.toString: {}", watch1);

Stopwatch watch2 = Stopwatch.createStarted();
wallet.coinjoin.toString();
info("wallet.coinjoin.toString: {}", watch2);

Stopwatch watch3 = Stopwatch.createStarted();
wallet.coinjoin.toString(true, false, null);
info("wallet.coinjoin.toString(true, false, null): {}", watch3);
}
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Add validation to the toString test method.

Similar to the transaction report test, this method exercises various toString methods but doesn't validate their output. Consider adding basic assertions to ensure the methods return meaningful results.

@Test
public void walletToStringTest() {
    Stopwatch watch0 = Stopwatch.createStarted();
-   wallet.toString(true, false, true, null);
+   String walletStr1 = wallet.toString(true, false, true, null);
    info("wallet.toString: {}", watch0);
+   assertNotNull("Wallet toString should not be null", walletStr1);
+   assertFalse("Wallet toString should not be empty", walletStr1.isEmpty());

    Stopwatch watch1 = Stopwatch.createStarted();
-   wallet.toString(true, false, true, null);
+   String walletStr2 = wallet.toString(true, false, true, null);
    info("wallet.toString: {}", watch1);
+   assertEquals("Wallet toString should be consistent", walletStr1, walletStr2);

    Stopwatch watch2 = Stopwatch.createStarted();
-   wallet.coinjoin.toString();
+   String coinjoinStr = wallet.coinjoin.toString();
    info("wallet.coinjoin.toString: {}", watch2);
+   assertNotNull("CoinJoin toString should not be null", coinjoinStr);
+   assertFalse("CoinJoin toString should not be empty", coinjoinStr.isEmpty());

    Stopwatch watch3 = Stopwatch.createStarted();
-   wallet.coinjoin.toString(true, false, null);
+   String coinjoinDetailedStr = wallet.coinjoin.toString(true, false, null);
    info("wallet.coinjoin.toString(true, false, null): {}", watch3);
+   assertNotNull("CoinJoin detailed toString should not be null", coinjoinDetailedStr);
+   assertFalse("CoinJoin detailed toString should not be empty", coinjoinDetailedStr.isEmpty());
}

Copy link
Member
@Syn-McJ Syn-McJ left a comment

Choose a reason for hiding this comment

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

Looks good

@HashEngineering HashEngineering merged commit c285bee into master May 6, 2025
6 of 8 checks passed
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.

2 participants
0