Repository navigation
feat(tooling): dincli system verify-deployment — on-chain drift check (issue #244) - #254
Conversation
…InfiniteZeroFoundation#244) Implements a read-only command that compares foundry/deployments/<network>.json against the live chain and reports [OK] / [DRIFT] / [ERROR] / [INFO] per item. Six check categories: 1. EIP-1967 implementation slot vs recorded dinXxxImpl address 2. EIP-1967 admin slot vs recorded proxyAdminXxx address 3. extcodehash(impl) vs recorded dinXxxImplCodehash 4. ProxyAdmin.owner() vs recorded owner 5. DinCoordinator cross-contract wiring (dinToken, dinValidatorStake, dinModelRegistry) 6. DinValidatorStake slasher authorizations (informational when --slashers not given) Exits 0 on all-OK/INFO, 1 on any DRIFT or ERROR. --no-color flag (auto-detected from isatty) for CI output. Deploy-script changes: DeployPlatform.s.sol: extended _writeDeployments to record each proxy's implementation address, extcodehash (via assembly extcodehash), deployer (ProxyAdmin owner), and optional GIT_COMMIT_HASH env-var value. UpgradePlatform.s.sol: after upgradeProxy(), patches the impl address, codehash, and commit back into the JSON via vm.writeJson. Tests: tests/test_verify_deployment.py — 16 unit tests using a DummyWeb3 that mocks eth.get_storage_at, eth.get_code, and eth.contract calls, following the pattern of tests/test_dintoken.py. Covers all-OK exit 0, DRIFT on impl/admin/codehash/owner mismatch, slasher OK and DRIFT paths, and file-not-found / malformed-JSON error handling. Docs: Documentation/public/guides/verify-deployment.md added. BACK_LOG.md BL-33 → ✅ Fixed (PR #<n>).
… tests - pyproject.toml: add eth-utils>=2.0.0 (imported directly in system.py; was only a transitive dep via web3, caught by test_develop_small_backports) - test_develop_small_backports.py: add eth_utils → eth-utils mapping to _MODULE_TO_DIST (same pattern as eth_account, eth_abi) - test_verify_deployment.py: catch (click.exceptions.Exit, typer.Exit) so tests pass on typer versions where typer.Exit is not a subclass of click.exceptions.Exit
|
Cc: @umeradl |
Santiagocetran
left a comment
There was a problem hiding this comment.
Thanks, Robbert. Reviewed commit 04ae2dd against issue #244 and its approved amendments. I found three points to address before approval.
- P2: Use the actual contract getters for wiring checks.
The checker calls dinValidatorStake() and dinModelRegistry() on DinCoordinator, but the contract exposes dinValidatorStakeContract() and no dinModelRegistry() getter. This can report an error for a correctly configured deployment. The mocked tests provide those same nonexistent getters, hiding the mismatch.
Please use getters and relationships present in the actual contracts, and add regression coverage that matches the real ABI.
- P2: Allow normal CLI invocation without a wallet.
verify-deployment is missing from the system callback’s account-free command list, so the callback loads an account before this read-only command runs. The tests invoke the function directly and bypass that callback.
Please skip account initialization for this command and add a CLI-dispatch test with RPC configured but no wallet/private key.
- P2: Complete the agreed ownership and wiring checks.
Issue #244 includes owner() checks on ownable application contracts and fee-router/treasury wiring. The approved amendment adds ProxyAdmin ownership checks rather than replacing the original requirements.
The implementation only checks ProxyAdmin.owner() and does not compare FeeRouter.treasury() against the recorded treasury. Changes to application ownership or the fee router’s treasury destination therefore go unchecked.
Please implement these agreed comparisons with their expected values, or explicitly agree a narrower scope before marking #244/BL33 complete.
These findings are based on inspection of the implementation, tests and approved scope.
Please address these findings and sync the branch with develop. The updated head, fresh CI and remaining verification need to be checked before approval.
…ner and FeeRouter.treasury checks, register command as account-free - Fix _WIRING_ABI to use dinToken/dinValidatorStakeContract/feeRouter (not the old dinValidatorStake/dinModelRegistry names) - Add Check 4b: application proxy owner() loop over all _PROXIES - Add FeeRouter.treasury() → recorded dinTreasury wiring check (Check 5b) - Add _FEE_ROUTER_ABI for treasury() call - Checksum both sides of wiring address comparison to survive mixed-case inputs from mocks or contract ABI decoders - Register "verify-deployment" in the account-free callback list so the command never triggers wallet loading - Add TestApplicationOwner, TestFeeRouterTreasury, TestAccountFreeDispatch test classes; all 22 tests pass
|
All three P2 findings from the re-review have been addressed in Finding 1 — wrong getter names in Finding 2 — Finding 3 — missing application proxy owner() and FeeRouter.treasury() checks
All 22 tests pass ( |
|
Cc: @Santiagocetran pls can you review this again |
Santiagocetran
left a comment
There was a problem hiding this comment.
Thanks, Robbert. Rechecked d5895de. The getter correction, account-free dispatch and application-owner checks address those findings. The treasury comparison also detects mismatches with a complete deployment record.
Two points remain before approval:
-
The FeeRouter.treasury comparison is inside the coordinator block. A file recording dinFeeRouter and dinTreasury but omitting dinCoordinator skips this comparison and can exit 0 despite treasury drift. Please move the independent comparison outside that guard and add a regression. This concerns partial records, not the complete file generated by DeployPlatform.
-
#244 and the guide still include registry wiring, but the checker doesn’t verify it. Please cover the agreed relationships through the registry’s actual getters, or agree a narrower scope and update the documentation accordingly.
Please also sync with current develop and obtain fresh CI. Run 40082902897 passed against the earlier baseline. The new deploy/upgrade metadata-writing path still needs verification: the existing script tests avoid run() and don’t exercise that JSON-writing cycle.
These findings are based on source inspection, observed CI and the existing isolated simulation, not a live-chain deployment test.
…, add registry wiring FeeRouter.treasury comparison was nested inside the DinCoordinator block, so a deployments file with dinFeeRouter and dinTreasury but no dinCoordinator would silently skip it and exit 0 despite treasury drift. The check is now independent (Check 5b). DINModelRegistry.dinValidatorStake() is added as a new independent wiring check (Check 5c) matching the guide's stated coverage. The guide table and command docstring are updated to reflect both additions. DeployPlatformHarness exposes _writeDeployments for white-box testing; test_writeDeployments_writesImplAndCodehashMetadata verifies that the JSON-writing cycle records dinTreasuryImpl, its codehash, and owner correctly.
|
Addressed in FeeRouter.treasury inside coordinator block The treasury comparison is now an independent block (Check 5b) — it runs whenever Registry wiring missing
JSON-writing cycle
Guide table Updated to reflect the correct getter names ( All 25 Python tests and all 11 Foundry |
|
Thanks, Robbert. Rechecked 6512498 against my last review. The independent treasury comparison and missing-coordinator regression address the first finding. The registry-to-stake check uses the actual getter with OK/DRIFT coverage. The deploy writer test also exercises the real JSON-writing/readback path. Those points are addressed. One verification item remains: the separate UpgradePlatform metadata-writing path. Could you add focused readback evidence showing that the recorded implementation and codehash match the upgraded implementation, and that commit metadata is written when GIT_COMMIT_HASH is supplied? A test of the production metadata-writing block would be sufficient. Factoring it into a testable helper is fine; no live-network deployment is required. Also, the sync currently changes BL-32 back to “Idea.” Please retain develop’s “Fixed” entry for #255 while preserving your BL-33 update. CI passed after your sync. Develop has since advanced with #258, so please refresh the branch and obtain CI against the updated base before final approval. This recheck is based on source inspection and observed CI, not a deployment or upgrade run. |
Addresses maintainer feedback (Santiagocetran):
1. Add focused Foundry test for UpgradePlatform metadata-writing block:
- Extract _writeUpgradeMetadata internal function from run() so the
test can call it directly without going through the broadcast/upgrade path
- foundry/test/UpgradePlatformScript.t.sol: UpgradePlatformHarness
exposes _writeUpgradeMetadata; test_writeUpgradeMetadata_writesImplCodehashAndCommit
verifies (a) dinTokenImpl matches upgraded implementation address,
(b) dinTokenImplCodehash matches extcodehash(newImpl),
(c) .deployedAtCommit is written when a non-empty commit hash is passed
2. Resolve BACK_LOG.md conflict against develop:
- BL-32: retain develop's PR No. 255 "Mostly fixed" entry
- BL-33: preserve this PR's "Fixed" entry (PR No. 254)
- BL-30, BL-31, BL-34, BL-35: take develop's updated statuses
|
@Santiagocetran Both items from the review addressed in UpgradePlatform metadata test (
The test covers all three requested properties:
All env-polluting calls ( BACK_LOG.md conflict:
|
Santiagocetran
left a comment
There was a problem hiding this comment.
Thanks, Robbert! Rechecked 6512498 → 50aa75e against the remaining review items and issue No. 244’s approved amendments. The new UpgradePlatform test calls the production metadata-writing helper and reads back the implementation address, extcodehash and non-empty commit string. The BL-32 sync regression is resolved; the final backlog diff updates only BL-33. Earlier getter, account-free dispatch, ownership, treasury and registry findings remain addressed. I also compared the checker’s wiring and slasher ABI fragments against the bundled contract ABIs; they match.
Verification: CI run 41210002474 passed all four checks. Its Solidity log explicitly shows both metadata-writing/readback tests passing (518 Foundry tests total); Python reports 631 passed. The local documentation link check also passes. The trial merge into develop at 8f291c1 is clean. This is source and CI-backed verification, not a new live-network deployment or upgrade run.
No new blocking findings. This approval supersedes my earlier changes-requested review. Ready for the merge queue, where fresh CI will validate against current develop.
|
Thanks, Robbert, for addressing the review feedback and adding the upgrade-metadata test! I’ve approved PR No. 254 at 50aa75e, superseding my earlier changes-requested review. The remaining verification and backlog items are resolved, all four CI checks are green, and the merge with current develop is clean. Ready for the merge queue—no additional sync is needed just because develop has advanced; queue CI will validate the combined result. Thanks for your patience! |
cf80216
|
@robertocarlous, cc @Santiagocetran: Failing runs. 2 of 3 CI runs since this merged:
Root cause.
Suggested fix. Take these tests off the environment variable entirely. Give To check the fix, run Per MAINTAINING No. 4.6, this needs fixing today, either a fix on top (through a PR) or a revert of the two tests. Until it's fixed, any PR in the merge queue can be dropped at random. Logged in Discussion 170. |
Closes #244
Summary
dincli system verify-deployment: a read-only command that readsfoundry/deployments/<network>.jsonand checks six categories against the live chain, reporting[OK]/[DRIFT]/[ERROR]/[INFO]per item. Exits 0 on all-OK, 1 on any DRIFT or ERROR.DeployPlatform.s.solandUpgradePlatform.s.solto write implementation addresses, extcodehashes, deployer, and optional git commit hash into the JSON at deploy time — giving the drift check a source of truth to compare against.Check categories
dinXxxImplproxyAdminXxxextcodehash(impl)dinXxxImplCodehashin JSONProxyAdmin.owner()ownerDinCoordinatorwiringdinToken/dinValidatorStake/dinModelRegistrymismatch--slashers)Changes
dincli/cli/system.pyverify-deploymentcommand with--file,--no-color(auto-detected fromisatty()), and--slashersflags.ctx.obj.w3andctx.obj.networkdirectly — no wallet needed.foundry/script/DeployPlatform.s.sol_writeDeploymentsto accept theDeploymentstruct +deployer.dinXxxImpl(implementation address viaUpgrades.getImplementationAddress),dinXxxImplCodehash(via assemblyextcodehash),owner(deployer/ProxyAdmin owner), anddeployedAtCommit(GIT_COMMIT_HASHenv var, empty string if unset).foundry/script/UpgradePlatform.s.solupgradeProxy(), patches the relevantimpladdress,implCodehash, and commit back into the JSON viavm.writeJson.tests/test_verify_deployment.pyDummyWeb3that mockseth.get_storage_at,eth.get_code, andeth.contract, following the pattern oftests/test_dintoken.py.Documentation/public/guides/verify-deployment.md— new usage guide.Developer/BACK_LOG.md— BL-33 flipped to ✅ Fixed.Test plan
python3.12 -m pytest tests/test_verify_deployment.py— 16/16 passpython3.12 -m pytest tests/test_dintoken.py tests/test_ipfs_config.py— all pass (no regressions)forge buildinfoundry/— exits 0 (DeployPlatform and UpgradePlatform compile cleanly)dincli/cli/system.py) and PR feat(stake): cross-model S5 escalation (#193) #236 (foundry/script/DeployPlatform.s.sol) — both open. The system.py change is additive (new command only, no edits to existing commands); the DeployPlatform change is isolated to_writeDeployments. Will rebase after those land.Closes #244