Skip to content

fix: defer automatic Paykit work during payments - #1626

Open
ben-kaufman wants to merge 4 commits into
fix/paykit-proof-latencyfrom
codex/paykit-background-admission
Open

ben-kaufman wants to merge 4 commits into
fix/paykit-proof-latencyfrom
codex/paykit-background-admission

Conversation

@ben-kaufman

@ben-kaufman ben-kaufman commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Refs #1407, #1419
Stacked on #1591 (fix/paykit-proof-latency).

This PR defers automatic Paykit contact publication, discovery and request refresh when payment review or submission becomes active before SDK admission.

Description

  • Checks payment activity when background identity, peer and scheduling reads acquire the SDK lock, including reads queued before review began.
  • Checks automatic private publication again before mutation, retaining pending contacts and releasing coordination locks so explicit publication can proceed and automatic work can retry afterward.
  • Keeps recipient discovery targets and transport retry intent when admission is deferred; cancellation, profile replacement and cleanup retain their existing behavior.
  • Keeps routine request reloads at background priority when a local action or proof invalidates their first snapshot, so they defer during payment and retry with current proof filters afterward; explicit refresh and recovery retain their priority.

Out of Scope

Design

N/A — no UI changes.

Preview

N/A — no layout changes.

QA Notes

Journeys

Existing regression journeys are unchanged; the final-head native run is pending.

  • existing review-refresh.xml — request review, PIN cancellation and subsequent request discovery remain usable.
  • existing onchain-original-payment-retry.xml — explicit fee approval and recovery authorization retain the original payment; requires its controlled unresolved-payment fixture.
  • existing link-contact-after-resume.xml — saved contacts finish linking after foreground resume without saving again.
  • existing contact-payment-sharing.xml — disabling sharing remains effective across navigation.

Manual Tests

  • regression: pause automatic publication before SDK admission → enter Send Confirmation → release admission → no publication mutation occurs during review; closing review lets the retained update retry — controlled SDK admission and mutation inspection not in Capabilities.
  • regression: defer an automatic contact update → request an explicit contact refresh and immediate publication → explicit work completes; resetting the profile prevents deferred work from resuming for the old profile — controlled SDK deferral and profile-generation inspection not in Capabilities.

Automated Checks

  • added PaykitSdkServiceTest.kt — automatic publication defers at queued admission and backup preflight without changing backup state; explicit publication, cleanup and cancellation remain supported.
  • added PrivatePaykitRepoTest.kt — deferred publication retains contacts, releases explicit publication and stops after reset or profile deletion.
  • added PaykitPaymentRequestRepoTest.kt — deferred recipient discovery retains existing targets; a concurrent proof change defers routine reloads, preserves the warm projection and filters the matching proof on retry while forced refresh stays available.
  • updated PaykitSdkServiceTest.kt — background capability, identity, peer, scheduling and request reads honor payment and review holds while ordered and interactive reads remain available; a payment starting during identity validation defers the subsequent request list without dirtying backup state.
  • updated PrivatePaykitRepoTest.kt — typed scheduling deferral retains retry intent without draining messages; a later fresh empty snapshot retires the retry. Queued capability and publication identity reads retain automatic updates when payment begins, while explicit publication remains available.

Local validation passed: compilation, 201 affected tests, all 4,423 unit tests, Detekt (zero SARIF findings) and Android Lint (zero XML/SARIF findings). Existing cursor-cleanup and tooling warnings were checked against the previous head; no introduced diagnostics were found.

The two new admission regressions were also run against the unchanged previous head and failed for the intended missing-deferral behavior. Final-head device QA remains pending; this PR makes no measured latency-gain claim.

@ben-kaufman
ben-kaufman marked this pull request as ready for review October 20, 2026 19:43
@ovitrif ovitrif added this to the 3.1.0 milestone Oct 20, 2026
@ovitrif

ovitrif commented Oct 20, 2026

Copy link
Copy Markdown
Collaborator

