Skip to content

feat(platform-wallet): expose sync_watermark() on PlatformAddressWallet#3723

Open
lklimek wants to merge 1 commit into
v3.1-devfrom
feat/platform-wallet-sync-watermark-getter
Open

feat(platform-wallet): expose sync_watermark() on PlatformAddressWallet#3723
lklimek wants to merge 1 commit into
v3.1-devfrom
feat/platform-wallet-sync-watermark-getter

Conversation

@lklimek
Copy link
Copy Markdown
Contributor

@lklimek lklimek commented May 21, 2026

Issue being fixed or feature implemented

The PA-007 / PA-007b e2e tests need to observe incremental-sync progress without depending on the periodic PlatformAddressSyncManager event — they call sync_balances() directly and need to verify the watermark advanced. No public accessor existed.

This PR is the minimal extracted slice from the closed #3647 (which also bundled a controversial update_sync_state monotonic-merge change — that is being abandoned, see #3647 discussion with @QuantumExplorer and @thepastaclaw).

What was done?

  • Added pub(crate) fn last_known_recent_block(&self) -> u64 on PlatformPaymentAddressProvider — crate-visible mirror of the field so wallet-level helpers can read it without going through the AddressProvider trait.
  • Added pub async fn sync_watermark(&self) -> Option<u64> on PlatformAddressWallet. None for "provider not initialised" or "watermark == 0", matching the existing apply_sync_state convention.

No behavioural change to existing call sites — pure additive surface.

How Has This Been Tested?

Breaking Changes

None.

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 added "!" to the title and described breaking changes in the corresponding section if my code contains any
  • I have made corresponding changes to the documentation if needed

🤖 Co-authored by Claudius the Magnificent AI Agent

Summary by CodeRabbit

  • New Features
    • Added blockchain block synchronization watermark tracking to the wallet platform, enabling improved monitoring of the latest processed blocks during wallet synchronization operations.

Review Change Stack

Adds an async accessor for the unified provider's
last_known_recent_block watermark, so callers driving sync_balances()
directly (e.g. PA-007/PA-007b e2e tests) can observe progress without
waiting for the periodic PlatformAddressSyncManager event.

Returns Option<u64> with None for both "provider not initialised" and
"watermark == 0" — the existing apply_sync_state convention.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 2026

📝 Walkthrough

Walkthrough

Two accessor methods expose the sync watermark state: a crate-visible getter in PlatformPaymentAddressProvider returns the internal last_known_recent_block value, and a new async method in PlatformAddressWallet reads this value and normalizes zero or missing provider to None.

Changes

Sync Watermark Accessor Chain

Layer / File(s) Summary
Provider-level watermark accessor
packages/rs-platform-wallet/src/wallet/platform_addresses/provider.rs
Added pub(crate) fn last_known_recent_block(&self) -> u64 to expose the internal watermark field as a read-only accessor.
Wallet sync watermark method
packages/rs-platform-wallet/src/wallet/platform_addresses/wallet.rs
Added pub async fn sync_watermark(&self) -> Option<u64> that acquires a read lock on the provider, retrieves the watermark, and maps zero or missing to None.

Suggested Labels

ready for final review

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Watermarks now flow with clarity bright,
Provider to wallet in sync and in sight,
Zero means nothing, a semantic delight,
Two simple getters get everything right!

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and concisely describes the main addition: exposing sync_watermark() method on PlatformAddressWallet, which is the primary user-facing API change.
Linked Issues check ✅ Passed The PR fully implements all coding objectives from #3647: exposes last_known_recent_block() accessor on PlatformPaymentAddressProvider and adds sync_watermark() method on PlatformAddressWallet with proper None handling for zero values.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the stated objectives: two new accessor methods in platform-wallet package with no unrelated modifications or behavioral changes to existing functionality.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/platform-wallet-sync-watermark-getter

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
Copy Markdown
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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
packages/rs-platform-wallet/src/wallet/platform_addresses/provider.rs (1)

428-430: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Make watermark updates monotonic in update_sync_state.

last_known_recent_block is overwritten directly, so out-of-order sync results can move the watermark backward. That breaks the no-regression objective and can report stale progress via sync_watermark().

