Skip to content

Latest commit

 

History

History
318 lines (244 loc) · 25.4 KB

task_061026_21.md

File metadata and controls

318 lines (244 loc) · 25.4 KB

Task: Full-GI Alignment: Contracts Check + Richer GI States, dincli Commands, Integration Suite on Foundry, GI Docs

ID: task_061026_21 Assigned to: Umer Majeed (@umermjd11) Created: 2026-10-06 Status: Open (assigned) Dates: Oct 6 – Oct 17, 2026 (about 8.5 working days; per-Part estimates below). The Parts run in order: A → B → C → D → E. If anything slips, say so early in the tracking discussion. Repo: https://github.com/InfiniteZeroFoundation/DevNet Base branch: develop. The spec was written against a1fcce2 (2026-10-05). Re-pull before starting. Roadmap ref: P3 onboarding (dincli), P3-6.3b (audit preparation), DevNet 2.0 launch readiness Source plan: Developer/tasks-plan/umermjd11/task-plan-051026-2.md, reviewed in PR #229 (verification review, reviewer decisions, decisions applied) Companion task: task_061026_20 (contract follow-ups #201 A4, #180, #193). See Coordination. Tracking:

  • Part C: #223 (closes, pending review): BL-27 deploy constructors and BL-28 release slots.
  • Parts C and E: the Discussion #216 follow-ups left by task_021026_19 (mapped below).
  • Follow-up, not in this task: #228, running the integration suite in its own CI job once Part D passes.
  • Discussion #231 (progress updates, questions, PR links)

Why

The task contracts on develop now have:

  • commit-then-reveal in all three scoring and aggregation phases
  • future-block batch seeds
  • encrypted test data
  • per-GI reward pools with pull claims
  • disputes
  • the modelId constructor argument

dincli and the full-GI integration suite never caught up:

  • The integration suite (tests/dincli/) can't pass with either toolchain.

    • Phase 1 assertion. It asserts a proxyAdmin key (test_01_platform.py:135-137, :164). DeployPlatform.s.sol writes seven per-contract proxyAdmin* keys instead.
    • Old task contracts. It deploys the hardhat task contracts (constants.py:50, ARTIFACT_BASE = hardhat/artifacts/contracts). Those predate foundry: no commit-reveal, rewards, seed lock or encrypted test data, and a 23-member GIstates, while dincli mirrors foundry's 26.
    • ABI overwrite. dump-abi --official (test_01_platform.py:167-197, test_02_task_contracts.py:74-107) overwrites the tracked foundry ABIs in dincli/abis/.
    • Missing steps. test_04_gi.py never funds the pool, registers auditor keys or runs any reveal phase. Its final check (:478) passes on the name but keeps a stale or "23" fallback; GIended is 25.
  • dincli can't drive a full GI.

    • model-owner deploy sends the old constructors (deploy.py:35, :77) and never calls setDinToken.
    • These have no command:
      • depositRewards / DinEmission.fundGI, so gi start reverts with TC_GIRewardPoolNotFunded
      • registerEncryptionKey, so create-testdataset --submit fails. The error message at auditor.py:39 names a dincli auditor register-encryption-key that doesn't exist
      • releaseGIRegistrationSlots, claims, and both dispute families
  • The GI state machine hides progress. Three steps change no state:

    • audit seed waiting vs locked
    • batches created vs test data assigned
    • aggregation seed waiting vs locked

    Worse, startLMsubmissionsEvaluation (DINTaskCoordinator.sol:532-538) doesn't check that test data was assigned. The auditor-side flag (DINTaskAuditor.sol:1033-1045) is one-way, but it's only the owner's own claim; nothing checks that every batch actually has test data.

  • The public GI docs are stale: wrong command names, and the funding, key, seed and reveal steps are missing.

Discussion #216 follow-ups