Triage: milestone 3.1.0, with #1591 it is stacked on. It refers to issues rather than closing one, so this PR carries the milestone itself. Not a release blocker.

@greptile-apps

greptile-apps Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerView in GreptileConfidence Score: 4/5

[Medium impact] The changes affect Paykit contact updates and recipient discovery around payments.

Carry the background priority through automatic identity reads before merging.

Findings

  1. P1 Automatic reads bypass payment holds ▶

Summary

This PR defers more automatic Paykit work during payment review and sending.

  • Automatic Paykit contact updates wait while payments are active.
  • Bulk recipient discovery keeps its results when payment work pauses it.

Review was based on code and test inspection; no tests were run.

Diagram

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Automatic contact work] --> B[Check payment hold]
    B -->|Held| C[Keep work and retry later]
    B -->|Clear| D[Read identity]
    D --> E{Read priority}
    E -->|Background| F[Check hold after SDK lock]
    E -->|Ordered helper| G[Read can bypass a new hold]
    F --> H[Prepare publication]
    H --> I[Check hold before mutation]
    I -->|Held| C
    I -->|Clear| J[Publish private endpoints]
Loading

Reviews (1) · Last reviewed commit: "chore: rename changelog fragment" · Reviewed by Greptile

Comment thread app/src/main/java/to/bitkit/repositories/PrivatePaykitRepo.kt
@github-actions

github-actions Bot commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

Regtest APK

Built from 5bd39a8 (run).

Download bitkit-dev-debug universal APK (expires in 30 days).

@talosmachina talosmachina left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

