feat(permissionless-groups): held-balance fields + migrateWithRetry#74
feat(permissionless-groups): held-balance fields + migrateWithRetry#74leinss wants to merge 1 commit into
Conversation
Add deterministic held-balance figures alongside the existing virtual
balance, and a resilient migration submit helper. The migration pathfinder
returns a network max-flow that moves block-to-block as the trust graph
changes, so figures derived from it are inherently unstable; this change
gives callers stable, holdings-only numbers and hardens migration execution
against that staleness. Additive / non-breaking.
balance():
- add personalHeldTotal + per-token heldTotal (raw held personal CRC, before
the migration outflow subtraction) — deterministic for a given chain state
- add `{ includeMigratable: false }` option to skip the pathfinder probe and
return held-only figures (faster, fully deterministic)
- surface migratableAtBlock, plus migratableProbe / personalProbe so a
swallowed RPC failure is distinguishable from a genuine zero
- thread a single demurrage timestamp through all conversions in the call
- document each field as deterministic vs live estimate
migration():
- expose MigrationResult.edges (flow-edge count; fragility gauge)
- add migrateWithRetry(): re-queries the pathfinder fresh per attempt and
shrinks the edge cap on a retryable revert (shorter, less-stale route);
rethrows non-retryable submit errors; returns a discriminated result with
reason 'empty' | 'exhausted'; validates options
misc:
- normalize PathfindingResult.graphBlock to bigint at the RPC boundary
- correct maxEdges docs (forwarded to the pathfinder's maxTransfers; not a
hard cap on the number of returned edges)
tests:
- held-vs-live breakdown across ERC1155 / demurrage-ERC20 / inflationary-ERC20
forms, incl. tokenAddress-keyed outflow subtraction
- migrateWithRetry: hop reduction, error classification, build-error retry,
defaults, and option validation
|
Warning Review limit reached
Next review available in: 55 minutes 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: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (6)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
|
Caution Review failedAn error occurred during the review process. Please try again later. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Summary
Adds deterministic held-balance figures to
balance()and a resilient migration submit helper. The migration pathfinder returns a network max-flow that moves block-to-block as the trust graph changes, so any figure derived from it is inherently unstable. This change gives callers stable, holdings-only numbers (independent of the pathfinder) and hardens migration execution against that same staleness. All changes are additive / non-breaking.What changed
balance()personalHeldTotal+ per-tokenheldTotal— raw held personal CRC, before the migration-outflow subtraction; deterministic for a given chain state.{ includeMigratable: false }option — skips the pathfinder probe entirely and returns held-only figures (faster, fully deterministic;scoreGroupTotal === scoreGroupHeldTotal).migratableAtBlock, plusmigratableProbe(ok|skipped|failed) andpersonalProbe(ok|failed) — surface which block the live estimate was computed at, and whether each fallible read succeeded, so a swallowed RPC failure is distinguishable from a genuine zero.Migration
MigrationResult.edges— flow-edge count (path complexity / fragility gauge).migrateWithRetry(params, submit, options)— re-queries the pathfinder fresh on each attempt and shrinks the edge cap on a retryable revert (shorter, less-stale route); rethrows non-retryable submit errors (e.g. user rejection) instead of re-prompting; returns a discriminated result withreason: 'empty' | 'exhausted'; validates options.Misc
PathfindingResult.graphBlocktobigintat the RPC boundary.maxEdgesdocs (forwarded to the pathfinder'smaxTransfers; not a hard cap on the number of returned edges).Test plan
bun run build(typecheck) passesbun testinpackages/permissionless-groupspasses (70 tests)personalHeldTotal/scoreGroupHeldTotalare stable across repeatedbalance()calls whilescoreGroupMigratablemay varybalance(avatar, { includeMigratable: false })returnsscoreGroupTotal === scoreGroupHeldTotaland issues no pathfinder callmigrateWithRetryretries with a shrinking edge cap on a retryable revert, rethrows a user-rejection error, and reportsreason: 'exhausted'when all attempts revert