Skip to content

Conversation

@xdustinface
Copy link
Collaborator

@xdustinface xdustinface commented Dec 30, 2025

The thread sanitizer in #253 found the issues fixed in here. X11 hash requires exactly 80 bytes (block header size). The tests adjusted in this PR were incorrectly passing small data leading to out of bounds memory reads. Now they just use test_block_hash helper to pass a mock hash.

Summary by CodeRabbit

  • Tests

    • Enhanced test infrastructure with new testing utilities for improved test consistency and maintainability.
  • Chores

    • Updated development dependencies to support testing improvements.

✏️ Tip: You can customize this high-level summary in your review settings.

The thread sanitizer in #253 found the issues fixed in here. X11 hash requires exactly 80 bytes (block header size).
The tests adjusted in this PR were incorrectly passing small data leading to out of bounds memory reads.
Now they just use `test_block_hash` helper to pass a mock hash.
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Dec 30, 2025

📝 Walkthrough

Walkthrough

Added a new test helper function test_block_hash() in the test-utils fixtures module. Updated existing chainlock and checkpoint tests to use this helper for consistent BlockHash construction instead of manual hashing.

Changes

Cohort / File(s) Summary
Dependency Addition
dash-spv/Cargo.toml
Added dev-dependency: dashcore-test-utils with path reference to ../test-utils
Test Fixture Function
test-utils/src/fixtures.rs
Added new public function test_block_hash(id: u32) -> BlockHash that constructs block hashes from a 4-byte little-endian ID value
Test Updates
dash-spv/src/chain/chainlock_test.rs, dash-spv/src/chain/checkpoint_test.rs
Replaced manual BlockHash construction with calls to test_block_hash() helper throughout test cases; imports updated to include the new fixture function

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

A helper born from test-utils' care,
Block hashes summoned with fixture's flair!
No more the tedious hash creation spree,
test_block_hash sets test data free! 🐰
Clean tests now dance with joy so bright!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: avoid X11 hash with wrong input size in tests' accurately describes the main purpose of the PR, which is to fix test code that was calling X11 hash with incorrectly-sized inputs by replacing those calls with a test helper function.
Docstring Coverage ✅ Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%.
✨ 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

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@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 (1)
test-utils/src/fixtures.rs (1)

41-46: Consider adding a unit test for the new helper function.

The implementation of test_block_hash is correct and provides deterministic test hashes. However, consider adding a test to verify:

  • Distinct ids produce distinct hashes
  • The function is deterministic (same id always produces same hash)
  • The hash format matches expectations
🔎 Suggested test addition

Add to the tests module at the end of the file:

#[test]
fn test_block_hash_determinism_and_uniqueness() {
    let hash1 = test_block_hash(1);
    let hash2 = test_block_hash(2);
    let hash1_again = test_block_hash(1);
    
    // Same id should produce same hash
    assert_eq!(hash1, hash1_again);
    
    // Different ids should produce different hashes
    assert_ne!(hash1, hash2);
    
    // Verify the id is encoded in the hash (first 4 bytes)
    let bytes1: &[u8] = hash1.as_ref();
    assert_eq!(bytes1[0..4], 1u32.to_le_bytes());
}
📜 Review details

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 3884314 and e1896db.

📒 Files selected for processing (4)
  • dash-spv/Cargo.toml
  • dash-spv/src/chain/chainlock_test.rs
  • dash-spv/src/chain/checkpoint_test.rs
  • test-utils/src/fixtures.rs
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{rs,toml}

📄 CodeRabbit inference engine (CLAUDE.md)

Never hardcode network parameters, addresses, or keys

Files:

  • test-utils/src/fixtures.rs
  • dash-spv/src/chain/chainlock_test.rs
  • dash-spv/Cargo.toml
  • dash-spv/src/chain/checkpoint_test.rs
**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.rs: Use proper error types (thiserror) and propagate errors appropriately
Use tokio runtime for async operations
Use conditional compilation with feature flags for optional features
Write unit tests for new functionality
Use secure random number generation for keys
Never log or expose private keys
Code must target Rust 1.89 minimum supported version (MSRV)
Format code using cargo fmt
Pass clippy linting without warnings

