Repository navigation
feat(cow): source the registry address from module [config] - #666
Conversation
1aa7891 to
acf0e06
Compare
acf0e06 to
336789c
Compare
|
Rebased onto The manifest moved underneath this PR, so the On the test overlap with Verified: 182 tests pass workspace-wide (173 plus this PR's 9), fmt and clippy clean at Worth recording why this car matters more than its diff suggests. The fork registry is at AI Assistance: Claude Code used for the rebase, the schema migration of the parity test, and verification. |
The keeper learns the ComposableCoW registry from its manifest [config] instead of the compiled cowprotocol::COMPOSABLE_COW constant. A missing or malformed registry key is a hard init error; there is no fallback of any kind. A manifest parity test pins [config].registry to the chain-log subscription address pins (and the test fixture constant) until the #652 cutover moves them together. Closes #651
336789c to
ba5ab94
Compare
|
Adopted The hand-rolled config machinery is gone. The SDK already provides all of it:
Two consequences worth calling out, both deliberate. The refusal fault changed from
The trade this makes: those two tests are nextest-only, because Also dropped the two message-text assertions in favour of asserting the variant and that the message names the key. Pinning the exact string coupled the test to upstream's wording. Verified: 182 tests pass workspace-wide, fmt and clippy clean at AI Assistance: Claude Code used for the SDK adoption and verification. |
What
Sources the ComposableCoW registry address from the twap-monitor manifest
[config]and deletes the compiledcowprotocol::COMPOSABLE_COWconstant from the module, with no fallback of any kind.modules/twap-monitor/src/keeper.rsgainsKeeperConfig { registry: Address }, parsed throughnexum_sdk::config::get_requiredand held in anexum_sdk::config::Slot, with aregistryfield threaded throughTwapSourceintopoll_one'seth_call_params.modules/twap-monitor/src/lib.rsparses and stores ininit, so a parse failure is the init error.on_blockreads the slot and delegates topoll_block, which takes the registry explicitly; beforeinitit is a typedFault::Internalrefusal, which is the SDK's classification forConfigError::NotInitialized.modules/twap-monitor/component.tomlgains[config]withregistry = "0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74", the current Sepolia registry, so behaviour is unchanged.Why
Closes #651: the converged ccow-monitor knows exactly one contract, the registry, and hard-coding the constant coupled the module to a single network and put a cow-rs rev on the critical path.
This is the first car of the convergence train and changes the mechanism only; the address cutover to the mainnet fork is #652's atomic swap.
That cutover is why the car matters more than its diff suggests: the fork registry is at
0xf9ba6F64c9b41Df1cEe76A50e2039D3847064232, a different address from the constant, so until the address is config-sourced, pointing at the fork means editing a constant in nullislabs/cow-rs and doing a cross-repo rev bump to move an address.After this it is a one-line manifest edit.
A parity test pins
[config].registryto every event triggeraddressand to the test fixture constant, so the #652 swap must move all three together.It is kept separate from
module_manifests.rsbecause the two guard different failures: this one is an internal-consistency invariant, that three places agree; that one is an external-fact invariant, that the address is a specific known deployment and itsstart_blockbelongs to it.Notes for review
Two deliberate behaviour changes came with adopting the SDK rather than hand-rolling.
The uninitialised-dispatch refusal is
Fault::Internal, notFault::Unavailable.config.rsstates the rationale:NotInitializedmeansinitreturnedOkwithout storing, a guest bug that never recovers, so it is not a transient unavailability.Slotis write-once, so a test cannot clear it.Rather than keep a mutable static to suit the tests, tests call
poll_blockwith an explicit registry and never touch the static; only two tests touchCONFIG, and nextest gives each its own process.The cost is that those two are nextest-only, where an earlier revision of this PR was runner-independent under
cargo test --lib.just testis nextest and the onlycargo testthe repo asks for is--doc, so this matches how the repo runs, but it is a real narrowing and worth a reviewer's opinion.Testing
Rebased onto
mainafter #675 landed the nexum-runtime migration, so the manifest iscomponent.toml, triggers are[[trigger]] on = "event", and the Watch vocabulary is Commitment throughout.just build-modules: green.cargo nextest run --workspace --all-features: 182 passed, 1 skipped.cargo nextest run -p twap-monitor: 36 passed.cargo fmt --all --checkandcargo clippy --workspace --all-targets --all-features -- -D warnings: clean.AI Assistance: Claude Fable used for the original implementation via a structured workflow; Claude Opus used for the red-team review (9 findings, 7 fixed, 1 duplicate-merged, 1 rejected as out-of-scope checksum policy); Claude Code used for the post-migration rebase and the
nexum_sdk::configadoption.