Skip to content

feat(sdk-ffi): expose the current epoch; fix getCurrentEpoch and the proposed-blocks range proof - #4453

Merged
QuantumExplorer merged 1 commit into
v4.2-devfrom
feat/current-epoch-ffi
Aug 22, 2026
Merged

feat(sdk-ffi): expose the current epoch; fix getCurrentEpoch and the proposed-blocks range proof#4453
QuantumExplorer merged 1 commit into
v4.2-devfrom
feat/current-epoch-ffi

Conversation

@QuantumExplorer

@QuantumExplorerQuantumExplorer commented Aug 22, 2026

Copy link
Copy Markdown
Member

Summary

  • New dash_sdk_system_get_current_epoch(sdk) in rs-sdk-ffi: the newest started epoch via ExtendedEpochInfo::fetch_current (the proved two-query probe), returned as one JSON object with the same keys dash_sdk_system_get_epochs_info emits per epoch (index, first_block_time, first_block_height, first_core_block_height, fee_multiplier_permille, protocol_version). NoData when Platform has no epoch yet.

  • Swift SDK.getCurrentEpoch() now calls it. The previous implementation used getEpochsInfo(start: nil, count: 1, ascending: true), which per EpochQuery semantics is epoch 0, not the current epoch — and an unbounded descending proved query is rejected by the proof verifier, so no existing bridge could answer "which epoch is it now".

  • dash_sdk_evonode_get_proposed_epoch_blocks_by_range now carries its limit in the request. It used to send limit: None, so Drive built the proof for its default page while the verifier re-derived a no-limit query from the request — every proved call failed with Proof is missing data for query range … KVHash (seen on mainnet from the iOS wallet). 0 ⇒ Drive's default page.

