Skip to content

fix(key-wallet): extend gap limit for operator keys like owner/voting keys#882

Merged
QuantumExplorer merged 1 commit into
devfrom
claude/operator-gap-limit
Jul 14, 2026
Merged

fix(key-wallet): extend gap limit for operator keys like owner/voting keys#882
QuantumExplorer merged 1 commit into
devfrom
claude/operator-gap-limit

Conversation

@QuantumExplorer

Copy link
Copy Markdown
Member

Problem

When a ProRegTx/ProUpRegTx marks a provider key as used, wallet_checker runs maintain_gap_limit on the matched account's pools — but it obtained the derivation key via extended_public_key_for_account_type, which returns None for BLS accounts ("These use BLS/EdDSA keys, not regular xpubs"), so the loop continued before gap maintenance. Result: owner and voting pools extend past used keys, the operator pool never does. A wallet whose pre-generated operator keys were all consumed by registrations would stop detecting registrations made with its next operator keys.

All the machinery below the checker already supported this: KeySource::BLSPublic does legacy-scheme non-hardened derivation (the same path used to pre-generate the pool), and the operator pool is AddressPoolType::Absent (non-hardened), so watch-side extension is possible.

Changes

  • Wallet::key_source_for_account_type (new, in wallet/helper.rs): key-source counterpart of extended_public_key_for_account_type. ECDSA accounts yield KeySource::Public; the provider operator account yields KeySource::BLSPublic from its stored account xpub; account types that cannot derive publicly yield NoKeySource.
  • wallet_checker: gap maintenance now sources its key through the new helper and only skips on NoKeySource, so operator pools extend exactly like owner/voting pools.
  • Platform-node (EdDSA) pools remain excluded — SLIP-0010 supports hardened derivation only, so extending them requires the seed, which the checker doesn't (and shouldn't) hold. This is now documented on the helper rather than implicit in a None.

Tests

provider_registration_extends_operator_key_gap_limit: derives operator key 0, processes a ProRegTx carrying it, and asserts the pool extends to highest_used + gap_limit, with the freshly derived entries surfaced in new_addresses and their BLS public keys matching the audited operator_public_key_at entry point (#880/#881). Verified the test fails without the source change (pool stays at the pre-generated window, Some(4) != Some(5)).

Full cargo test -p key-wallet --all-features (544 passed), clippy -D warnings, and fmt are clean; key-wallet-ffi, key-wallet-manager, and dash-spv still compile.

🤖 Generated with Claude Code

… keys

When a ProRegTx/ProUpRegTx marks a provider key as used, wallet_checker
runs maintain_gap_limit on the account's pools — but it sourced the
derivation key via extended_public_key_for_account_type, which returns
None for BLS accounts, so the operator pool was silently skipped while
the ECDSA owner/voting pools were extended. A wallet whose operator keys
were all registered would stop detecting registrations with its next
operator keys.

Add Wallet::key_source_for_account_type, which yields
KeySource::BLSPublic (legacy-scheme non-hardened derivation, matching
how the pool addresses were generated) for the operator account and
KeySource::Public for ECDSA accounts, and route wallet_checker's gap
maintenance through it. Platform-node (EdDSA) pools remain excluded:
SLIP-0010 supports hardened derivation only, so they cannot be extended
from a public key.

The regression test pins the semantics: after a ProRegTx uses operator
key 0, the pool extends to highest_used + gap_limit and the freshly
derived entries carry BLS public keys matching the audited
operator_public_key_at entry point.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Jul 14, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

@QuantumExplorer, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 29 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: cd2b0647-9802-4b48-a345-f30752283b2c

📥 Commits

Reviewing files that changed from the base of the PR and between bc6cbf9 and b52200e.

📒 Files selected for processing (3)
  • key-wallet/src/tests/special_transaction_matching_tests.rs
  • key-wallet/src/transaction_checking/wallet_checker.rs
  • key-wallet/src/wallet/helper.rs
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/operator-gap-limit

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.

@codecov

codecov Bot commented Jul 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 74.28%. Comparing base (bc6cbf9) to head (b52200e).

Additional details and impacted files
@@            Coverage Diff             @@
##              dev     #882      +/-   ##
==========================================
+ Coverage   74.23%   74.28%   +0.04%     
==========================================
  Files         326      326              
  Lines       74585    74602      +17     
==========================================
+ Hits        55370    55415      +45     
+ Misses      19215    19187      -28     
Flag Coverage Δ
core 77.09% <ø> (ø)
ffi 50.31% <ø> (ø)
rpc 20.00% <ø> (ø)
spv 91.08% <ø> (+0.14%) ⬆️
wallet 74.32% <100.00%> (+0.03%) ⬆️
Files with missing lines Coverage Δ
...-wallet/src/transaction_checking/wallet_checker.rs 99.24% <ø> (ø)
key-wallet/src/wallet/helper.rs 67.68% <100.00%> (+1.76%) ⬆️

... and 7 files with indirect coverage changes

@QuantumExplorer QuantumExplorer merged commit be18425 into dev Jul 14, 2026
35 checks passed
@QuantumExplorer QuantumExplorer deleted the claude/operator-gap-limit branch July 14, 2026 04:21
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.

1 participant