Follow-up Part
model-owner deploy still uses the old constructors (no modelId) C (closes #223 with BL-28)
No dincli commands for depositing/claiming rewards, registerEncryptionKey or disputes C
din-workflow.md still lists 4 contracts and withdraw E
Old command names in roles/clients.md, roles/auditors.md, roles/model-owner.md, model-workflow.md E
setup.md's broken @main#subdirectory=dist install line E
ROADMAP.md:19 deploy-blocker sentence (wrong since PR #211) E

Sequencing

Part PR Touches Conflicts with Rule
A with B Read-only audit, recorded in this spec. Two text fixes: DINShared.sol:30-34, and the utils.py state-24 text — First
B PR 1 DINShared.sol enum + new error, DINTaskCoordinator.sol (3 transitions + gates), DINTaskAuditor.setTestDataAssignedFlag (commitment check), foundry tests, dincli/cli/utils.py mirrors and every dincli state gate, dincli/abis/, DINShared.md, DINTaskCoordinator.md, DINTaskAuditor.md task_061026_20 PR 1 (DINShared.sol interface; DINTaskAuditor bytes and ABI); PR #29 (subgraph enum); PR #218 (lifecycle test ordinals) After A. Before C/D, so commands and the suite are built on the final state machine
C PR 2 dincli/cli/modelownerd/deploy.py, new commands, dincli/abis/DinEmission.json, cli/context.py helper, dinrep approval check, unit tests — After B
D PR 3 tests/dincli/**, tests/dincli/NOTES.md, dincli-testing-guide.md — After C
E PR 4 Documentation/public/**, CLAUDE.md, DINShared.md §2.2 diagram, ROADMAP.md:19 — Last

Rebase each PR on develop after the previous one merges; no stacked branches.


Part A — Contracts check: what a complete GI needs — with PR 1

This is a read-only pass over every owner and role GI function in DINTaskCoordinator, DINTaskAuditor, DinValidatorStake and DinEmission, checked against DINTaskCoordinator.md §6 and the GIstates enum. The result below is the reference for Parts B–E. Update it in PR 1 if anything has moved.

Preconditions for a complete GI:

Precondition Where Without it
modelId constructor argument on both task contracts DINTaskCoordinator.sol:290, DINTaskAuditor.sol:406 Deploy fails at ABI encoding (BL-27)
setDinToken on the auditor (and the coordinator, for dispute bonds) DINTaskAuditor.sol:440, DINTaskCoordinator.sol:1307 depositRewards, claims and bonds can't move DIN
The GI's reward pool funded before each startGI DINTaskCoordinator.sol:380 → DINTaskAuditor.depositRewards (:481) or DinEmission.fundGI (DinEmission.sol:212) TC_GIRewardPoolNotFunded
Every batch auditor has an X25519 key on DinValidatorStake registerEncryptionKey (DinValidatorStake.sol:509), checked at DINTaskAuditor.sol:1018-1019 TA_AuditorEncryptionKeyNotRegistered when test data is assigned
Seed blocks get mined disputeSeedDelay = 7 blocks; dincli polls (utils.py:1029-1143); anvil --block-time 2 mines The seed lock hangs
The owner opens each of the three reveal windows start*Reveal close / finalize revert

Re-checked at eb8085d (PR 1's base): the preconditions hold, and line references in this spec are updated to that commit. The coverage table below is unchanged: every row marked missing is still missing.

dincli coverage at a1fcce2:

GI step Contract function dincli command
Deploy + wire task-contract constructors; setDINTaskAuditorContract model-owner deploy task-coordinator / task-auditor (old constructors)
Slashers DinCoordinator.addSlasherContract; task-side slasher flags dinrep add-slasher; model-owner add-slasher
Genesis, registry setGenesisModelIpfsHash; requestModelRegistration / approveModel model-owner model submit-genesis-model; task model-owner register-request; dinrep registry approve-*
Wire DIN token setDinToken (both) missing
Fund pool depositRewards / DinEmission.fundGI missing
Start, registration startGI; registration windows; registerDINaggregator / registerDINAuditor gi start; gi reg …; aggregator register; auditor register
Encryption key DinValidatorStake.registerEncryptionKey missing
LMS start/closeLMsubmissions; submitLocalModel lms open/close; client train-lms + submit-lm
Seeds lockAuditSeed / lockAggSeed auditor lock-seed / aggregator lock-seed, and automatic in batch creation
Audit batches, test data createAuditorsBatches; assignAuditTestDataset + setTestDataAssignedFlag auditor-batches create; auditor-batches create-testdataset --submit
Score commit/reveal/close startLMsubmissionsEvaluation, commitAuditScore, startLMsubmissionsEvaluationReveal, revealAuditScore, closeLMsubmissionsEvaluation lms-evaluation start / start-reveal / close; auditor lms-evaluation evaluate --submit / reveal
T1/T2 autoCreateTier1AndTier2; start/commit/startReveal/reveal/finalize T1 and T2; setTier2Score aggregation create-t1nt2-batches, T1/T2 start / start-reveal / close, T2 set-score; aggregator aggregate-t1/t2 --submit, reveal-t1/t2
Slash, end slashAuditors, slashAggregators, endGI slash auditors / aggregators; gi end
Release slots releaseGIRegistrationSlots missing (BL-28)
Claim claimReward(gi) / claimRewards() missing
Disputes coordinator openDispute … claimDisputeBond; auditor openTestDataDispute … reassignAuditTestDataset missing
Owner parameter setters setDisputeParams, setS1/S2/S3*, setRewardSplit, setNetworkFeeFloor, … missing (out of scope)

Text fixes (land in PR 1):

  • DINShared.sol:30-34 says the table has "24 members". There are 26 today, and more after Part B.
  • The dincli/cli/utils.py stateDescription entry for state 24 says "Validators slashed"; it should say aggregators slashed.

If the check turns up any other blocker to a complete GI, fix it in Part B, or raise it on its own issue if it needs a decision. Don't work around it in dincli.

Deliverables (Part A)

  • Preconditions and coverage tables re-checked at the PR's base and updated here if needed
  • Both text fixes in PR 1

Estimate: 0.5 day.


Part B — Richer GI states — PR 1

Each new state is set by the function that already does the step, so a GI needs no extra owner transactions, and dincli task gi show-state (and the subgraph, and dashboards) can say exactly where a GI is. Decision 1, option B: add all three. If the coordinator budget runs short, keep them in this priority: AuditTestDataAssigned first (it closes a real gap), then AuditSeedLocked, then AggSeedLocked.

New state (lifecycle / enum order) Inserted Set by Gate change
AuditSeedLocked between LMSclosed and AuditorsBatchesCreated lockAuditSeed (DINTaskCoordinator.sol:1483, anyone). Only on a successful lock, never on a re-anchor createAuditorsBatches requires AuditSeedLocked
AuditTestDataAssigned between AuditorsBatchesCreated and LMSevaluationStarted setTestDataAssignedFlag (:519) startLMsubmissionsEvaluation requires it. The auditor side (DINTaskAuditor.sol:1033-1045) checks that every batch of the GI has a stored commitment (testDataCommitments[gi][b] != 0, written by assignAuditTestDataset), else it reverts with a new TA_TestDataNotAssigned. The flag is already one-way (TA_FlagMustBeTrue, TA_FlagAlreadySet)
AggSeedLocked between LMSevaluationClosed and T1nT2Bcreated lockAggSeed (:1459) autoCreateTier1AndTier2 requires AggSeedLocked

Not added, and why:

  • A "reward pool funded" state. Funding lives on the auditor contract, anyone can fund, and it targets the next GI. dincli reads giRewardPool(gi) instead.
  • A "test-data dispute pending" state. Disputes are per batch and can overlap evaluation.
  • A "rewards settled" state. endGI settles the pool, so GIended already means that.

Constraints:

  • Insert at the lifecycle position, not at the end, as PR #63 and #197 did. Every later ordinal shifts; with all three, GIended goes from 25 to 28.
  • In the same PR, update everything that encodes ordinals or names:
    • the dincli/cli/utils.py states / stateDescription mirrors
    • every dincli state gate (grep for GIstateToStr and name comparisons)
    • DINShared.md §2.1 / §2.2
    • DINTaskCoordinator.md §6
    • foundry tests that assert ordinals or names
    • the bundled ABIs (dump-abi --official)
  • Post the new ordinal table on PR #29 (the subgraph regenerates its GIstates mapping). Don't push to that branch. If PR #218 has merged, update any ordinals its lifecycle test asserts.
  • Size:
    • Coordinator: DINTaskCoordinator has a 1,079 B margin. Measure each state alone and all three together. Anything that doesn't fit with the gate green follows the priority order above and becomes a view; say so in the PR.
    • Auditor: the commitment check costs DINTaskAuditor +75 B (measured). The combined auditor budget, and the way back out of the warn band, is in task_061026_20 Part A. Once AuditTestDataAssigned guards the double-set, Is_testdataCIDs_Assigned can be removed.
  • lockAuditSeed / lockAggSeed stay permissionless. The state change happens after the seed is stored.

Tests:

  • each transition happens
  • createAuditorsBatches / autoCreateTier1AndTier2 revert before the lock
  • a re-anchor leaves the state unchanged
  • startLMsubmissionsEvaluation reverts until test data is assigned (regression test for the gap)
  • with one batch unassigned, setTestDataAssignedFlag reverts with TA_TestDataNotAssigned, and evaluation can't start
  • the full lifecycle test walks every ordinal

Deliverables (Part B)

  • Three states (or the subset that fits, by priority), the commitment check and the gates, with the tests above
  • dincli mirrors and gates, docs, ABIs and foundry tests updated in the same PR. Ordinal table posted on PR #29
  • Coordinator and auditor sizes in the PR (combined with task_061026_20 if that landed first). Gate green, forge test and pytest -m "not integration" green

Estimate: 1.5 days.


Part C — dincli commands for a complete GI — PR 2

Closes #223 (BL-27 + BL-28).

Deploy (BL-27).

  • model-owner deploy task-coordinator / task-auditor get --model-id, defaulting to DINModelRegistry.totalModels(). That's the ID the next approval assigns (DINModelRegistry.sol:237, 0-based). Warn that the guess only holds if no other request is approved first.
  • The auditor deploy reads modelId() from the coordinator and refuses a mismatch.
  • Both deploys call setDinToken.
  • Fix the latent NameError when the stake entry is missing (deploy.py:27-28, :63-64).
  • modelId check at approval (Decision 2: dincli-side). dinrep registry approve-registration-request compares the requested contracts' modelId() with totalModels() and refuses on a mismatch unless --force is passed. A contract-side check in DINModelRegistry.approveModel is a mainnet-registry follow-up, in the same area as BL-34 / #224.

New commands:

Command Calls Notes
dincli model-owner rewards deposit <model_id> --gi N --amount <DIN> approve + depositRewards Anyone can fund
dincli model-owner rewards fund-emission <model_id> --gi N DinEmission.fundGI Adds dincli/abis/DinEmission.json and get_deployed_din_emission_contract (din_info already has emission)
dincli rewards claim <model_id> --gi N / dincli rewards withdraw <model_id> claimReward(gi) / claimRewards() All roles. First checks giRewardSnapshot(gi).settled and rewardClaimed
dincli auditor register-encryption-key DinValidatorStake.registerEncryptionKey Generates the X25519 key per wallet (e.g. auditor_x25519_<address>.key, chmod 600), replacing today's single shared auditor_x25519.key, which breaks several --demokey auditors on one machine. Updates _load_auditor_x25519_key (auditor.py:33-41) to match. The owner key (auditor_batches.py:170-177) also gets chmod 600
dincli model-owner gi release-slots <model_id> --gi N releaseGIRegistrationSlots BL-28
dincli auditor dispute-test-data, dincli model-owner disputes resolve-test-data / reassign-test-data, … disputes close-expired openTestDataDispute (DINTaskAuditor.sol:1496), resolveTestDataDispute (:1540), closeExpiredDispute (:1573), reassignAuditTestDataset (:1617) Decision 4: in this task. Built against the PR #215 shape: only batch auditors open a dispute, only the owner resolves, an unanswered dispute is upheld on expiry, there's no penalty after settlement, and TA_RewardsAlreadySettled applies. Bond approval comes first
dincli aggregator dispute, dincli model-owner disputes resolve-aggregation / settle-recomputation, … expire, … claim-bond openDispute (DINTaskCoordinator.sol:1368), resolveDispute (:1535), settleRecomputation (:1609), expireDispute (:1671), claimDisputeBond (:1583) S4

Fail fast instead of reverting:

  • gi start checks giRewardPool(next GI) > 0 and points to rewards deposit.
  • create-testdataset --submit checks every batch auditor's key and names any that are missing.

Reuse:

  • build_and_send_tx (dincli/cli/utils.py:978)
  • the ctx.obj.get_deployed_din_task_*_contract(model_id) lookups (cli/context.py:339, :357)
  • a new approve_din(ctx, spender, amount) helper, taken from the inline approve in dintoken.stake_dintokens (dincli/cli/dintoken.py:71-128)

Tests: one pytest per command group, in the tests/test_dinrep_add_slasher.py style (SimpleNamespace context, monkeypatched build_and_send_tx). They cover:

  • call arguments
  • approve before act
  • the fail-fast checks
  • the modelId mismatch refusal

Deliverables (Part C)

  • Deploy with --model-id + setDinToken, NameError fixed, approval-time modelId check
  • Rewards, encryption-key, release-slots and both dispute command families, plus the fail-fast checks
  • Unit tests. pytest -m "not integration" green
  • BL-27 / BL-28 status in Developer/BACK_LOG.md, and the "dincli lags" caveats removed (DINTaskCoordinator.md §10 No. 10, DINTaskAuditor.md §13 No. 8)

Estimate: 3 days.


Part D — The integration suite runs a complete GI on the foundry contracts — PR 3

Toolchain:

  • Point ARTIFACT_BASE at foundry/out. It's the same X.sol/X.json layout, and get_contract_instance already reads bytecode.object (contract_utils.py:150-152).
  • Run npx hardhat compile only when PLATFORM_DEPLOY_TOOLCHAIN=hardhat. Hardhat task contracts leave the GI path.
  • The dump-abi tests write to DIN_TEMP (--output), never --official.
  • Phase 1 asserts the per-contract proxyAdmin* keys.

test_04_gi.py walks one complete GI (Decision 3). Assert the state after every phase with the existing, unused _gi_state helper (:52-58):

  1. setDinToken (from deploy) → rewards deposit (or fund-emission) → gi start
  2. aggregator and auditor registration → auditor register-encryption-key for each auditor
  3. LMS → auditor lock-seed (AuditSeedLocked) → auditor-batches create → create-testdataset --submit (AuditTestDataAssigned)
  4. lms-evaluation start → evaluate --submit → lms-evaluation start-reveal → auditor lms-evaluation reveal → close
  5. aggregator lock-seed (AggSeedLocked) → create-t1nt2-batches
  6. T1 start → aggregate-t1 --submit → T1 start-reveal → reveal-t1 → T1 close; the same for T2; then T2 set-score
  7. slash auditors → slash aggregators → gi end (assert GIended by name and its new ordinal; drop the or "23" fallback)
  8. rewards claim / withdraw for one client, one auditor and one aggregator (assert each DIN balance rises) → gi release-slots

Once task_061026_20 Part B has landed, add a negative check: an aggregator trying to register as an auditor reverts.

Optional second GI: fund GI 2, then gi start from GIended. This proves the loop and slot reuse. Mark it integration + slow and keep it out of CI. Add it only after the single-GI run passes.

Docs: update tests/dincli/NOTES.md (drop the INTERIM hardhat notes, refresh the GI map) and Documentation/technical/testing/dincli-testing-guide.md:

  • 7 platform contracts
  • no hardhat compile
  • the new phases
  • client accounts are really range(2, 11)

Deliverables (Part D)

  • Suite on foundry artifacts, no tracked-file writes, Phase 1 assertions fixed
  • One complete GI with state asserted after every phase, claims and release slots
  • A local pytest tests/dincli/ -v -x -m integration --tb=short run (anvil, IPFS, Docker), passing end to end, with its summary pasted in the PR
  • NOTES.md and the testing guide updated

Estimate: 2 days.


Part E — GI docs — PR 4

Bring each doc in line with the final commands and states:

Doc Main fixes
Documentation/public/workflows/model-workflow.md Foundry artifacts + --model-id; create-genesis-model / submit-genesis-model; task model-owner register-request + DIN-Rep approval; update-manifest-request; funding before gi start; train-lms → submit-lm; auditor key prerequisite; the three reveal windows; seed and test-data states; claim and release slots after gi end
Documentation/public/roles/model-owner.md get-registry-fee; task model-owner … registry commands (replacing the nonexistent model-owner registry …); genesis names; funding; start-reveal for evaluation, T1 and T2; create-testdataset --submit; claim; release slots; disputes
Documentation/public/roles/auditors.md register-encryption-key, lms-evaluation reveal, claim, disputes
Documentation/public/roles/clients.md train-lms then submit-lm, claim
Documentation/public/roles/aggregators.md claim, reveal-t2 --batch, dispute
Documentation/public/getting-started.md aggregator show-t1/t2-batches; auditor key + reveal + lock-seed; submit-lm; the outdated "rewards not the focus" line
Documentation/public/manifest.md, guides/keystore-migration.md genesis command name; train-lms --submit
Documentation/public/workflows/din-workflow.md 7 contracts; withdraw → sweep-fees; the fee-value conflict
Documentation/public/setup.md Option B's pip install git+…@main#subdirectory=dist can't build: dist/ on main holds only wheels and sdists, with no pyproject.toml. Replace it with a working install, e.g. pip install "git+https://github.com/InfiniteZeroFoundation/DevNet.git@main" from the repo root, or a direct wheel URL. Bring Option A's wheel name (dincli-0.1.0) to the current version
Developer/ROADMAP.md:19 Rewrite the deploy-blocker sentence ("24,585 B … 9 B over EIP-170") for the PR #211 sizes and the CI size gate. Flag the "DevNet 3.0" vs "DevNet 2.0" naming in the PR for Umer to decide
Documentation/technical/contracts/DINShared.md §2.2 Diagram with the funding gate and the seed and test-data states
CLAUDE.md 7 platform contracts; GI summary with funding, seed locks, keys, reveals, claim and release slots

Flag the node README's "local Hardhat devnet" line in the PR; don't change it.

After merge, follow up on the wiki pages that still say "no dincli command yet".

Deliverables (Part E)

  • Every doc in the table updated
  • python3 .github/scripts/check_doc_links.py Documentation and … Developer green
  • Wiki follow-up listed in the PR

Estimate: 1.5 days.


Coordination with task_061026_20

  • DINShared.sol. Part B edits the GIstates enum and adds TA_TestDataNotAssigned. task_061026_20 Part B adds isDINAggregator to IDINTaskCoordinator and TA_DualRoleNotAllowed. The sections differ; whichever PR merges second rebases.
  • DINTaskAuditor bytes and ABI. Part B's commitment check (+75 B) counts against the shared budget in task_061026_20 Part A. Both tasks regenerate dincli/abis/DINTaskAuditor.json; the second to merge regenerates on top of the first.
  • Getters. task_061026_20 keeps giRewardSnapshot, rewardClaimed and testDataDisputes public for Part C. Once Part B's state guards the double-set, Is_testdataCIDs_Assigned can go entirely. Settle that in whichever PR lands second.
  • #180 guard. The suite uses disjoint role accounts. Part D adds the negative check once task_061026_20 Part B lands.

Out of scope

  • #228: the integration-suite CI job. It follows once Part D passes.
  • #201 A4, #180, #193: covered by task_061026_20.
  • Owner parameter setters in dincli (setDisputeParams, setS1/S2/S3*, setRewardSplit, setNetworkFeeFloor): revisit with #155.
  • A contract-side modelId check in DINModelRegistry: a mainnet follow-up (BL-34 / #224).
  • BL-29 to BL-33, #194, #78, #181, #178: each needs a design decision first, or is mainnet-grade.