Consumer: dashwallet-ios home-screen "blocks proposed this epoch" card (dashpay/dashwallet-ios#1036).

Test plan

  • cargo test -p rs-sdk-ffi --lib -- current_epoch proposed_epoch_blocks, cargo clippy -p rs-sdk-ffi --all-targets -- -D warnings, cargo fmt
  • ./build_ios.sh --target sim (xcframework + SwiftExampleApp, warnings-as-errors)
  • Mainnet/testnet: the iOS card shows the real current epoch index and the range pages verify

🤖 Generated with Claude Code

`dash_sdk_system_get_current_epoch` returns the newest started epoch via
`ExtendedEpochInfo::fetch_current` (the proved two-query probe), as one JSON
object with the same keys `dash_sdk_system_get_epochs_info` emits per epoch.
The Swift `SDK.getCurrentEpoch()` used `getEpochsInfo(start: nil, count: 1,
ascending: true)`, which is epoch 0 — not the current epoch — and an
unbounded descending proved query is rejected by the proof verifier, so no
existing bridge could answer the question. It now calls the new FFI.
Consumer: dashwallet-ios home-screen "blocks proposed this epoch" card.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@coderabbitai

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:37 minutes

Limit details: You’ve used the included review currently available.

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

Wait for the limit to reset, then comment @coderabbitai review or push new commits to the PR.

An organization admin can change what happens after included review limits in Billing.

How do review limits work?

CodeRabbit enforces per-developer PR review limits within each organization.

For paid Pro and Pro+ reviews, CodeRabbit uses a developer's included PR review attempts over the past 7 days to set the current hourly allowance. At typical activity levels, the full plan allowance applies. Higher sustained activity can lower the allowance until earlier attempts leave the 7-day window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 79c359ee-44bc-4550-93d7-598f76727ac7

📥 Commits

Reviewing files that changed from the base of the PR and between 6fd939c and 0eaceda.

📒 Files selected for processing (3)
  • packages/rs-sdk-ffi/src/system/queries/current_epoch.rs
  • packages/rs-sdk-ffi/src/system/queries/mod.rs
  • packages/swift-sdk/Sources/SwiftDashSDK/FFI/PlatformQueryExtensions.swift

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.

@thepastaclaw

thepastaclaw commented Aug 22, 2026

Copy link
Copy Markdown
Collaborator

ℹ️ Review skipped (commit 0eaceda)
Last checked: 2026-08-22 14:00 UTC

@QuantumExplorer
QuantumExplorer merged commit b97a072 into v4.2-devAug 22, 2026
18 of 21 checks passed
@QuantumExplorer
QuantumExplorer deleted the feat/current-epoch-ffi branch August 22, 2026 13:57
QuantumExplorer added a commit to dashpay/dashwallet-ios that referenced this pull request Aug 22, 2026
…ange with it
Proved proposer queries must name an explicit epoch — the proof verifier
rejects "current" (`proved proposer queries require an explicit epoch`), so
every range scan failed silently and the card/rows never populated. The
service now resolves the current epoch via `getCurrentEpoch()` first (a hard
dependency on dashpay/platform#4453) and passes its index to every page.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@QuantumExplorerQuantumExplorer changed the title feat(sdk-ffi): expose the current epoch; fix Swift getCurrentEpochfeat(sdk-ffi): expose the current epoch; fix getCurrentEpoch and the proposed-blocks range proofAug 22, 2026
QuantumExplorer added a commit to dashpay/dashwallet-ios that referenced this pull request Aug 22, 2026
…his epoch (#1036)
* feat(wallet): home card with the blocks your evonodes proposed this epoch
Adds a home-feed card (shown only when the wallet has active evonodes) with
the number of Platform blocks they have proposed in the current epoch,
"Epoch N · started <relative>", tapping into the masternode list, which
now shows the per-evonode count on each row.
Privacy: the wallet never names its own evonodes to DAPI. Instead of the
by-ids query (whose request would list exactly our nodes),
`EvonodeEpochBlocksService` pages the whole epoch's proposer tallies with
`getEvonodesProposedEpochBlocksByRange` — a request with no node ids,
identical for every wallet — and joins against the owned set on-device.
A wallet without evonodes issues no query at all.
Refresh: sync done, app foreground, wallet/network switch, and screen
appear (throttled to 5 min). The epoch label uses the SDK's new
`getCurrentEpoch()` (dashpay/platform#4453 — the old one returned epoch 0).
Also factors the Masternodes hosting wrapper into
`MasternodesScreen.hostingController(popFrom:)`, shared by the Governance
menu and the home card.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(wallet): evonode epoch-blocks review follow-ups
- Empty owned set returns without touching the SDK (no query at all).
- A scan still paging at the page guard throws `pageLimitReached` instead of
reporting a truncated tally; callers keep their last value.
- Generation token owns the in-flight fetch (home + masternode list): a
superseded fetch unwinding late can no longer clear or publish over its
replacement.
- Masternode list refreshes its tallies on the same events as the home card
(sync done, foreground, wallet/network switch).
- Locale-formatted per-row counts; log line wrapped under 180 chars.
- Failed fetches retry after 30 s on routine triggers (not the 5-min
success throttle) and log why the card is hidden.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(wallet): resolve the current epoch first and query the proposer range with it
Proved proposer queries must name an explicit epoch — the proof verifier
rejects "current" (`proved proposer queries require an explicit epoch`), so
every range scan failed silently and the card/rows never populated. The
service now resolves the current epoch via `getCurrentEpoch()` first (a hard
dependency on dashpay/platform#4453) and passes its index to every page.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* refactor(wallet): shared EvonodeEpochBlocksMonitor owns the epoch-blocks refresh policy
CodeRabbit follow-ups, resolved by centralising the policy instead of
duplicating it in two view models:
- `EvonodeEpochBlocksMonitor` (shared; one scan serves every screen, seam
via `EvonodeEpochBlocksProviding` + injectable owned-evonode source)
serialises scans: at most one in flight, a forced refresh requested while
one runs is queued behind it (never dropped), routine triggers are
throttled (5 min after success, 30 s after failure), and a wallet/network
reset cancels the running scan, drops the stale value and queues a forced
one. Failure state is only recorded by the live generation.
- The service forwards the caller's cancellation into its detached scan
(`withTaskCancellationHandler` + stop flag checked per page) and parses
counts through their decimal text so negatives are rejected.
- Home and Masternodes view models mirror the monitor and only call
`refresh()` on appear; the list therefore gets the same throttle and
lifecycle triggers as the card.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(wallet): Nodes shortcut with epoch day and blocks proposed, instead of the home card
Replaces the home-feed card with a "Nodes" shortcut in the customizable
shortcut bar (long-press to switch), per the owner's direction:
- `ShortcutActionType.nodes`, offered in the customization picker — and
swapped into the default bar's last slot — only while the wallet has
active evonodes (same runtime gating as CrowdNode / Switch Wallet).
- `NodesShortcutIcon`: a live 46 pt disc — the epoch day (0–9, recomputed
every minute from the epoch start) large on top, a divider, and the
blocks proposed this epoch ("99+" cap) on the bottom strip; "–" until
the first tally; accessibility label carries both numbers. Reads the
shared `EvonodeEpochBlocksMonitor`.
- Tap opens the Masternodes list (per-row counts unchanged).
- Home no longer mirrors the tallies; it only nudges the monitor on appear.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* fix(wallet): Nodes shortcut is opt-in only; gate saved Nodes; reload list on context changes
- Defaults unchanged: Nodes is offered in the long-press picker for evonode
owners and never placed automatically (owner's direction).
- A persisted Nodes shortcut degrades to Spend / the faucet while the active
wallet runs no evonodes (e.g. after a wallet switch); the saved config is
untouched and it returns with an evonode wallet.
- `EvonodeEpochBlocksMonitor.contextVersion` bumps on sync-done and
wallet/network changes; the Masternodes list reloads itself (and its
ownership indexes) on it while visible.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat(wallet): Nodes icon as epoch ring + badge, coloured by evonode health
- Icon redesign (design B): the rim is an epoch-progress ring, the epoch day
sits large in the centre, and a white badge on the bottom edge carries the
blocks proposed this epoch.
- Health colouring: blue when every evonode is proposing; yellow when any
evonode hasn't proposed a block in the last 2 days; red when we're on
epoch day 4+ and an evonode still has no block this epoch.
- Platform only reports per-epoch totals, so recency is tracked locally:
`EvonodeProposalActivity` folds every successful tally (per node: last
observed increase, first observation, epoch-aware) and is persisted per
network; the monitor publishes it and the icon evaluates `EvonodeHealth`
every minute. Accessibility label names the condition.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
bfoss765 added a commit that referenced this pull request Aug 23, 2026
Brings the branch up to date with upstream after #4451 (masternode
credit withdrawals), #4452, #4453, #4456, and #4461 landed on v4.2-dev.
One conflict, in packages/rs-platform-wallet/src/wallet/core/mod.rs:
a module-registration collision where this branch adds
'pub mod spend_observer;' and upstream adds
'pub(crate) use sign_message::is_signable_funding_account;' at the same
spot. Resolved as the union — both lines kept, no semantic overlap.
Auto-merged overlaps verified by hand: both error.rs files and
DashSdkError.kt gained disjoint additions (upstream's
MasternodeWithdrawalUnconfirmed / FFI code 42 alongside this branch's
StaleReservation reusing code 34 — codes distinct, both mapping arms
present). generation.rs (the broadcast-fence redesign) was touched by
this branch only.
Verified: cargo check -p platform-wallet -p platform-wallet-ffi clean;
cargo test -p platform-wallet wallet::core::generation — 15/15 passed,
including the settle-boundary and handoff tests.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
bfoss765 added a commit that referenced this pull request Aug 23, 2026
Brings the shielded-invite branch up to date with upstream v4.2-dev
(#4451 masternode credit withdrawals, #4452, #4453, #4456, #4461).
One conflict, in rs-platform-wallet/src/wallet/shielded/operations.rs:
upstream #4451 moved carries_consensus_rejection() and
broadcast_definitely_failed() out of operations.rs into the new shared
crate::broadcast_outcome module (so masternode withdrawals can reuse
them), while this branch had inserted its one-time-key claim machinery
(NullifierSpentStatus, claim-evidence resolution) directly after those
functions. Resolved by dropping the now-local duplicate of
broadcast_definitely_failed() — its body is byte-identical to the moved
copy, and the file already imports both helpers from
crate::broadcast_outcome via upstream's auto-merged use line — and
keeping this branch's one-time-key claim block in place. No semantic
changes to either side.
Verified: cargo check -p platform-wallet -p platform-wallet-ffi
-p rs-unified-sdk-jni clean; cargo test -p platform-wallet
--features shielded wallet::shielded = 205 passed, 0 failed
(includes the one_time_claim_evidence and note_selection suites).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for freeto 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

@QuantumExplorer@thepastaclaw