Skip to content

feat(cluster-tool): add generic dclaim bootstrap planning - #92

Open
huangminghuang wants to merge 3 commits into
masterfrom
feature/ops-197-bootstrap-plan
Open

feat(cluster-tool): add generic dclaim bootstrap planning#92
huangminghuang wants to merge 3 commits into
masterfrom
feature/ops-197-bootstrap-plan

Conversation

@huangminghuang

@huangminghuang huangminghuang commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

Why this PR exists

OPS-197 asks cluster-tool to accept Ethereum and Solana prelaunch balance JSON and to reuse the same bootstrap path in the emissions soak flow.

That cannot safely be implemented as independent import paths. sysio.dclaim::importdone is global and irreversible, so configured indexer data, per-chain fallback data, and controlled additive credits must first become one validated, deterministic plan. This PR adds that generic planning foundation without changing cluster creation, FlowScenario, or on-chain behavior.

Implemented features and why each is needed

Implemented feature Why OPS-197 needs it
Schema-derived ETH/SOL indexer validation with source, chain, row, and field errors The future CLI flags accept external JSON. Consumed integer fields and native addresses must fail during preflight, before cluster processes or transactions begin. Unknown fields remain compatible with harmless indexer schema additions.
One-pass address and converted-balance validation Every row must be checked against the selected chain and Antelope asset limit. A consolidated traversal avoids redundant decoding while preserving precise file provenance in failures.
Immutable, clone-friendly, chain-bound validated-dump token and conversion fast path The later file reader must validate once with the real file path, then convert without replacing that provenance with an in-memory label. Frozen validated data and context prevent post-validation mutation, while reference proofs preserve safe object-spread clones and reject replaced data or context without WeakMap identity coupling.
Deterministic ETH/SOL balance conversion Ethereum source balances use 18 decimals while Solana uses 9. Both must become 9-decimal WIRE atomic units; Ethereum conversion reports floor dust. Staker entitlement is pretokenYield - yieldClaimed, with non-positive entitlement filtered as required by the ticket.
Separate conversion, merge, and batching boundaries OPS-197 requires controlled emissions-soak credits to be added after raw-dump conversion but before batching. Separating these stages keeps scenario data out of synthetic dumps and sends every source through one final batching path.
Generic configured, fallback, and additive source types A configured file suppresses fallback only for the same native chain, while controlled credits remain additive. This lets cluster-tool own source policy without putting emissions-specific behavior in FlowScenario.
Configured-but-empty input fails planning An explicitly supplied file with no eligible credits must not silently suppress fallback and omit a requested chain. Every empty configured set is rejected independently with a human-readable chain label, keeping per-file failures actionable before execution.
Duplicate-address merging An address can occur in purchaser and staker rows or collide with an additive controlled identity. Summing by (chain, native_address) before batching produces the collision-aware entitlement needed by emissions-soak assertions.
Contribution-accurate provenance and dust summaries Empty additive or fallback sets can contribute conversion dust but no credits. Sources therefore describe only contributing credit sets, while dropped dust still accounts for every selected input.
Stable chain/address sorting and deterministic batches Identical inputs must produce identical importseed payloads. Stable ordering makes later execution, verification, restart reconciliation, reports, and tests reproducible.
Live-seedable, globally consecutive dclaim row IDs unmapped row IDs are global across Ethereum and Solana imports. The planner accepts the live capcounters.next_unmapped_id, defaults to 1 for a new table, and enforces the uint64 range across every planned batch so chain-local numbering cannot collide or overflow.
Transaction and serialization boundaries Final action batches contain 1–10,000 credits, enforce chain/address width and asset limits in the planning schemas, and serialize wire_atomic as a decimal string for clio. The serializer retains an O(1) 1–10,000 boundary assertion without repeating per-credit validation in the push path.
Typed DistributionClaimBootstrapResultKey The later cluster phase needs a typed OutputStore handle for the finalized plan rather than an ad hoc string or scenario-specific field. Declaring it with the output model keeps the library contract ready for PR 2.
Compact per-chain plan summaries Eligible address count, total atomic amount, contributing sources, batch count, and dropped dust are calculated once. Later PRs can log and report these values without serializing bulk credit arrays into step reports.
Empty-input behavior remains dormant With no configured, fallback, or additive credits, the planner returns an empty plan. Ordinary cluster behavior remains unchanged until a follow-on integration PR consumes the output.

Scope boundary

This is PR 1 of the OPS-197 split and is deliberately library-only.

Included:

  • generic input/output types, runtime schemas, and the typed output key;
  • indexer validation and ETH/SOL conversion;
  • configured/fallback/additive selection and configured-empty rejection;
  • merge, sort, batch, summaries, and live-seedable global IDs;
  • unit and regression coverage.

Deferred to follow-on PRs:

  • bootstrap JSON file reading and CLI/config persistence;
  • reading capcounters.next_unmapped_id and storing this plan in OutputStore;
  • cluster build phases and sysio.dclaim writes;
  • restart journals and reconciliation;
  • emissions-soak migration;
  • acceptance flow and canonical runner forwarding.

There are no changes here to FlowScenario, CLI behavior, process launch, cluster phases, or chain writes.

Follow-on implementation must convert plan bigint values to strings at report/JSON boundaries, log the irreversible importdone finalization explicitly, and decide any aggregate supply ceiling from an authoritative contract requirement rather than inventing one in this planner.

Validation

  • pnpm test
    • 227 suites passed across 8 projects
    • 1,990 tests passed
  • pnpm run lint
  • targeted Prettier checks for every follow-up file
  • focused planner/converter suites after the final compliance corrections
    • 2 suites passed
    • 25 tests passed
  • git diff --check
  • three independent correctness, architecture/policy, and evidence reviews repeated after fixes, with no remaining findings

Merge model

This PR is based directly on master. Follow-on OPS-197 PRs will be created sequentially from the preceding merged foundation so each review remains focused and the complete feature reaches master incrementally.

Change-Id: Ia189543da9093bbd03866c6735b8bbf113fbb97b
@huangminghuang
huangminghuang requested a review from heifner August 31, 2026 19:28
Change-Id: Ie172d32c05b114d2e304fbf3e8dcf6b86230e8b3
@huangminghuang

Copy link
Copy Markdown
Contributor Author

Addressed the review feedback in aebee240:

  • added DistributionClaimBootstrapResultKey;
  • made the global row-id seed configurable from the live counter and bounded all planned IDs to uint64;
  • made configured-but-empty chain data fail instead of silently suppressing fallback;
  • limited source provenance to credit-contributing sets while retaining all selected dust;
  • removed the orphan configured-chain helper and centralized chain address widths;
  • consolidated dump validation and added an opaque, chain-bound validated conversion path that preserves caller provenance;
  • made chain labeling reject unsupported values explicitly;
  • made clio serialization enforce the non-empty batch schema.

The PR description now explains why each feature is required by OPS-197 and records the PR 2 boundaries. Current-head CI is green, and independent code/scope re-reviews found no remaining issues.

Change-Id: If05e99bc1344cf6bbddc4fbdf635cdf7171307a9
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.

1 participant