**/*.rs: MSRV (Minimum Supported Rust Version) is 1.89; ensure compatibility with this version for all builds
Unit tests should live alongside code with #[cfg(test)] annotation; integration tests use the tests/ directory
Use snake_case for function and variable names
Use UpperCamelCase for types and traits
Use SCREAMING_SNAKE_CASE for constants
Format code with rustfmt before commits; ensure cargo fmt --all is run
Run cargo clippy --workspace --all-targets -- -D warnings for linting; avoid warnings in CI
Prefer async/await via tokio for asynchronous operations

Files:

  • test-utils/src/fixtures.rs
  • dash-spv/src/chain/chainlock_test.rs
  • dash-spv/src/chain/checkpoint_test.rs
dash-spv/**/*.rs

📄 CodeRabbit inference engine (dash-spv/CLAUDE.md)

dash-spv/**/*.rs: Use async/await throughout the codebase, built on tokio runtime
Use Arc for trait objects to enable runtime polymorphism for NetworkManager and StorageManager
Use Tokio channels for inter-component message passing between async tasks
Maintain minimum Rust version (MSRV) of 1.89 and use only compatible syntax and features

Files:

  • dash-spv/src/chain/chainlock_test.rs
  • dash-spv/src/chain/checkpoint_test.rs
**/{dash-network,dash-spv,key-wallet}/**/*.rs

📄 CodeRabbit inference engine (CLAUDE.md)

Use async/await for async operations in network and wallet modules

Files:

  • dash-spv/src/chain/chainlock_test.rs
  • dash-spv/src/chain/checkpoint_test.rs
🧠 Learnings (20)
📓 Common learnings
Learnt from: DCG-Claude
Repo: dashpay/rust-dashcore PR: 0
File: :0-0
Timestamp: 2025-06-26T15:47:37.438Z
Learning: Transaction IDs (txids) and block hashes in Dash are always 32 bytes and should be passed as fixed-size byte arrays in FFI interfaces, not as C strings, to avoid inefficiency and encoding issues.
📚 Learning: 2025-12-01T07:59:58.608Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-12-01T07:59:58.608Z
Learning: Applies to dash-spv-ffi/tests/unit/**/*.rs : Add corresponding unit tests in `tests/unit/` for each new FFI function

Applied to files:

  • test-utils/src/fixtures.rs
  • dash-spv/src/chain/chainlock_test.rs
  • dash-spv/Cargo.toml
  • dash-spv/src/chain/checkpoint_test.rs
📚 Learning: 2025-06-26T15:47:37.438Z
Learnt from: DCG-Claude
Repo: dashpay/rust-dashcore PR: 0
File: :0-0
Timestamp: 2025-06-26T15:47:37.438Z
Learning: Transaction IDs (txids) and block hashes in Dash are always 32 bytes and should be passed as fixed-size byte arrays in FFI interfaces, not as C strings, to avoid inefficiency and encoding issues.

Applied to files:

  • test-utils/src/fixtures.rs
📚 Learning: 2025-12-16T09:03:55.811Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-16T09:03:55.811Z
Learning: Applies to dash-spv/tests/**/*.rs : Organize tests into unit tests (in-module), integration tests (tests/ directory), real network tests (with live Dash Core nodes), and performance benchmarks

Applied to files:

  • dash-spv/src/chain/chainlock_test.rs
  • dash-spv/Cargo.toml
  • dash-spv/src/chain/checkpoint_test.rs
📚 Learning: 2025-12-16T09:03:55.811Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-16T09:03:55.811Z
Learning: Applies to dash-spv/tests/**/*.rs : Integration tests should gracefully handle unavailable Dash Core nodes at 127.0.0.1:9999 without failing the test suite

Applied to files:

  • dash-spv/src/chain/chainlock_test.rs
  • dash-spv/Cargo.toml
  • dash-spv/src/chain/checkpoint_test.rs