Suggested fix
 pub(crate) fn update_sync_state(
     &mut self,
     result: &AddressSyncResult<PlatformAddressTag, PlatformP2PKHAddress>,
 ) {
-    self.sync_height = result.new_sync_height;
-    self.sync_timestamp = result.new_sync_timestamp;
-    self.last_known_recent_block = result.last_known_recent_block;
+    self.sync_height = self.sync_height.max(result.new_sync_height);
+    self.sync_timestamp = self.sync_timestamp.max(result.new_sync_timestamp);
+    self.last_known_recent_block = self
+        .last_known_recent_block
+        .max(result.last_known_recent_block);
 }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@packages/rs-platform-wallet/src/wallet/platform_addresses/provider.rs` around
lines 428 - 430, update_sync_state currently assigns
self.last_known_recent_block (and potentially sync_height/sync_timestamp)
directly from result, allowing out-of-order results to move the watermark
backward; change the updates to be monotonic: set self.last_known_recent_block =
max(self.last_known_recent_block, result.last_known_recent_block) and similarly
only advance self.sync_height and self.sync_timestamp if result values are
greater than the current ones (use std::cmp::max or conditional checks). Update
the logic inside update_sync_state so no field is ever decreased by a newer
result and keep existing field names (self.sync_height, self.sync_timestamp,
self.last_known_recent_block) to locate the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@packages/rs-platform-wallet/src/wallet/platform_addresses/provider.rs`:
- Around line 428-430: update_sync_state currently assigns
self.last_known_recent_block (and potentially sync_height/sync_timestamp)
directly from result, allowing out-of-order results to move the watermark
backward; change the updates to be monotonic: set self.last_known_recent_block =
max(self.last_known_recent_block, result.last_known_recent_block) and similarly
only advance self.sync_height and self.sync_timestamp if result values are
greater than the current ones (use std::cmp::max or conditional checks). Update
the logic inside update_sync_state so no field is ever decreased by a newer
result and keep existing field names (self.sync_height, self.sync_timestamp,
self.last_known_recent_block) to locate the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 44e6647e-e6df-4ce4-96f2-a50c7c1242ce

📥 Commits

Reviewing files that changed from the base of the PR and between 2e6fc32 and e75932b.

📒 Files selected for processing (2)
  • packages/rs-platform-wallet/src/wallet/platform_addresses/provider.rs
  • packages/rs-platform-wallet/src/wallet/platform_addresses/wallet.rs

@github-actions
Copy link
Copy Markdown
Contributor

✅ DashSDKFFI.xcframework built for this PR.

SwiftPM (host the zip at a stable URL, then use):

.binaryTarget(
  name: "DashSDKFFI",
  url: "https://your.cdn.example/DashSDKFFI.xcframework.zip",
  checksum: "3f6a1fe1eecc567356b61bdf002b34fffc460850e9266b13235263fc2ab96ef8"
)

Xcode manual integration:

  • Download 'DashSDKFFI.xcframework' artifact from the run link above.
  • Drag it into your app target (Frameworks, Libraries & Embedded Content) and set Embed & Sign.
  • If using the Swift wrapper package, point its binaryTarget to the xcframework location or add the package and place the xcframework at the expected path.

Copy link
Copy Markdown
Collaborator

@thepastaclaw thepastaclaw left a comment

Choose a reason for hiding this comment

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

Code Review

The PR is a small, read-only API addition that exposes existing sync state without changing wallet mutation or persistence behavior. I did not find a correctness, security, or consensus issue in the implementation. The only review-worthy gap is that the new public Option contract is not pinned down by a focused test.

🟡 1 suggestion(s)

Comment on lines +299 to +302
pub async fn sync_watermark(&self) -> Option<u64> {
let guard = self.provider.read().await;
let raw = guard.as_ref().map(|p| p.last_known_recent_block())?;
(raw > 0).then_some(raw)
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

🟡 Suggestion: sync_watermark()'s public None contract is not covered by a focused test

sync_watermark() intentionally collapses two distinct internal states into the same public result: it returns None both when the provider is uninitialized and when the stored watermark is 0. That behavior is documented here and matches the existing apply_sync_state convention, but this PR adds no test that locks those semantics in. A later refactor of provider initialization or persisted-state replay could change one branch without any test failing, because nothing currently asserts the three externally observable cases: uninitialized provider -> None, initialized provider with watermark 0 -> None, and non-zero watermark -> Some(value).

source: ['codex']

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