docs: multi-chain deployment patterns — Mainnet/Gnosis/Arbitrum/Base#310
Closed
lgahdl wants to merge 9 commits into
Closed
docs: multi-chain deployment patterns — Mainnet/Gnosis/Arbitrum/Base#310lgahdl wants to merge 9 commits into
lgahdl wants to merge 9 commits into
Conversation
Collaborator
|
Following up on the Wonder if this line could mislead operators who only have an HTTP endpoint available. Maybe it could be reworded to something like "WebSocket gives lower-latency streaming, but HTTP works for both block and log subscriptions via polling." |
jean-neiverth
approved these changes
Jul 10, 2026
eed7c47 to
fb475c0
Compare
b8aeb1c to
d94a4bd
Compare
daeac17 to
c3c9027
Compare
b4734ce to
e15aa66
Compare
3ed77e2 to
e718f06
Compare
4c508ec to
6f83ed6
Compare
e718f06 to
6b9dc81
Compare
Introduce the world-neutral half of the poll loop in nexum_sdk::keeper: a ConditionalSource trait (one watch in, one outcome out, generic over the host, no venue-transport pre-abstraction), a Tick carrying the dispatch instant, and the RetryAction (try-next-block / backoff / drop) whose effects the Retrier runs through the gate and watch-set stores. RetryAction moves out of shepherd-sdk; the CoW crate re-exports it so no module rewires. shepherd-sdk keeps classify_api_error as the CoW errorType table but returns the keeper action, and encodes two fixes in the one classification path: classify_poll_error maps an unrecognised revert selector with a structured payload to DontTryAgain instead of re-polling every block forever, and DuplicatedOrder (both spellings) classifies as already-submitted - the run records the submitted: receipt and keeps the watch rather than dropping every future tranche. classify_submit_error widens the table to the whole CowApiError surface and gives Backoff its producer: a rate-limit fault with server guidance gates the watch on the epoch clock. cow::run composes the loop: watch-set scan -> gate check -> source poll -> PollOutcome dispatch, driving submission through the existing CowApiHost seam with the journal as the idempotency guard and the retry ledger as the failure dispatch. Acceptance tests run against the composed shepherd-sdk-test MockHost as integration tests; no module is rewired yet.
RpcError.data is now Bytes; the test helper takes raw Vec<u8> and wraps it (Vec -> Bytes is O(1)).
The run logged through the LoggingHost seam, which the guest tracing capture cannot observe - module tests proving behaviour identity for keeper ports assert on tracing events. Route the submit-path diagnostics through the tracing macros with the wording the legacy twap poll loop established, and give ConditionalSource a defaulted label so shared log lines attribute the strategy that produced them.
Reduce strategy.rs to decode and evaluate: log decoding persists watches through the keeper watch set, and the getTradeableOrderWithSignature evaluation moves behind ConditionalSource. The hand-rolled gate keys, watch-update lifecycle, submitted: markers, and submit-retry dispatch are deleted in favour of cow::run over the keeper stores and retry ledger, still on the legacy CowApiHost seam. The MockHost dispatch tests are untouched - the behaviour-identity proof for the port.
Rework MockLocalStore to mirror the runtime store's shape: namespaced views over one shared row map, so identical key strings in sibling namespaces never collide, plus store-wide entry and byte limits that span namespaces the way one database file does. Fault injection stays per-view.
Script per-call venue behaviour where MockCowApi replays one response: a strictly-draining queue of submit outcomes with a configurable steady-state fallback, per-route response sequences whose final entry sticks (a terminal order status persists across re-polls), and venue fault injection that overrides both without consuming them. MockHost grows a defaulted venue type parameter so the composed host carries either mock on the same CowApiHost seam. Acceptance tests drive the keeper run across multi-tick retry, backoff, and outage scenarios, and module-shaped strategy code against status sequences.
…124) New docs/deployment/multi-chain.md covering the verbatim M5 grant deliverable: per-chain [chains.<id>] + env-var wiring, CoW orderbook URL slugs per network, per-chain contract addresses (CREATE2-stable vs EthFlow per-network caveat), the [[subscription]] duplication pattern with twap-monitor and ethflow-watcher examples, event topic reference, and resource sizing guidance. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TfSsJPYDQ1GQGbnSVFxATx
…ents Review catches: - The EthFlow section claimed the address is per-network and told operators to hunt for a different mainnet address. The current production deployment is address-identical on every supported chain (cowprotocol's ETH_FLOW_PRODUCTION, from networks.prod.json) - the old text would have steered a mainnet port toward the legacy v1.0.0 deployment and missed every OrderPlacement event. The real caveat is narrower and now stated as such: sameness is not a CREATE2 guarantee, legacy per-version deployments exist, verify on version bumps. - "every chain the orderbook supports" was false (the Chain enum also carries BNB, Polygon, Avalanche, Linea, Plasma); the table is scoped to the chains this repo's modules target. - Dropped the unsupported "Gnosis volume roughly equal to Mainnet" claim; require_ws violations are an ERROR log, not a warning; the RPC recommendation names a rate requirement instead of a specific provider's free tier. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01TfSsJPYDQ1GQGbnSVFxATx
6b9dc81 to
255c4aa
Compare
02e6276 to
6076837
Compare
Contributor
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Adds
docs/deployment/multi-chain.md, a guide for running Shepherd against multiple EVM chains at once. It covers the chain support matrix (Mainnet, Gnosis, Base, Arbitrum One, Sepolia) with chain IDs, orderbook slugs and barn availability, the[chains.<id>]wiring pattern inengine.tomlincluding${VAR}substitution and therequire_ws = falseopt-out for poll-only chains, the CoW API orderbook URL resolution and override pattern, the CREATE2-stable contract addresses versus the EthFlow per-network caveat (with a pointer tocowprotocol/ethflowcontractnetworks.prod.json), the[[subscription]]duplication pattern with annotatedtwap-monitorandethflow-watcherexamples spanning two chains each, an event topic-0 reference table, and per-chain resource sizing guidance.Why
Shepherd's engine already dispatches modules per chain, but there was no reference for how to configure and reason about a multi-chain deployment. This is the M5 grant deliverable that documents the pattern so operators can wire additional chains without reverse-engineering the module manifests.
Testing
Documentation only, no code changes. All contract addresses, orderbook slugs and barn eligibility are derived directly from
cowprotocol-primitives-0.1.0(already a workspace dependency) and the existingmodule.tomlmanifests rather than manual lookup.