Skip to content

fix(dapi): use deterministic keys in subscribeToNewTransactions test to prevent bloom filter false positives#3160

Open
thepastaclaw wants to merge 2 commits intodashpay:v3.1-devfrom
thepastaclaw:fix/dapi-flaky-bloom-filter-test
Open

fix(dapi): use deterministic keys in subscribeToNewTransactions test to prevent bloom filter false positives#3160
thepastaclaw wants to merge 2 commits intodashpay:v3.1-devfrom
thepastaclaw:fix/dapi-flaky-bloom-filter-test

Conversation

@thepastaclaw
Copy link
Contributor

@thepastaclaw thepastaclaw commented Feb 25, 2026

Issue

The subscribeToNewTransactions integration test in packages/dapi is flaky — it intermittently fails with:

AssertionError: expected [ …(2) ] to deeply equal [ …(1) ]

This was blocking CI on unrelated PRs like #3089.

Root Cause

The test creates two addresses from new PrivateKey() (random each run) and sets up a bloom filter for only the first address. Bloom filters are probabilistic — random addresses can occasionally produce hash collisions, causing the filter to match transactions sent to anotherAddress when it shouldn't.

Important context: This test is fully synthetic — no live network data is involved:

  • beforeEach creates local tx/block/instant-lock objects from scratch
  • The test feeds them through bloomFilterEmitterCollection.test() and .emit()
  • No network calls happen in this test path

Everything in the test is already deterministic (transactions, blocks, instant locks, bloom filter parameters) — except the private keys. new PrivateKey() was the sole non-deterministic input, generating random addresses each run. Occasionally those random addresses would collide in the bloom filter, causing a false positive and a test failure.

Fix

Replace random private keys with fixed, deterministic hex keys that are verified not to collide under BloomFilter.create(1, 0.0001). This eliminates the source of non-determinism while preserving the test's intent (verifying that only matching transactions pass through the filter).

This makes the last non-deterministic input deterministic, so the entire test is now fully reproducible across runs. Bloom filters remain probabilistic in production; this just ensures the test fixtures don't accidentally trigger that probabilism.

1 file changed, 5 insertions, 2 deletions.

Validation

  • Ran the test 20 consecutive times locally — 0 failures
  • With the old random keys, failures were intermittent (roughly 1 in ~50 runs)

Summary by CodeRabbit

  • Tests
    • Improved stability of transaction filtering test suite by implementing deterministic test data initialization, eliminating intermittent test failures and ensuring consistent test execution.

The test used random PrivateKey() instances for address generation.
Since bloom filters are probabilistic, random addresses can occasionally
produce false positive matches (anotherAddress matching a filter built
for address), causing the 'should send instant locks for new
transactions' assertion to fail intermittently.

Replace random keys with fixed deterministic private keys that are
verified to not collide in the bloom filter configuration used by the
test (BloomFilter.create(1, 0.0001)).
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 25, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5dcbf97 and 5ffc00c.

📒 Files selected for processing (1)
  • packages/dapi/test/integration/transactionsFilter/subscribeToNewTransactions.spec.js

📝 Walkthrough

Walkthrough

Tests updated to replace randomly generated private keys with deterministic PrivateKey instances (explicit hex seeds) in bloom filter address setup to stabilize test addresses and prevent intermittent false positives.

Changes

Cohort / File(s) Summary
Test Determinism
packages/dapi/test/integration/transactionsFilter/subscribeToNewTransactions.spec.js
Replaced random private key generation with deterministic PrivateKey instances using explicit hex seeds in the test setup to stabilize bloom filter address inputs and avoid flaky failures.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~8 minutes

Poem

🐰 Hoppity-hop, the test seeds are sown,
No more random hops—determinism's grown!
Bloom filters steady, no false alarms found,
Stable little warren on dependable ground. 🌱✨

🚥 Pre-merge checks | ✅ 3
✅ 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 accurately describes the main change: replacing random keys with deterministic keys to fix flaky bloom filter tests in the subscribeToNewTransactions integration test.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

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: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@packages/dapi/test/integration/transactionsFilter/subscribeToNewTransactions.spec.js`:
- Around line 45-46: The hex string assigned to anotherAddress is 63 characters
long and will be truncated by Buffer.from when PrivateKey is constructed; update
the string used to create anotherAddress (the argument passed into new
PrivateKey(...).toAddress()) so it is exactly 64 hex characters (for example by
prepending a '0') so the PrivateKey receives a full 32-byte buffer.

ℹ️ Review info

Configuration used: defaults

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 8e90ceb and 5dcbf97.

📒 Files selected for processing (1)
  • packages/dapi/test/integration/transactionsFilter/subscribeToNewTransactions.spec.js

@thepastaclaw
Copy link
Contributor Author

Hey @QuantumExplorer @shumkov — friendly ping for review on this one when you get a chance. 🙏

Quick summary: this fixes a known flaky test in subscribeToNewTransactions by using deterministic private keys instead of random ones, which prevents bloom filter false positives from causing intermittent failures.

CI is all green ✅ and the change is small (single test file).

@PastaPastaPasta PastaPastaPasta marked this pull request as draft February 26, 2026 00:12
The second deterministic key was 63 hex chars (odd length), which causes
Node.js Buffer.from(hex) to silently truncate to 31 bytes. Prepend '0'
to make it a proper 64-char (32-byte) private key.
@thepastaclaw
Copy link
Contributor Author

Addressed CodeRabbit feedback on the 63-char hex key: prepended 0 to make it a proper 64-char (32-byte) key in 5ffc00c. The odd-length string was causing silent truncation via Buffer.from(hex).

@PastaPastaPasta PastaPastaPasta added the ready for final review Ready for the final review. If AI was involved in producing this PR, it has already had a reviewer. label Feb 26, 2026
@PastaPastaPasta PastaPastaPasta marked this pull request as ready for review February 26, 2026 05:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for final review Ready for the final review. If AI was involved in producing this PR, it has already had a reviewer.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants