modules: re-point twap-monitor onto pool submit via the cow adapter#469
modules: re-point twap-monitor onto pool submit via the cow adapter#469mfw78 wants to merge 2 commits into
Conversation
The module flips from the shepherd:cow world onto #[videre_sdk::keeper]: the manifest declares the client capability and body version 1, the keeper run submits through the typed CowClient over the module's own videre:venue/client import, and the direct cow-api import and legacy cow client bridge drop out. Status transitions the registry polls back arrive on a cow intent-status subscription. Behaviour identity is proven at the VenueTransport seam: the dispatch tests script submit outcomes against the mock host and assert the same journal, gate, and retry effects as the legacy bridge, including the throttle hint surviving as an epoch backoff and the appData digest riding the body verbatim. The bundle boot proof moves to the videre platform suite (twap against the installed cow adapter); the cow-api boot-order invariant re-pins on ethflow-watcher. Engine configs that boot twap install the bundled adapter.
The adapter fixes its orderbook at init from its manifest chain, so a Sepolia run wired to the mainnet manifest submits to the wrong orderbook. Add per-chain manifest variants (sepolia, load-mock) and point every twap-wired engine config at the one matching the chain it indexes.
lgahdl
left a comment
There was a problem hiding this comment.
Solid module migration — verified all seven touched engine configs correctly pair the Sepolia cow-venue manifest with twap-monitor (whose chain is pinned in its own module.toml, not derived from the engine's [chains.*] block, so no mismatch there), the dispatch tests genuinely substantiate the claimed behavior-identity coverage (journal short-circuit, gates, retry classification, throttle-hint backoff, appData digest — all checked against real assertions, not just renamed), the new intent-status subscription is purely additive with no duplicate polling, and every cow-api/CowApiHost reference is either removed or correctly scoped to ethflow-watcher (intentionally still on the legacy path). Two things worth a look:
| let config = EngineConfig { | ||
| adapters: vec![AdapterEntry { | ||
| path: adapter_wasm, | ||
| manifest: Some(workspace_path("crates/cow-venue/module.toml")), |
There was a problem hiding this comment.
This new e2e test — the one meant to prove the keeper+adapter pairing end-to-end — wires twap-monitor (Sepolia-pinned, chain_id = 11155111) against module.toml, the mainnet-default manifest, not module.sepolia.toml. It passes today only because the dispatched block hits the chainless-poll fault path with no watches indexed, so no submission ever happens. If a future change causes this exact test wiring to attempt a real submit, it would silently target the wrong chain's orderbook and this test wouldn't catch it — the manifest-matching invariant this whole PR is built around is untested here. Worth pointing this test at module.sepolia.toml.
lgahdl
left a comment
There was a problem hiding this comment.
One more thing worth flagging, on the architecture side rather than this diff's own code: CowVenue::ID is a fixed VenueId::from_static("cow") (pre-existing, unchanged here), and the adapter fixes its orderbook chain at init with no chain parameter on any VenueAdapter method. Combined, that means two adapter instances installed simultaneously (e.g. mainnet + Sepolia in one engine process) would register under the same venue id with nothing to disambiguate them at the pool router. Today's per-chain-manifest approach works because each deployment only ever installs one chain's adapter, but that's a real single-process-multi-chain limitation this PR's manifests are compensating for, not just a configuration convenience — and it isn't documented anywhere as a known constraint (the manifest/Dockerfile comments read as a factual description, not a flagged limitation). Worth a one-line ADR/doc note naming single-process-multi-chain as an explicit non-goal for M4, or a chain-qualified venue-id scheme now while the surface is still small, before a second chain's adapter needs to coexist with the first in one process.
What
Re-points
twap-monitorfrom the legacyshepherd:cow/CowApiHostworld onto pool submit and status through the cow venue adapter: addsvidere_sdk::keeperwiring (typedCowClient, body version 1), drops the directcow-apiimport and theshepherd-sdkcow client dependency, and subscribes tointent-statusfor submitted-order polling. Per-chain adapter manifests (sepolia, load-mock) are added and every twap-wired engine config is pointed at the manifest matching the chain it indexes, since the adapter fixes its orderbook from the manifest chain at init.Why
Wave I of #138: twap's chassis port (#147) landed on the legacy CowApiHost seam; this is the second half, re-pointing it onto the generic pool seam per M4.
Testing
Dispatch tests assert behaviour identity against the legacy bridge at the VenueTransport seam (journal, gate, retry effects, throttle-hint backoff, appData digest). Bundle boot proof moves to the videre-host platform suite (twap against the installed cow adapter); the cow-api boot-order invariant re-pins on ethflow-watcher.
AI Assistance
Implemented with Claude Code assistance; human-reviewed.
Closes #327