📚 Learning: 2025-12-16T09:03:55.811Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-16T09:03:55.811Z
Learning: Applies to dash-spv/src/sync/**/*.rs : Implement sequential phase-based synchronization via SyncManager with phases progressing in order: Headers → Masternode List → Filter Headers → Filters → Blocks

Applied to files:

  • dash-spv/src/chain/chainlock_test.rs
📚 Learning: 2025-12-22T17:59:37.849Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-22T17:59:37.849Z
Learning: Applies to **/{dash-network,dash-spv,key-wallet}/**/*.rs : Use async/await for async operations in network and wallet modules

Applied to files:

  • dash-spv/src/chain/chainlock_test.rs
  • dash-spv/Cargo.toml
📚 Learning: 2025-12-22T17:59:37.849Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-22T17:59:37.849Z
Learning: Applies to **/tests/**/*.rs : Test both mainnet and testnet configurations

Applied to files:

  • dash-spv/src/chain/chainlock_test.rs
📚 Learning: 2025-12-22T17:59:37.849Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-22T17:59:37.849Z
Learning: Applies to **/tests/**/*.rs : Create integration tests for network operations

Applied to files:

  • dash-spv/src/chain/chainlock_test.rs
📚 Learning: 2025-12-16T09:03:55.811Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-16T09:03:55.811Z
Learning: Applies to dash-spv/**/*.rs : Use Arc<dyn TraitName> for trait objects to enable runtime polymorphism for NetworkManager and StorageManager

Applied to files:

  • dash-spv/src/chain/chainlock_test.rs
📚 Learning: 2025-12-19T00:07:22.904Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: key-wallet/CLAUDE.md:0-0
Timestamp: 2025-12-19T00:07:22.904Z
Learning: Applies to key-wallet/**/*.rs : Always validate network consistency when deriving or validating addresses; never mix mainnet and testnet operations

Applied to files:

  • dash-spv/src/chain/chainlock_test.rs
📚 Learning: 2025-12-16T09:03:55.811Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-16T09:03:55.811Z
Learning: Applies to dash-spv/**/*.rs : Use Tokio channels for inter-component message passing between async tasks

Applied to files:

  • dash-spv/src/chain/chainlock_test.rs
📚 Learning: 2025-12-22T17:59:51.097Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: AGENTS.md:0-0
Timestamp: 2025-12-22T17:59:51.097Z
Learning: Applies to **/tests/**/*.rs : Use descriptive test names (e.g., `test_parse_address_mainnet`)

Applied to files:

  • dash-spv/src/chain/chainlock_test.rs
📚 Learning: 2025-12-16T09:03:55.811Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-16T09:03:55.811Z
Learning: Applies to dash-spv/**/*.rs : Maintain minimum Rust version (MSRV) of 1.89 and use only compatible syntax and features

Applied to files:

  • dash-spv/Cargo.toml
📚 Learning: 2025-12-01T07:59:58.608Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv-ffi/CLAUDE.md:0-0
Timestamp: 2025-12-01T07:59:58.608Z
Learning: Applies to dash-spv-ffi/src/**/*.rs : Use thread-local storage for error propagation via `dash_spv_ffi_get_last_error()` function

Applied to files:

  • dash-spv/Cargo.toml
📚 Learning: 2025-08-21T04:45:50.436Z
Learnt from: QuantumExplorer
Repo: dashpay/rust-dashcore PR: 108
File: key-wallet/src/gap_limit.rs:291-295
Timestamp: 2025-08-21T04:45:50.436Z
Learning: The rust-dashcore project uses Rust 1.89 as evidenced by rust-version = "1.89" in dash-spv/Cargo.toml. Modern Rust features like Option::is_none_or (stabilized in 1.82) can be used safely.

Applied to files:

  • dash-spv/Cargo.toml
📚 Learning: 2025-12-16T09:03:55.811Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-16T09:03:55.811Z
Learning: Applies to dash-spv/**/*.rs : Use async/await throughout the codebase, built on tokio runtime

