Skip to content

feat(dincli): rewards, encryption-key, release-slots and dispute commands (task_061026_21 Part C) - #302

Open
umermjd11 wants to merge 2 commits into
InfiniteZeroFoundation:developfrom
umermjd11:feat/task-061026-21-dincli-commands
Open

umermjd11 wants to merge 2 commits into
InfiniteZeroFoundation:developfrom
umermjd11:feat/task-061026-21-dincli-commands

Conversation

@umermjd11

Copy link
Copy Markdown
Collaborator

Summary

task_061026_21 Part C, PR 2: the dincli commands needed to drive a complete GI on the foundry task contracts. Spec: Developer/tasks/task_061026_21.md. Tracking: Discussion #231.

Closes BL-28 (#223 Part 2). #223 Part 1 (deploy --model-id) is in #261; see Scope below.

New commands

Command Calls Checks before sending
model-owner rewards deposit <model_id> --amount <DIN> [--gi N] approve_din → depositRewards GI ≥ current (defaults to the next GI), dinToken set, balance
model-owner rewards fund-emission <model_id> [--gi N] DinEmission.fundGI(gi, taskAuditor) registered in the registry, GI not already funded, schedule not exhausted
rewards claim <model_id> --gi N / rewards withdraw <model_id> claimReward(gi) / claimRewards() giRewardSnapshot(gi).settled, rewardClaimed, claimable > 0
auditor register-encryption-key DinValidatorStake.registerEncryptionKey skips the tx if that key is already registered
model-owner gi release-slots <model_id> [--gi N] releaseGIRegistrationSlots GI ended, not already released
auditor dispute-test-data <model_id> --batch B approve_din → openTestDataDispute batch auditor, not settled, commitment exists, no active/pending dispute
model-owner disputes resolve-test-data / close-expired / reassign-test-data resolveTestDataDispute / closeExpiredDispute / reassignAuditTestDataset active dispute, which side of the window we're on, pending reassignment, auditor keys
aggregator dispute <model_id> --tier t1|t2 --batch B approve_din → openDispute not already disputed, dinToken set
model-owner disputes resolve-aggregation --upheld/--rejected, settle-recomputation --confirmed/--dismissed, expire resolveDispute / settleRecomputation / expireDispute dispute state; upholding locks the dispute seed first (lockDisputeSeed, waiting for seedBlock)
aggregator claim-dispute-bond <model_id> claimDisputeBond disputeBondClaimable > 0

Fail-fast checks on existing commands

  • gi start exits if giRewardPool(next GI) == 0 and points to rewards deposit. It checks this before the pass-score evaluation, which needs the test dataset.
  • auditor-batches create-testdataset --submit checks every batch auditor's key before sending any tx, and names any auditor that hasn't registered one.
  • dinrep registry approve-registration-request compares each requested contract's modelId() with totalModels() (Decision 2: the check is in dincli) and refuses a mismatch unless --force is passed.

Keys and secrets

  • Auditor X25519 key, one per wallet: stored as auditor_x25519_<checksum address>.key, chmod 600. It replaces the single auditor_x25519.key, which stopped several --demokey auditors on one machine from working. _load_auditor_x25519_key(address) matches the new layout. An existing shared key isn't migrated: an auditor reruns register-encryption-key, which registers a new key.
  • Owner key owner_x25519.key is now chmod 600.
  • Per-batch K and plaintext hash: create-testdataset --submit and reassign-test-data save them to <model dir>/audits/testdata_keys/gi_<gi>_batch_<b>.json (chmod 600), before the assign tx goes out. resolve-test-data needs them: until now K was never persisted, so the owner had no way to answer a dispute.
  • The per-batch encryption is moved into _encrypt_batch_testdata, which assign and reassign share. Its output is unchanged.

Reuse

  • The new approve_din(ctx, spender, amount) helper comes from the inline approve in stake_dintokens, which now uses it. Every bond and deposit command goes through it.
  • build_and_send_tx and the get_deployed_din_task_*_contract lookups, as the spec asks.
  • dincli/abis/DinEmission.json is generated from foundry/out in the dump-abi format, and there's a new get_deployed_din_emission_contract. All the other bundled ABIs match foundry/out on this base.

Scope and deviations, for review

  1. Deploy (BL-27, dincli model-owner: deploy sends stale constructor args (broken); no command for releaseGIRegistrationSlots (BL-27, BL-28) #223 Part 1) isn't in this PR. feat(cache_model_0): refresh task-contract ABIs from foundry and fix deploy constructors (BL-25) #261 (robertocarlous) already adds --model-id and the coordinator modelId() check to deploy.py and is close to approval. Doing it here too would conflict. Once feat(cache_model_0): refresh task-contract ABIs from foundry and fix deploy constructors (BL-25) #261 merges, a small follow-up adds the rest of the spec's deploy items:

    • setDinToken on both contracts
    • defaulting --model-id to totalModels()
    • the NameError fix

    The caveats in DINTaskCoordinator.md §10 No. 10 and DINTaskAuditor.md §13 No. 8 are about deploy, so they wait for that follow-up as well.

  2. claim-dispute-bond is under aggregator, not model-owner disputes. claimDisputeBond pays msg.sender, and only the challenger ever has a balance; a model owner never would.

  3. close-expired and expire stay under model-owner disputes, as the spec lists them. Both are permissionless, so a disputer can run them from there too.

  4. reassign-test-data re-runs the owner's create_audit_testDataCIDs service and uses only the disputed batch's entry. The service has no single-batch entry point, so it re-uploads every batch with fresh keys; only the reassigned batch's data goes on-chain.

  5. Order relative to feat(task-coordinator): re-land richer GI states — AuditSeedLocked, AuditTestDataAssigned, AggSeedLocked (task_061026_21 A+B) #287 (Part B re-land). The spec says Part C goes after B. Nothing here depends on the new states: create-testdataset already handles AuditTestDataAssigned, and the funding check reads the pool, not the state. Both PRs touch auditor_batches.py, in different hunks, so whichever lands second rebases.

Tests

One pytest file per command group, using a shared tests/_cli_fakes.py (fake contracts plus a monkeypatched build_and_send_tx that records sent calls in order):

  • test_rewards_commands.py: deposit/fund-emission/claim/withdraw, plus a CliRunner --help check for all 15 new command paths
  • test_auditor_encryption_key.py: one key per wallet, 0600, reuse, skip when already on-chain
  • test_dispute_commands.py: both dispute families; bond approval comes before the open; the seed is locked before an upheld resolve; window checks
  • test_gi_release_slots_and_funding.py: release-slots and the gi start funding check
  • test_dinrep_approve_model_id.py: refusal on a mismatch, --force, and the matching case
  • test_create_testdataset_submit.py: the keyless-auditor exit (before any tx), and per-batch secrets plus the owner key saved as 0600

test_dintoken.py: its dummy get_deployed_din_token_contract now takes verbose, like the real method.

pytest -m "not integration"
609 passed, 133 deselected

Not run against a chain. The full-GI integration run is Part D (PR 3).

🤖 Generated with Claude Code

…ands (task_061026_21 Part C)

Adds the dincli commands a complete GI needs that had no CLI path:

- rewards: `model-owner rewards deposit` / `fund-emission` (DinEmission
  ABI + context getter), `rewards claim` / `withdraw` for every role
- `auditor register-encryption-key`, with one X25519 key per wallet
  (auditor_x25519_<address>.key, 0600) instead of one shared file;
  the owner key is now 0600 too
- `model-owner gi release-slots` (BL-28, InfiniteZeroFoundation#223 Part 2)
- test-data disputes: `auditor dispute-test-data`, `model-owner disputes
  resolve-test-data / reassign-test-data / close-expired`. Each batch's K
  and plaintext hash are saved (0600) at assignment so the owner can answer
- aggregation disputes: `aggregator dispute` / `claim-dispute-bond`,
  `model-owner disputes resolve-aggregation / settle-recomputation / expire`
- fail fast: `gi start` on an empty reward pool, `create-testdataset
  --submit` on a keyless batch auditor (named), and
  `dinrep registry approve-registration-request` on a task-contract
  modelId() that isn't the ID the approval assigns (`--force` overrides)
- shared `approve_din` helper, reused by `stake`

Deploy `--model-id` (InfiniteZeroFoundation#223 Part 1) is left to PR InfiniteZeroFoundation#261.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ispute seed (BL-11)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copy link
Copy Markdown
Collaborator

Reviewed head 15e7afc3f274926fa5f87671ddc351e5a51cc51c against develop / merge-base e9424af1db5c17fabb0919253954ba5f435337aa: two commits ahead, zero behind. At the October 29, 18:09 UTC refresh, GitHub reported open/mergeable and no discussion comments. Recheck before posting.

Changes requested

1. P1 — Block funding a settled GI. Target selection accepts the current GI after settlement. depositRewards accepts it, but claims use the frozen settlement snapshot: additional DIN never becomes claimable, and emission funding also consumes a schedule step. Fix: reject giRewardSnapshot(target).settled before approval/funding; test both deposit and emission against a settled current GI. Evidence: CLI/contract inspection, not chain reproduction.

2. P1 — Preserve the last confirmed test-data secret. Persistence overwrites the sole GI/batch file before assignment. Following partial success or flag failure, a retry can save K2 and then fail its replacement transaction, leaving K1 committed on-chain but lost locally. resolve-test-data then reveals the mismatch, upholding the dispute and potentially penalizing rewards. Fix: retain commitment-indexed pending/confirmed secrets and verify the on-chain commitment before revealing. Add success → retry failure → resolve regressions. An offline probe of the exact extracted helpers confirmed overwrite behavior with a simulated failed transaction; no full CLI/chain flow was run.

3. P2 — Create secrets with 0600 immediately. Auditor-key creation and batch-secret writes precede chmod. With umask 022, files can initially be 0644; interruption leaves exposure. Fix: safe exclusive/atomic creation with 0600 at open. Test creation-time permissions and interruption, not just final mode. Evidence: source inspection.

Claimed / verified

  • Rewards/emission, claims, slots and model-ID checks: relevant selectors, getter positions and guards align statically; mock tests cover arguments/order/early exits, not balances or contract execution. Finding 1 remains.
  • Keys, saved K/hash and shared encryption: implemented; wallet separation/reuse and final permissions have mock coverage. Findings 2–3 remain; real decryption, retry recovery and encrypted-output equivalence were not verified.
  • Disputes and fail-fast checks: source/mocks support bond-before-open, seed-before-uphold, selected state/windows and keyless-auditor refusal. Reassignment, recomputation, slashing and timeout recovery lack independent chain evidence.
  • Helper reuse/ABI: reuse and relevant signatures checked; artifact generation/full ABI equality not reproduced.
  • Tests: CI run has Python, Solidity, Docs and CI OK green. Its nonblocking full-GI job failed on the existing platform proxyAdmin assertion before new flows. Author-reported 609 passes were not independently reproduced. No local full pytest/build/live-chain/IPFS run; dependencies unavailable.

Scope/process: deploy follow-up, documentation/artifact paths and Part D remain outstanding; keep issue No. 223 open. Neither commit has closing keywords; prefer “Part of issue No. 223; addresses BL-28” in the body. Authenticated peer helper, isolated Git worktree and local merge-tree check were not run: this is not a completed formal skill run or eligibility certification. umeradl and author umermjd11 are one person; obtain an eligible independent peer. No contract-source changes trigger the automatic second-signoff rule here; any later contract/mechanism fix needs its own review.

Recommendation: request changes on the three findings, then recheck regressions, final SHA/CI and live-flow coverage.

Copy link
Copy Markdown
Collaborator

23 files; +2105/-63, at the head/base above. Global table notes: base equals merge-base (no intervening base drift); GitHub reports mergeable: true, but supplied no mergeStateStatus. Local conflicts were not checked, so local/GitHub agreement is unestablished. “Base unchanged”, “Not checked” and “None reported” below refer to these global facts—not per-file local verification. All actual proposals remain Soon.

Developer/BACK_LOG.md

Field Value
Change Modified
Lines +2/-2
Diff (what exactly is in this PR) BL-28 review status; BL-11 seed-lock note.
Functionality — how & why How: Links pending work and records CLI mitigation. Why: keeps status accurate.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Keep issue No. 223 open.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/abis/DinEmission.json

Field Value
Change New
Lines +553/-0
Diff (what exactly is in this PR) Adds DinEmission ABI.
Functionality — how & why How: Enables emission contract calls. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep; verify generated equality.
Actual merge proposal Soon
Pending proposal Artifact equality not reproduced.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/aggregator.py

Field Value
Change Modified
Lines +65/-2
Diff (what exactly is in this PR) Adds dispute/open and bond claim.
Functionality — how & why How: Approves bond before opening; pays challenger. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Real bond flow unverified.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/auditor.py

Field Value
Change Modified
Lines +87/-5
Diff (what exactly is in this PR) Wallet-specific keys; registration; test-data disputes.
Functionality — how & why How: Separates identities and preflights dispute eligibility. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Fix finding 3.
Actual merge proposal Soon
Pending proposal Creation/interruption tests.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/context.py

Field Value
Change Modified
Lines +9/-0
Diff (what exactly is in this PR) Adds emission lookup.
Functionality — how & why How: Resolves configured address and bundled ABI. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Deployed lookup unverified.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/dinrep.py

Field Value
Change Modified
Lines +37/-1
Diff (what exactly is in this PR) Approval model-ID check plus force.
Functionality — how & why How: Compares both requested IDs with next registry ID. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Deployed approval unverified.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/dintoken.py

Field Value
Change Modified
Lines +21/-10
Diff (what exactly is in this PR) Extracts approve_din; reuses in staking.
Functionality — how & why How: Centralizes allowance-before-action. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Real allowance flow unverified.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/modelowner.py

Field Value
Change Modified
Lines +4/-0
Diff (what exactly is in this PR) Registers rewards/disputes groups.
Functionality — how & why How: Exposes owner command paths. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep wiring.
Actual merge proposal Soon
Pending proposal Dependent fixes 1–2.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/modelownerd/auditor_batches.py

Field Value
Change Modified
Lines +106/-42
Diff (what exactly is in this PR) Shared encryption; key preflight; K/hash persistence.
Functionality — how & why How: Prepares assignments and dispute answers. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Fix findings 2–3.
Actual merge proposal Soon
Pending proposal Retry-safe secrets; atomic 0600.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/modelownerd/disputes.py

Field Value
Change New
Lines +277/-0
Diff (what exactly is in this PR) Adds both dispute response/settlement families.
Functionality — how & why How: Checks states/windows; reveals K; locks seed. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Fix finding 2 at reveal.
Actual merge proposal Soon
Pending proposal Commitment match; chain coverage.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/modelownerd/gi.py

Field Value
Change Modified
Lines +39/-0
Diff (what exactly is in this PR) Release-slots; start funding preflight.
Functionality — how & why How: Releases ended slots; checks pool before scoring. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Real slot/GI loop unverified.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/modelownerd/rewards.py

Field Value
Change New
Lines +104/-0
Diff (what exactly is in this PR) Adds deposit/emission funding.
Functionality — how & why How: Approves deposit; checks emission eligibility. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Fix finding 1.
Actual merge proposal Soon
Pending proposal Reject settled target; regressions.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/rewards.py

Field Value
Change New
Lines +63/-0
Diff (what exactly is in this PR) Adds claim and withdraw.
Functionality — how & why How: Credits GI shares, then transfers claimable DIN. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Actual shares/transfers unverified.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/cli/utils.py

Field Value
Change Modified
Lines +11/-0
Diff (what exactly is in this PR) Adds tier parsing.
Functionality — how & why How: Normalizes t1/t2 and rejects invalid tiers. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal None identified.
Local merge conflict Not checked.
GitHub merge conflict None reported.

dincli/main.py

Field Value
Change Modified
Lines +2/-0
Diff (what exactly is in this PR) Registers top-level rewards.
Functionality — how & why How: Exposes claim/withdraw entry points. Why: CLI coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Help is wiring evidence only.
Local merge conflict Not checked.
GitHub merge conflict None reported.

tests/_cli_fakes.py

Field Value
Change New
Lines +122/-0
Diff (what exactly is in this PR) Adds shared contract/context/tx fakes.
Functionality — how & why How: Records calls for offline unit tests. Why: regression coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Not contract/financial evidence.
Local merge conflict Not checked.
GitHub merge conflict None reported.

tests/test_auditor_encryption_key.py

Field Value
Change New
Lines +72/-0
Diff (what exactly is in this PR) Tests key separation/reuse/final mode.
Functionality — how & why How: Guards local registration decisions. Why: regression coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Extend for finding 3.
Actual merge proposal Soon
Pending proposal Creation-time/interruption coverage.
Local merge conflict Not checked.
GitHub merge conflict None reported.

tests/test_create_testdataset_submit.py

Field Value
Change Modified
Lines +44/-0
Diff (what exactly is in this PR) Tests keyless refusal and saved secrets/mode.
Functionality — how & why How: Guards assignment preflight/persistence. Why: regression coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Extend for findings 2–3.
Actual merge proposal Soon
Pending proposal Failed replacement; initial mode.
Local merge conflict Not checked.
GitHub merge conflict None reported.

tests/test_dinrep_approve_model_id.py

Field Value
Change New
Lines +60/-0
Diff (what exactly is in this PR) Tests matching/mismatch/force approval.
Functionality — how & why How: Guards ID-check send/refuse branches. Why: regression coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Fake getters, not registry execution.
Local merge conflict Not checked.
GitHub merge conflict None reported.

tests/test_dintoken.py

Field Value
Change Modified
Lines +1/-1
Diff (what exactly is in this PR) Dummy lookup accepts verbose.
Functionality — how & why How: Keeps staking tests helper-compatible. Why: regression coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal Compatibility only.
Local merge conflict Not checked.
GitHub merge conflict None reported.

tests/test_dispute_commands.py

Field Value
Change New
Lines +186/-0
Diff (what exactly is in this PR) Tests dispute states/windows/call order.
Functionality — how & why How: Guards mocked bonds, seed and resolution calls. Why: regression coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Extend for finding 2.
Actual merge proposal Soon
Pending proposal Reject stale saved reveal.
Local merge conflict Not checked.
GitHub merge conflict None reported.

tests/test_gi_release_slots_and_funding.py

Field Value
Change New
Lines +63/-0
Diff (what exactly is in this PR) Tests slots and unfunded start.
Functionality — how & why How: Guards GI preflight/transaction selection. Why: regression coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Keep.
Actual merge proposal Soon
Pending proposal No real registration-count test.
Local merge conflict Not checked.
GitHub merge conflict None reported.

tests/test_rewards_commands.py

Field Value
Change New
Lines +177/-0
Diff (what exactly is in this PR) Tests funding/claims and 15 help paths.
Functionality — how & why How: Guards mock arguments/order and registration. Why: regression coverage.
Diff vs current develop HEAD Base unchanged.
Recommended merge proposal Extend for finding 1.
Actual merge proposal Soon
Pending proposal Settled target sends nothing.
Local merge conflict Not checked.
GitHub merge conflict None reported.

Verification

Comment 1 distinguishes observed CI, source/mocks and the extracted-helper simulation. No full local suite or live flow was run; full-GI CI failed before these commands. Local/GitHub conflict agreement: not established. Resolve findings 1–3 and recheck eligibility/head/CI before approval.

Copy link
Copy Markdown
Collaborator

Thanks Umer! These commands are a useful step forward. I’d address the three funding and secret-handling findings, add the regression tests, and then recheck before merging. The remaining live-flow verification is noted above.

@robertocarlous

Copy link
Copy Markdown
Collaborator

Reviewed against develop in an isolated worktree (pr-302-review on top of 15e7afc3, the PR head). Peer check: OK (umermjd11 is the author; operator is not).

CI on 15e7afc3: CI OK ✅, Python ✅ (609 passed, 133 deselected), Solidity ✅, Docs ✅ — all green. Integration (full GI) failed, but that is explicitly non-blocking per MAINTAINING No. 4.9 and the PR body ("Not run against a chain. The full-GI integration run is Part D (PR 3)").

The PR's own work is two commits: 01c26e0b (all new commands, +2103/-61 lines) and 15e7afc3 (BACK_LOG.md only). The remaining diff against upstream/develop is from upstream merge commits already on develop.


Claimed — all 15 new command paths are registered. Verified via test_command_is_registered, which invokes CliRunner().invoke(main_app, [..., "--help"]) on every path and asserts exit_code == 0. Wiring: dincli/cli/rewards.py (claim/withdraw, any role) added at the top level via main.py; dincli/cli/modelownerd/rewards.py (deposit/fund-emission, model owner) and dincli/cli/modelownerd/disputes.py added under model-owner via modelowner.py. Both the top-level rewards sub-app and the model-owner rewards sub-app exist and are routed to different Typer apps.

Claimed — approve_din helper is extracted and reused by stake, deposit and dispute-bond commands. Verified: approve_din added in dintoken.py; it calls din_token.functions.approve(spender, amount) followed by time.sleep(5). stake_dintokens now uses it (replacing the same inline block). All three callers that need a DIN pull — reward deposit, test-data dispute bond, aggregation dispute bond — go through it.

Claimed — gi start fails fast on an empty reward pool before the pass-score evaluation. Verified in gi.py L~93–100: immediately after the GI-index check and before the manifest policy section, the code reads giRewardPool(target_gi) and exits with a user-friendly message pointing to rewards deposit / fund-emission if zero. Test: test_gi_start_exits_early_if_reward_pool_is_empty in test_gi_release_slots_and_funding.py asserts no tx is sent and the message contains "reward pool is empty."

Claimed — resolve-aggregation --upheld locks the dispute seed before calling resolveDispute. Verified in disputes.py _lock_dispute_seed: polls until disputes(...)[8] != ZERO_BYTES32, waits for seedBlock, then calls lockDisputeSeed with exit_on_failure=False; if the receipt is None and the seed is still zero, raises Exit. build_and_send_tx with exit_on_failure=False returns None on any failure, confirmed at L1008–1035 of utils.py. Test: test_resolve_aggregation_upheld_locks_the_seed_first uses a callable views["disputes"] that returns a locked seed only after lockDisputeSeed appears in sent; asserts [lockDisputeSeed, resolveDispute] in order.

Claimed — one X25519 key per wallet. Verified: _auditor_x25519_key_path(address) returns auditor_x25519_<checksum_address>.key; _load_auditor_x25519_key(address) uses it; the old single-file path is gone. key_path.chmod(0o600) is called on every code path through register-encryption-key. The owner key owner_x25519.key is similarly chmod'd 0o600 via _load_owner_x25519_key.

Claimed — per-batch K and plaintext hash saved before the assign tx. Verified in auditor_batches.py: _save_testdata_secret writes {"K": hex, "plaintext_keccak": hex} to audits/testdata_keys/gi_<gi>_batch_<b>.json and calls .chmod(0o600) before returning. create-testdataset --submit calls it inside the batch loop, before build_and_send_tx(assignAuditTestDataset). _load_testdata_secret is used by resolve-test-data to recover K for the on-chain reveal.

Claimed — create-testdataset --submit exits before any tx if any batch auditor is missing an encryption key. Verified: _auditors_missing_encryption_key collects all addresses with len(getEncryptionKey(addr).call()) == 0 across all batches to process, raises Exit with their addresses if non-empty, and does so before the first assignAuditTestDataset call. Test: test_create_testdataset_exits_before_any_tx_if_an_auditor_key_is_missing.

Claimed — dinrep registry approve-registration-request reads modelId() from both task contracts and compares to totalModels(). Verified: _task_contract_model_ids reads req[3] (taskCoordinator) and req[4] (taskAuditor) from the modelRequests(requestId) tuple. Struct layout in DINModelRegistry.sol L85–95: [0]requester [1]isOpenSource [2]manifestCID [3]taskCoordinator [4]taskAuditor .... The indexing is correct. Mismatching contracts are named individually in the error message. --force bypasses the check. Test: test_dinrep_approve_model_id.py covers mismatch (refusal), force, and matching cases.

Claimed — DinEmission.json ABI is sourced from foundry/out. Verified: fundGI, giEmissionFunded, and emissionForCurrentEpoch all appear in the ABI and all exist in foundry/src/DinEmission.sol (L212, L250, and a view getter respectively). get_deployed_din_emission_contract reads the "emission" key from din_info (consistent with how all other platform contract getters resolve addresses).

Claimed — BACK_LOG.md BL-28 updated. Verified: BL-28 changed from "🆕 New — unaddressed" to "🟡 Fix in review — PR No. 302 adds dincli model-owner gi release-slots." BL-11 updated to note that model-owner disputes resolve-aggregation --upheld now locks the seed itself.


No findings. Merge-ready; branch needs update-branch before merge (BEHIND develop, no conflict). No foundry/src/** touched, so no second sign-off is required.

@robertocarlous

Copy link
Copy Markdown
Collaborator

Head at review: 15e7afc3
Merge base (upstream develop): behind but clean — no conflict (merge-tree exit 0)


dincli/abis/DinEmission.json (new)

Key Value
Change +553 lines: DinEmission ABI sourced from foundry/out via dump-abi format
Pending proposal None — fundGI, giEmissionFunded, emissionForCurrentEpoch verified against source
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/context.py

Key Value
Change +9 lines: get_deployed_din_emission_contract reads "emission" key from din_info; consistent pattern with all other platform getters
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/dintoken.py

Key Value
Change +18/-13 lines: approve_din(ctx, spender, amount, purpose) extracted from stake_dintokens; stake_dintokens now calls it
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/utils.py

Key Value
Change +11 lines: TIER_KINDS dict and parse_tier_kind(tier) helper for T1/T2 enum encoding
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/modelownerd/rewards.py (new)

Key Value
Change +104 lines: deposit (approve → depositRewards, defaults to next GI) and fund-emission (DinEmission.fundGI, with pre-flight registry/funded/schedule checks)
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/rewards.py (new)

Key Value
Change +63 lines: claim (claimReward for one GI, guards on settled + already-claimed) and withdraw (claimRewards, guards on claimable > 0) for any role
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/modelownerd/gi.py

Key Value
Change +39 lines: gi start reward-pool pre-check (before pass-score evaluation); release-slots command (guards on GI ended + not already released)
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/auditor.py

Key Value
Change +92/-1 lines: _load_auditor_x25519_key renamed to take address; _auditor_x25519_key_path(address) helper; register-encryption-key command (generate/reuse per-wallet key, chmod 0600, skip if already on-chain); dispute-test-data command (pre-flight checks before approve → openTestDataDispute)
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/modelownerd/auditor_batches.py

Key Value
Change +148/-8 lines: _load_owner_x25519_key, _save_testdata_secret, _load_testdata_secret, _auditors_missing_encryption_key, _encrypt_batch_testdata extracted as shared helpers; create-testdataset --submit gains keyless-auditor exit (before any tx) and per-batch secret save (before assign tx); owner key chmod 0600
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/modelownerd/disputes.py (new)

Key Value
Change +277 lines: resolve-test-data, close-expired, reassign-test-data (test-data dispute family); resolve-aggregation (uphold: locks seed first → resolveDispute; reject: direct), settle-recomputation, expire (aggregation dispute family)
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/aggregator.py

Key Value
Change +67/-3 lines: dispute (approve DIN bond → openDispute, guards on existing dispute + dinToken set); claim-dispute-bond (guards on disputeBondClaimable > 0)
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/dinrep.py

Key Value
Change +38/-5 lines: approve_registration_request gains --force; _task_contract_model_ids reads modelId() from both task contracts (req[3]=coordinator, req[4]=auditor, verified against ModelRequest struct layout); refuses approval on mismatch unless --force
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

dincli/cli/modelowner.py / dincli/main.py

Key Value
Change rewards_app and disputes_app wired under model-owner; rewards.app (claim/withdraw) wired at top level
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

tests/_cli_fakes.py (new) / tests/test_rewards_commands.py / tests/test_dispute_commands.py / tests/test_gi_release_slots_and_funding.py / tests/test_auditor_encryption_key.py / tests/test_dinrep_approve_model_id.py / tests/test_create_testdataset_submit.py

Key Value
Change +684 lines across 7 files: shared FakeContract/FakeCtxObj/record_txs infrastructure; one test file per command group; pre-tx exit checks throughout; test_command_is_registered covers all 15 new paths via --help
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

tests/test_dintoken.py

Key Value
Change +2/-1 lines: dummy get_deployed_din_token_contract updated to accept verbose kwarg
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

Developer/BACK_LOG.md

Key Value
Change BL-28: "Fix in review — PR No. 302 adds release-slots"; BL-11 residual note updated: dincli's resolve-aggregation --upheld now locks the seed
Pending proposal None
Recommended merge proposal Merge as-is
Actual merge proposal Soon

@robertocarlous robertocarlous 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.

15 new commands verified: wiring, pre-flight checks, per-wallet key paths, per-batch secret save-before-tx, seed-lock ordering, modelRequests tuple indexing, DinEmission ABI vs source. All 609 tests pass at 15e7afc3. No findings.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants