feat(dashpay): any number of simultaneous contested name requests - #959
Conversation
The one-contested-request-at-a-time refusal existed only because the
reconciliation bookmark was single-slot; the protocol itself runs one
independent vote poll (and vote-resolution fund) per label. The store
is now a per-(network, wallet) dictionary — canonical label →
{submittedAt, votingEnd} — and the guard is gone:
- DWContestedNameStatusService: pendingLabels / per-label votingEndTime,
recordSubmission upserts, recordVotingEndTime and clearPending are
per-label, finalizeWon clears only the won label. pendingLabel /
pendingVotingEndTime remain as OLDEST-entry conveniences for the
setup-flow surfaces (which only ever deal with the first username),
so those consumers are unchanged. The retired single-slot bookmark
migrates into the dictionary on first read; the unscoped legacy
bookmark is still discarded. resetForWipe covers the new key prefix.
- DWCurrentUserIdentityInfo: the username-surface filter and the
recovered-username pick exclude EVERY in-flight label; identity
recovery rebuilds a bookmark per still-voting contested label
instead of only the lexicographic minimum.
- DWIdentityRegistrationCoordinator: checkPendingContestResolution
resolves every in-flight label independently — a per-label failure
skips only that label; won/lost clears only its own bookmark.
- UsernameMarketplaceService: contestInProgress guard and error case
removed; RegisterNameSheet's wait-for-the-other-vote branch removed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reached
Next review available in: 30 seconds Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the 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 configurationConfiguration used: defaults Review profile: CHILL Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Comment |
After the PIN the marketplace sat silent for the seconds a Platform
transition takes — the action sheets dismiss themselves as the action
starts, so nothing said work was happening until the success banner.
perform() now takes a progressText and drives a blocking spinner
overlay on the marketplace screen ("Submitting your username
request…", "Listing for sale…", "Completing your purchase…", …), shown
until the action succeeds or fails. The PIN prompt presents above it.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Added in 2nd commit: a blocking activity overlay during trade transitions — after the PIN, the screen now shows a spinner with what's happening ("Submitting your username request…", "Listing for sale…", etc.) instead of sitting silent until the success banner. |
|
Verified on the testnet QA simulator: four contested requests in flight simultaneously (greg, qu1et, samu, ye1p), each with its own bookmark and deadline under My Names → In network vote; the pre-rework single-slot "greg" bookmark migrated cleanly, and no still-voting label leaks into the username surfaces. |
Issue being fixed or feature implemented
Testnet QA: requesting "bite-me" while "greg" was still in its vote was refused with "wait for that vote to finish". The limit was never a protocol rule — each label runs its own independent vote poll with its own 0.2 DASH vote-resolution fund. It existed only because the app's reconciliation bookmark (
DWContestedNameStatusService) was single-slot, and #946's review fixed the overwrite hazard with a one-at-a-time guard rather than a multi-label store.What was done
The bookmark store is now a per-(network, wallet) dictionary — canonical label → {submittedAt, votingEnd} — and the guard is removed end to end:
DWContestedNameStatusService:pendingLabels(oldest-first) and per-labelpendingVotingEndTime(label:for:);recordSubmissionupserts (recovery re-records can't reorder);recordVotingEndTime/clearPendingare per-label;finalizeWonclears only the won label, so other contests keep reconciling.pendingLabel/pendingVotingEndTimesurvive as OLDEST-entry conveniences — the setup-flow consumers (JoinDashPay banner, CreateUsername voting screen, profile sheet, menus) only ever deal with the first username and needed no changes. The retired single-slot bookmark migrates into the dictionary on first read (same wallet scope, unambiguous attribution); the unscoped legacy bookmark is still discarded, andresetForWipecovers the new key prefix.DWCurrentUserIdentityInfo: the username-surface filter (Edit Profile, profile sheet, invitation links, payment memo) and the recovered-username pick now exclude EVERY in-flight label; identity recovery rebuilds one bookmark per still-voting contested label instead of onlycontested.min().DWIdentityRegistrationCoordinator:checkPendingContestResolutionloops all in-flight labels; each resolves independently (a per-label fetch failure skips only that label for the pass), and won/lost clears only its own bookmark.contestInProgressguard, error case, sheet branch, and its string are gone.How Has This Been Tested?
Clean
dashpayarm64 simulator build. On the testnet QA simulator (which carries a live in-flight "greg" contest whose old-format bookmark exercises the migration): verifying that a second contested request now submits, both labels show under My Names → "In network vote", and neither leaks into the username surfaces. Results to follow on this PR. (Unit-test target pre-existing broken.)Breaking Changes
None.
Checklist:
For repository code-owners and collaborators only
🤖 Generated with Claude Code