Applied to files:

  • dash-spv/Cargo.toml
📚 Learning: 2025-12-16T09:03:55.811Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-16T09:03:55.811Z
Learning: Applies to dash-spv/src/client/**/*.rs : Use the DashSpvClient high-level API with proper configuration via ClientConfig for client initialization

Applied to files:

  • dash-spv/Cargo.toml
📚 Learning: 2025-12-16T09:03:55.811Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-16T09:03:55.811Z
Learning: Applies to dash-spv/src/network/**/*.rs : Use DNS-first peer discovery with automatic DNS seeds (dnsseed.dash.org, testnet-seed.dashdot.io) when no explicit peers are configured; implement immediate startup with 10-second delay only for subsequent peer searches

Applied to files:

  • dash-spv/Cargo.toml
📚 Learning: 2025-12-16T09:03:55.811Z
Learnt from: CR
Repo: dashpay/rust-dashcore PR: 0
File: dash-spv/CLAUDE.md:0-0
Timestamp: 2025-12-16T09:03:55.811Z
Learning: Applies to dash-spv/src/validation/**/*.rs : Implement three validation modes: ValidationMode::None (no validation), ValidationMode::Basic (structure and timestamp validation), and ValidationMode::Full (complete PoW and chain validation)

Applied to files:

  • dash-spv/src/chain/checkpoint_test.rs
🧬 Code graph analysis (2)
dash-spv/src/chain/chainlock_test.rs (1)
test-utils/src/fixtures.rs (1)
  • test_block_hash (42-46)
dash-spv/src/chain/checkpoint_test.rs (2)
test-utils/src/fixtures.rs (1)
  • test_block_hash (42-46)
dash-spv/src/types.rs (1)
  • block_hash (72-74)
⏰ 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). (20)
  • GitHub Check: fuzz (hashes_ripemd160)
  • GitHub Check: Pre-commit (macos-latest)
  • GitHub Check: fuzz (dash_deserialize_script)
  • GitHub Check: Pre-commit (ubuntu-latest)
  • GitHub Check: fuzz (hashes_sha512)
  • GitHub Check: fuzz (dash_deserialize_address)
  • GitHub Check: fuzz (hashes_sha256)
  • GitHub Check: fuzz (hashes_cbor)
  • GitHub Check: fuzz (hashes_json)
  • GitHub Check: fuzz (dash_deserialize_amount)
  • GitHub Check: fuzz (hashes_sha512_256)
  • GitHub Check: fuzz (dash_deserialize_witness)
  • GitHub Check: fuzz (dash_outpoint_string)
  • GitHub Check: fuzz (dash_script_bytes_to_asm_fmt)
  • GitHub Check: fuzz (hashes_sha1)
  • GitHub Check: fuzz (dash_deser_net_msg)
  • GitHub Check: Key Wallet Components Tests
  • GitHub Check: SPV Components Tests
  • GitHub Check: RPC Tests (stable, true)
  • GitHub Check: Core Components Tests
🔇 Additional comments (4)
dash-spv/Cargo.toml (1)

68-68: LGTM!

The addition of dashcore-test-utils as a dev-dependency correctly enables test fixtures without impacting production builds.

dash-spv/src/chain/checkpoint_test.rs (1)

10-34: LGTM!

The refactored create_test_checkpoint correctly uses test_block_hash to avoid X11 hash computation with incorrect input sizes. The prev_blockhash logic (using test_block_hash(height - 1) or BlockHash::all_zeros() for genesis) is appropriate and preserves test semantics.

dash-spv/src/chain/chainlock_test.rs (2)

5-6: LGTM!

The import changes correctly add test_block_hash from the test utilities and streamline the imports by removing unused hash construction dependencies.


19-19: LGTM!

All usages of test_block_hash are correct and provide deterministic block hashes for the ChainLock tests. The choice of ids (1, 2, and height) ensures distinct hashes where needed while maintaining test clarity.

Also applies to: 52-52, 63-63, 91-91

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