Repository navigation
fix(receive): serve the receive address from the SDK engine, not the held dashj chain #1570
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
HashEngineering
merged 40 commits into
feat/kotlin-sdk-phase-1
from
fix/receive-address-from-sdk-engine
Oct 7, 2026
Merged
Changes from 34 commits
Commits
Show all changes
40 commits
Select commit
Hold shift + click to select a range
8c8e107
fix(receive): serve the receive address from the SDK engine, not the …
HashEngineering 2f6c906
fix(receive): correct two stale docs and pin the rollback clear
HashEngineering b62303a
fix(receive): stamp the address cache with a binding generation
HashEngineering 4f593cb
fix(shielded): unshield to the unadvertised chain, not the receive ad…
HashEngineering aa0c36f
fix(shielded): fail closed rather than fall back to the advertised ad…
HashEngineering 5145394
fix(receive): revoke ownership eagerly and order address publications
HashEngineering 4e8b6dc
fix(receive): answer every caller from the cache; own the sweep desti…
HashEngineering 1b0bc96
fix(receive): keep sweep failures retryable; park a real read in the …
HashEngineering 4b409be
fix(receive): fail closed after cutover instead of the frozen dashj a…
HashEngineering 6148a02
fix(receive): repair six consumer paths the fail-closed change broke
HashEngineering 2a7e673
fix(crowdnode): guard signup and linking when no account address exists
HashEngineering 77f8c78
fix(crowdnode): report and retry a missing account address, don't fai…
HashEngineering 5ab1c64
refactor(coinbase): bind the deposit address instead of force-unwrapp…
HashEngineering 38f0d4c
fix(receive): refuse on COMMITTED ownership, not the pipeline flag
HashEngineering 34933b5
fix(receive): revoke the binding before publishing disabled ownership
HashEngineering 92fa089
fix(receive): fence EVERY completed read, not only the successful ones
HashEngineering 766de7f
fix(receive): carry the binding identity with the self-transfer desti…
HashEngineering 75b4dac
fix(coinbase): take the confirm single-flight on the tap, not in the …
HashEngineering 211d329
style: drop a redundant !! and merge two stacked KDoc blocks
HashEngineering 29c1d73
test(receive): drain the pipeline's first read instead of racing it
HashEngineering 78b1104
fix(sdk): let nothing escape the bind-heal job
HashEngineering 7c9dee4
fix(receive): never let a remembered "dashj owns it" authorise the fa…
HashEngineering 2e86d46
fix(receive): order the receive snapshots at the engine read, not bef…
HashEngineering d69c61e
fix(receive): stop an older deactivation revoking a newer activation
HashEngineering a9629fb
fix(receive): read the ownership state so a failed read stays a failure
HashEngineering 22ffb53
test(receive): prove the activation survives, and record what this te…
HashEngineering 21a903d
test(receive): stub the ownership read the service actually calls
HashEngineering 59ea6b9
fix(receive): never let a Receive failure dismiss the payments flow
HashEngineering 8194dc7
fix(receive): retry the address read when Receive is selected
HashEngineering 5e9c61e
fix(receive): revalidate the address instead of latching the first one
HashEngineering e6765fd
fix(receive): a held address is not a successful revalidation
HashEngineering a1f5ae7
fix(coinbase): release the confirm flight only to the attempt that ow…
HashEngineering 373ca4b
fix(receive): decide the ownership no-op under the ownership mutex
HashEngineering 66facee
test(cutover): route the cutover-state fixtures by caller, not by sub…
HashEngineering f4374a4
fix(receive): do not surface an address failure after the screen is gone
HashEngineering 6c850d2
fix(topper): scope the click-owned address read to the originating view
HashEngineering 4e4cedd
docs(sdk): correct the unadvertised-destination KDoc residual
HashEngineering 3862d6c
docs(cutover): state the reservation primitive as verified, not reported
HashEngineering 3f09fd1
docs(receive): stop the receive/unadvertised KDocs naming stale callers
HashEngineering 1abb621
docs(sdk): correct the unshield collision-window figure with the meas…
HashEngineering File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
36 changes: 36 additions & 0 deletions
36
common/src/main/java/org/dash/wallet/common/services/ReceiveAddressUnavailableException.kt
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| /* | ||
| * Copyright 2026 Dash Core Group. | ||
| * | ||
| * This program is free software: you can redistribute it and/or modify | ||
| * it under the terms of the GNU General Public License as published by | ||
| * the Free Software Foundation, either version 3 of the License, or | ||
| * (at your option) any later version. | ||
| * | ||
| * This program is distributed in the hope that it will be useful, | ||
| * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| * GNU General Public License for more details. | ||
| * | ||
| * You should have received a copy of the GNU General Public License | ||
| * along with this program. If not, see <http://www.gnu.org/licenses/>. | ||
| */ | ||
|
|
||
| package org.dash.wallet.common.services | ||
|
|
||
| /** | ||
| * No receive address can be served right now. | ||
| * | ||
| * Raised only POST-CUTOVER, when the SDK engine cannot answer and the wallet | ||
| * therefore has no address it is safe to advertise. It exists because the | ||
| * obvious fallback is actively wrong: the dashj key chain is HELD after the | ||
| * cutover, so its "current" pointer is frozen wherever the restore left it — | ||
| * index 0 on a fresh restore, an address the chain has ALREADY been paid on. | ||
| * Serving that is the SR-03 defect. | ||
| * | ||
| * Callers must surface a retry rather than substitute an address. The condition | ||
| * is transient by nature: it covers the window before the engine binds, a failed | ||
| * engine read, and the instant after a wallet wipe revokes the binding. | ||
| */ | ||
| class ReceiveAddressUnavailableException( | ||
| message: String = "no receive address is available yet" | ||
| ) : IllegalStateException(message) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🔴 Blocking: Check lifecycle cancellation before displaying an address-read failure
Rotate or leave this screen while getTransferDashParams() is waiting for an unbound SDK wallet. The fragment's lifecycleScope is cancelled, but the underlying Thread.sleep/FFI work continues. When that work subsequently fails, ReceiveAddressUnavailableException can still reach this catch: withContext's cancellation check discards successful results, but does not replace an exception produced by its body. The handler then calls requireContext() after the fragment has detached, throwing an uncaught IllegalStateException instead of presenting a retry. ReceiveFragment and the Topper entry-point fragments contain the same newly added failure-handler pattern. Check coroutine cancellation before performing error UI, and use a still-attached, appropriate lifecycle owner/context. Add coverage for cancellation followed by a failed address read; the current confirmation tests model cancellation cleanup without exercising the fragment's requireContext() call.
source:
gpt-6.1-sol(phase2-reviewer: general)There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Resolved (re-reviewed at
f4374a46): Your Coinbase failure handler now calls toastIfStillAttached(), which checks coroutine activity and uses nullable context rather than requireContext(). AttachedUiTest also explicitly stages an exceptional withContext completion after cancellation, so the guard addresses the reported late-failure path.