No findings. Defers automatic (Background-priority) Paykit contact publication, link preparation and recipient discovery when a payment review or submission becomes active after the work queued but before SDK admission, and keeps the pending keys and retry intent so the work resumes afterward. Reviewed 92148c4 against fix/paykit-proof-latency, full tier, reasoned from the code and CI (Bitkit Android branches are not built on this reviewer's side).

What I checked, and 4 candidates I ruled out

Read in full: the changed regions of PaykitSdkService.kt (checkRefreshAdmission, identityStatus, linkedPeers, privateMessageSchedulingSnapshot, syncPrivatePaymentListsWithReservations, withStateRevisionTracking), PrivatePaykitRepo.kt (scheduleContactPreparation, contactPreparationPriority, publishLocalEndpoints, preparePrivateLinks, drainPendingPrivateMessages, advancePendingPrivateLinks, runPrivateMessageDrainRetries, readPrivateMessageDrainState), PaykitPaymentRequestRepo.refreshEligibleTargets, PaykitSdkOperationLock.
Call sites traced: every caller of the three reads that now check admission; every OperationInProgress rethrow added in PrivatePaykitRepo up to the handler that catches it.
CI: build (unit tests) green, lint and detekt green, Greptile green. e2e shards still running at review time; e2e-tests-local - lnurl_transfer failed in "Create AVD and generate snapshot for caching", an emulator setup step, not the change.

Ruled out

  • Explicit and payment-time paths now deferred: checkRefreshAdmission throws only for Priority.Background; prepareSavedContacts, handleOnchainActivity, refreshPrivateEndpointsBeforePayment and the public identityStatus() / linkedPeers() default to Ordered, and refreshEligibleTarget uses Interactive, so none of them can hit the new throw.
  • A rethrown OperationInProgress escaping uncaught: every new throw it sits under a Background caller whose top-level handler catches it, scheduleContactPreparation's onFailure (requeues the keys, then waits 1 s) or runPrivateMessageDrainRetries (resets the backoff and loops). retryScope is a SupervisorJob with a logging handler regardless.
  • Deferred preparation resuming for a reset or deleted profile: the requeue is gated on generation == preparationGeneration && !isDeletingProfile, and invalidateContactPreparation clears pendingPreparationKeys; covered by deferred preparation cannot resume after reset or profile deletion.
  • Recipient list cleared on deferral: refreshEligibleTargets returns early on OperationInProgress before the pruning branch, so existing targets stay; covered by the new PaykitPaymentRequestRepoTest.kt case.

Merge confidence: 4/5, no findings, but the e2e shards had not finished and the native journeys listed in QA Notes are still unchecked.

@jvsena42 jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Code scan at 92148c4: no issues found. Reviewed 766f4a8..92148c4, this PR's own two commits on top of #1591. Greptile's open P1 at PrivatePaykitRepo.kt:1032 is the one remaining gap: three Ordered reads in automatic publication aren't checked for review, and it costs latency only.

Checked and clean:

  • Every deferral resumes:
    • Back, cancel and backgrounding release the hold through the repeatOnLifecycle cleanup.
    • An app kill drops the in-memory holds, and startup sync re-queues the contacts.
    • The preparation loop re-queues keys ∩ knownSavedContactKeys only for the same generation and outside profile deletion.
  • Pending publication is kept: retry.prepareEndpoints stays true, and the Lightning refresh isn't acknowledged.
  • Explicit publication isn't blocked: Ordered and Interactive pass admission. The deferral error is thrown inside publicationMutex / operationLock, so both are released, and waiting activeLinkPreparations complete with the error instead of hanging.
  • Locks: the order is publicationMutex → operationLock, and admission only takes synchronized(paymentReviews).
  • No payment waits on deferred work: payment-path reads are Ordered or Interactive, and contact resolution happens before the review screens.
  • Discovery: a deferred refresh keeps the existing targets and skips pruning, and pickers join with contacts.
  • Supervision and cancellation: the batched-drain deferral escapes into a SupervisorJob scope, and runSuspendCatching and the cancellable delay are used throughout.

Perf-relevant: while Confirm, PIN or HardwareSign is open, each deferred job wakes about once a second for a cheap check with no SDK call. It resumes within about 1 s of review ending.

Device gate (partial): 92148c4 — not run yet. Pending:

  • link-contact-after-resume.xml and contact-payment-sharing.xml;
  • open Confirm on one device while the other adds or links it, keep it open for 30 s or more, and check nothing publishes;
  • then end the review by Back, by paying and by backgrounding, and check the other device gets the updated list within a few seconds;
  • control: an explicit link while review is open still publishes at once.

Device results will follow in a separate review.

@jvsena42

jvsena42 commented Oct 20, 2026 •

Copy link
Copy Markdown
Member

Device gate (partial): 6cf67cd on Pixel_9 (emulator), contact-payment-sharing.xml: 9/9 passed. The payments-with-contacts toggle turns off and stays off after Home and reopening Settings, then turns back on.

Toggle timing: the slow disable here (about 3.5 min) came from a congested SDK queue. On a quiet machine the PR matches master; see partial 3.

Still running:

@ben-kaufman

Copy link
Copy Markdown
Contributor Author

Updated in 5bd39a8: routine request reloads now retain Background priority when a concurrent action or proof invalidates the first snapshot. The actual repository and SDK regressions fail on the previous head and pass with this change; all 4,423 unit tests and complete Detekt/Lint checks pass. Forced refresh and recovery retain their priority. Final-head device QA remains pending; this does not establish the cause of the observed native delay.

@ben-kaufman
ben-kaufman requested a review from jvsena42 October 20, 2026 22:55

@ovi-reviewer ovi-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict: ⚠️ Not verified — the PR moved before the new device cases started.

The PR moved to 5bd39a8 after this run; these results are for 6cf67cd.

Findings: No new actionable findings in 766f4a8..6cf67cd. I verified the automatic identity-read finding is fixed at 6cf67cd: automatic capability and publication reads retain Background priority through SDK admission and key preparation, and typed deferral reaches the owner that retains pending contacts.

QA for 6cf67cd:

Test 1: request review, PIN cancellation and later request discovery ⏭️ Not driven because the head moved during setup.

The confirmation/PIN waits, later request arrival, background/reopen and one-payment assertions remain unverified in this run.

Test 2: original on-chain retry ✅ Retained prior pass: cancellation preserved the original payment, and fresh approval completed it once.

I relied on Test 3 of the earlier review and recording at 5ced847, carried through the base-head approval at 766f4a8. It covered fee/PIN waits and cancellation, invalid fees, original inputs, the recipient amount and the winning fee. This diff leaves the Ordered recovery implementation unchanged; I did not repeat that device case.

Test 3: link contact after resume ⏭️ Not driven because the head moved during setup.

Save, immediate Home/resume, Request Or Pay readiness and duplicate-contact checks remain unverified in this run.

Test 4: contact payment sharing stays disabled ✅ Teammate verified the toggle remains off after navigation at this head.

I relied on the current-head device report. It verifies disabling sharing, returning Home, reopening Settings and retaining the disabled preference, then re-enabling it. The same report records slow toggle completion without a matched base comparison; I make no latency-improvement claim.

Test 5: automatic publication defers and resumes ⏭️ Not driven because the head moved during setup.

The controlled before-admission hold, absence of publication during Send Confirmation and retained update after closing review remain unverified on a device. The corresponding automated admission and retention checks passed in Test 7.

Test 6: explicit publication and profile invalidation ⏭️ Not driven because the head moved during setup.

Explicit refresh/publication while automatic work is deferred, and prevention of old-profile work after reset, remain unverified on a device. Their repository regressions passed in Test 7.

Test 7: automated admission and retry regressions ✅ The pristine head built and the focused SDK, private-contact and recipient-discovery suites passed.

I ran assembleDevDebug and testDevDebugUnitTest for PaykitSdkServiceTest, PrivatePaykitRepoTest and PaykitPaymentRequestRepoTest. Gradle completion and JUnit XML confirmed execution with no failures, errors or skips. These cover queued capability/identity reads, pre-mutation deferral without dirtying backup state, explicit publication and cleanup, cancellation, profile invalidation, retained scheduling intent and recipient targets. No device media applies.

Coverage: full 766f4a8..6cf67cd review of all seven changed files and reached admission, publication, retry, lifecycle, cancellation, identity/reset and discovery paths. The four new device cases were not started; their changed behavior has source and automated coverage only. No device result from setup is counted as a pass.

Twin: synonymdev/bitkit-ios#1054 fix: defer automatic paykit work during payments at 0077196 matches the admission, retained-work and explicit-cleanup behavior in the source paths compared; no iOS device validation was performed here.


Reviewed by gpt-6.1-sol-high via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest

@jvsena42

Copy link
Copy Markdown
Member

Device gate (partial 2): deferral check at 6cf67cd, A = Android, B = iOS synonymdev/bitkit-ios#1054 at 90e954c. Android logs nothing when it publishes a private list, so B's Opened private Paykit payment … using payment list version N lines are the evidence.

  • On-chain receive on A while Confirm is open publishes at once, as designed. The rotation runs at Priority.Ordered (handleOnchainActivity → publishLocalEndpoints(reason = "on-chain rotation")). B saw version 223 → 226 with A's Confirm still open: payment at 22:16:09, OnchainTransactionReceived at 22:16:17, B at 22:17:41.
  • ⚠️ Inconclusive: B deletes and re-adds A while Confirm is open.
    • B's polls failed with recovery_required during the review.
    • B saw version 226 again 2 min 38 s after Back on A. The version is unchanged, so that's the link recovering, not a new publication.
    • The control run is invalid: three pending requests from B kept auto-presenting on A, which put it back into review.
    • Android logged Deferred private endpoint publication during 'contact preparation' [PrivateUnavailable] and Waiting for private Paykit link recovery.

Still running:

  • clear the pending requests so A can idle for a valid control, then use a background-only trigger;
  • the toggle re-timing against master;
  • review-refresh.xml and link-contact-after-resume.xml;
  • the A = iOS direction.

@jvsena42

Copy link
Copy Markdown
Member

Device gate (partial 3): the payments-with-contacts toggle timed on a quiet machine, from tap until the toggle is enabled again, same emulator and wallet.

build off: flip / enabled on: flip / enabled
6cf67cd, run 1 2.5 s / 91.2 s 6.1 s / 53.6 s
6cf67cd, run 2 2.5 s / 67.0 s 6.0 s / 44.3 s
master 36bfb4a, run 1 2.5 s / 91.7 s 2.7 s / 52.1 s
master 36bfb4a, run 2 2.7 s / 65.2 s 2.9 s / 48.4 s

The PR matches master. The 3.5 min in partial 1 came from the congested SDK queue, not from this PR. The PR's "on" flips about 3 s later than master in both runs; that's small, and two samples can't separate it from noise.

Still running: the idle-control deferral check, review-refresh.xml, link-contact-after-resume.xml, and the A = iOS direction.

@jvsena42

Copy link
Copy Markdown
Member

Device gate (partial 4): see synonymdev/bitkit-ios#1054 for the iOS-as-A deferral run with this build as B.

@jvsena42

jvsena42 commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Device gate (partial 5): review-refresh.xml at 6cf67cd, with Android as the payer and iOS synonymdev/bitkit-ios#1054 as the requester. 17/17 passed.

  • The requested amount stays 1,000 with a ₿141 fee across 30 s idle, PIN, Back and close.
  • A second request arrives without a restart.
  • After Home and unlock the request is ready again at 1,000.
  • After paying there is exactly one outgoing activity (₿1,141), the requester row shows +₿1 000, and the 2,000 request stays pending.

PIN → broadcast: this run took 91 s, with the payment reads queued 16-19 s right after several minutes of contact relinking. On a quiet machine the PR takes 23-31 s with nothing queued ahead, against 40-96 s on #1591; see partial 6.

Still running: link-contact-after-resume.xml, the idle-control deferral run with Android as A, and the PIN → broadcast comparison against #1591.

@ben-kaufman

Copy link
Copy Markdown
Contributor Author

Thanks for capturing the queue times. Those waits are significant; the back-to-back comparison will help distinguish the branch change from differences between runs.

We also measured long waits behind automatic Paykit work. #1639 keeps passive proof-display refreshes at Background priority. I’m validating two further changes on both platforms: keeping automatic contact-triggered refreshes at Background priority, and receiving then reading the resulting state under one SDK admission so unrelated maintenance cannot intervene. Explicit payment checks, forced freshness and recovery remain intact.

These are not yet a demonstrated fix for your 91-second sample. Our repeated runs still vary, and we’re adding private timing probes to separate SDK queueing, remote storage/delivery and native broadcast time. Please keep the exact build heads and operation queue/work timings with the comparison; I’ll reconcile them with our traces before claiming an improvement.

@jvsena42

Copy link
Copy Markdown
Member

Device gate (partial 6): link-contact-after-resume.xml and PIN → broadcast timing at 6cf67cd, against the iOS synonymdev/bitkit-ios#1054 requester.

link-contact-after-resume.xml: 8/8 passed, with one deviation. Step 3 pressed Home 3 min 48 s after Save instead of right away, because the script waited for a title the dump doesn't expose, so the "Home right after Save" race wasn't exercised on Android. Request Or Pay showed with Request enabled 6 min 18 s after Save (2 min 15 s after resume). Request opens the amount screen, and the contact is listed once.

PIN → Accepted on-chain send, quiet machine, same route as review-refresh.xml steps 13-14:

build PIN → broadcast queue before readPaymentRequests / claim / accept what ran ahead
this PR, 3 runs 30.5, 28.0, 23.1 s under 1 ms each nothing
#1591 5ced847, 2 runs 96.3, 39.5 s 1.7-7.6 s background identityStatus / allPaymentRequests reads, including one identityStatus queued 40.6 s before sendOnChain

On this PR nothing else runs between PIN and broadcast, which is what it sets out to do. The 91 s in partial 5 came from queues on this build right after several minutes of contact relinking, and the quiet runs don't reproduce it.

One run first paid the wrong pending request through a script fallback: 3,055 regtest sats to a fixture identity. It's excluded from the table.

The device gate is paused here, at the user's request. Still pending:

  • #1591 run 3;
  • the idle-control deferral run with Android holding the review;
  • link-contact-after-resume.xml with iOS as the first device.

@ben-kaufman

Copy link
Copy Markdown
Contributor Author

Thanks—these quiet runs support the admission change removing competing work from the payment path. They also show that the remaining 23–31 seconds needs separate investigation; removing queue waits alone does not make the flow fast. Our latest Android runs likewise include 23.9 and 25.8 seconds with little queueing.

I’m keeping the missed “Home immediately after Save” race and the unfinished comparison cases marked unverified. The next private build adds storage, delivery and native-broadcast phase timings to identify the remaining work, without changing payment checks or retries.

@ovi-reviewer ovi-reviewer Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict: ✅ Approve

Findings: No actionable findings in the delta from 6cf67cd to 5bd39a8.

QA for 5bd39a8:

Two Pixel 7 Android 15 emulators, Bitcoin regtest and staging Pubky. Recordings show the payer on the left and requester on the right, at 2× speed.

Test 1: request review, PIN cancellation and later request discovery ✅ The original request survived cancellation and resume, then paid once.

On the pristine build, the 1,000-sat confirmation and PIN each stayed open for over 30 seconds. Cancelling left Sent activity empty. A later 2,000-sat request arrived without restart. After reopening the original and backgrounding/unlocking, fresh authorization produced one 1,141-sat outgoing including the 141-sat fee. The requester showed “Proof submitted” for 1,000 sats; the later request remained pending.

j1.2x.mp4

Confirmation/PIN waits, cancellation, subsequent discovery, resume and both payment records.

Test 2: original on-chain retry ✅ Retained prior device evidence proves original inputs and fresh approval complete one payment.

I retained Test 3 and its recording from the earlier review, carried through the base-head approval. That case exercised fee/PIN waits and cancellation, invalid fees, original inputs and the approved fee. This delta leaves the Ordered recovery paths unchanged, so I did not repeat it.

Test 3: link contact after resume ✅ Immediate Home after Save retained the contact, and Request became available without saving again.

The fresh contact survived immediate backgrounding and reopening. Request Or Pay became available, Request opened the amount screen, and Contacts contained one entry. It was first observed about 115 seconds after the saved-contact log, with sampled UI checks; this is not an exact linking duration or a latency-improvement claim. Android returns directly to Contact after Save.

j3.2x.mp4

Save, immediate Home, resume, Request availability and the single saved contact.

Test 4: contact payment sharing stays disabled ✅ Retained teammate evidence verifies the disabled preference across navigation.

I relied on the device report at 6cf67cd, which disabled sharing, returned Home, reopened Settings and verified it stayed off before re-enabling it. This delta leaves the preference and withdrawal paths unchanged. The separate matched timing report does not establish a speedup.

Test 5: automatic publication defers and resumes ✅ SDK traces confirmed no automatic mutation during review, then successful publication after Back.

On a debug control build, sharing withdrawal/re-enable created a pending private-list update. A gate held its Background capability read before SDK admission. I opened the 2,000-sat confirmation and released the gate. The trace showed repeated admission deferral and retained contacts for over 30 seconds, with no automatic publication mutation. Closing confirmation let the retained update queue successfully. The hook only supplied the gate and logs; it did not replace SDK results or admission decisions.

j5.2x.mp4

The pending-update setup, held confirmation and return Home; mutation and queue results were checked in the SDK hook trace.

Test 6: explicit publication and profile invalidation ✅ Explicit publication completed during review, and invalidation discarded the deferred generation.

With another automatic update repeatedly deferred, explicit preparation with immediate publication completed while confirmation stayed open. The hook trace confirmed one queued update. Through the debug control, I invoked the actual profile-deletion invalidation and repository-clearing methods: the pending generation was cleared, and no old-generation preparation or publication resumed after closing review and observing for over 30 seconds. This exercised the repository lifecycle boundary; the full profile-deletion UI was not driven.

j6.2x.mp4

Confirmation remained open during the explicit operation and invalidation; completion, queued publication and generation clearing were checked in the hook trace.

Test 7: automated admission and retry regressions ✅ The pristine head built and the focused SDK, private-contact and request suites passed.

I ran assembleDevDebug and the PaykitSdkServiceTest, PrivatePaykitRepoTest and PaykitPaymentRequestRepoTest suites. Gradle completion and JUnit results confirmed execution without failures or skips. These include the new Background checkpoint reload, warm-projection retention and proof filtering on retry, plus admission after identity validation and continued Ordered/Interactive availability. No device media applies.

Review coverage: 6cf67cd…5bd39a8, all four changed files and reached callers. The precise concurrent-proof checkpoint race and request-list identity-validation race were exercised by automated regressions; the native request journey covered their visible flow. The earlier identity-read finding remains fixed and its thread is already resolved.

Twin: synonymdev/bitkit-ios#1054 fix: defer automatic paykit work during payments at 7ed5b69 matches the automatic-publication deferral and explicit-cleanup behavior in the source paths compared. Its request refresh uses a different combined-observation implementation. No iOS device validation was performed here.


Reviewed by gpt-6.1-sol-high via gh-pr-review-loop skill
Commands: @ovi-reviewer review · test · retest

@ovitrif ovitrif left a comment

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.

utAck

@piotr-iohk piotr-iohk left a comment

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.

QA review

Scope: Reviewed the full PR diff against its merge base, at 5bd39a8.

No new actionable code findings.

Background contact publication, recipient discovery, and routine payment-request reloads defer when payment review or submission is already active before SDK admission. Pending contacts and the current discovery targets remain queued and retry afterward. Explicit publication, cleanup, withdrawal, and forced refresh or recovery keep their existing priority. A routine reload whose first snapshot is invalidated by a local action or proof stays at background priority, so the warm request projection is left unchanged until a later successful refresh applies the current proof filter. The earlier Ordered identity-read gap in this thread is fixed on this head: automatic capability and publication identity reads keep Background priority through the SDK lock.

Recipient-discovery deferral matches bitkit-ios#1054 at 7ed5b69: both keep existing targets when admission fails. iOS applies proof filters after one snapshot rather than Android's checkpoint re-read. That was a scoped comparison, not a full iOS review.

Validation: the CI build ran unit tests on this revision and passed, and lint and detekt passed. The new unit tests were inspected and not re-run locally. Device testing: not performed in this review. Earlier device notes apply to 6cf67cd and do not cover this head's request-reload change.

Ready for device testing. Re-run review-refresh.xml on this head.

@jvsena42 jvsena42 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Delta at 5bd39a8: no issues found. Reviewed 6cf67cd..5bd39a8, one commit with no merges; base #1591 is unchanged at 766f4a8.

  • What changed: when a local action or proof lands during a routine refresh, the request re-read now runs at the refresh's own priority instead of Ordered (PaykitPaymentRequestRepo.kt:592, :608-613). During a review the re-read defers and the current list stays. Forced refreshes and every other synchronizeLocked caller keep Ordered.
  • No stale entry: a paid request can't stay pending while the re-read waits, because accepting it removes it before the payment runs (:1593).
  • Lock and backup state: deferral releases the SDK lock and the key, and leaves backup state alone.

Device gate (partial): 5bd39a8 — the earlier results from 6cf67cd hold for contact-payment-sharing.xml (9/9) and link-contact-after-resume.xml (8/8): this delta doesn't touch publication or linking. They no longer hold for review-refresh.xml (17/17), because the delta changes the re-read on that route.

Pending:

  • re-run review-refresh.xml;
  • re-capture PIN→broadcast in the same run;
  • link-contact-after-resume.xml with iOS first.

This branch has not been deployed

No deployments
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.

5 participants