feat(ethflow-watcher): workspace + skeleton (BLEU-831)#8
Open
brunota20 wants to merge 1 commit into
Open
Conversation
Mirror of the twap-monitor skeleton (BLEU-825) for the EthFlow path. Adds modules/ethflow-watcher/ as a workspace member, with [lib] crate-type = ["cdylib"] for WASM Component output, and the same dep set (cowprotocol no-default-features, alloy-primitives, alloy-sol-types, wit-bindgen) pre-pulled so BLEU-832 (event decode) and BLEU-833 (EIP-1271 submit + retry) can layer in without churning Cargo.toml. src/lib.rs binds against shepherd:cow/shepherd, init logs once, on_event logs Event::Logs as a placeholder until BLEU-832 decodes the CoWSwapEthFlow OrderPlacement payload. cargo build --target wasm32-wasip2 --release -p ethflow-watcher emits a 67 KB .wasm (within ~3 KB of twap-monitor's skeleton — identical world + deps, identical link footprint). Engine load is gated on module.toml (BLEU-834).
This was referenced Jun 15, 2026
brunota20
added a commit
that referenced
this pull request
Jun 15, 2026
- Cargo.toml: clarify in comment that cowprotocol = "1.0.0-alpha" is the cowdao-grants/cow-rs crate (homepage / repository fields on crates.io point there) and cross-reference ADR-0004. Bump alloy declarations (provider / rpc-client / transport[-ws]) from 1.5 to 1.8 (latest 1.x at 1.8.3); 2.x is held off because alloy-provider@2 pulls alloy-signer@2 while cowprotocol still pins alloy-signer@1.8.3 — they'd collide via cargo-deny's multiple-versions check. alloy-primitives stays at 1.6 (its own release cadence; 1.6.0 is max stable today). - host/error.rs: drop the hand-rolled write!-loop hex encoder for alloy_primitives::hex::encode. alloy is already in the dep graph via the chain backend, so this is a net code-loss with no extra link cost. - host/provider_pool.rs: gate ProviderPool::empty() behind #[cfg(test)]. It is only referenced from the inline test module, so the non-test build now does not link an unused constructor. - manifest/error.rs: convert to thiserror::Error derives. ParseError becomes a clean enum with #[from] impls for std::io::Error / toml::de::Error, and UnknownCapability switches to a struct variant with a `name` field. Display strings preserved. manifest/load.rs adopts the `?` conversion now that From is in scope.
brunota20
added a commit
that referenced
this pull request
Jun 15, 2026
Two structural changes that share the HostState / main.rs hot path,
landed together to avoid an inconsistent intermediate revision.
## ModuleStore: cached prefix per module (review on local_store_redb.rs)
Per mfw78's main concern, the namespace prefix is no longer
recomputed on every get / set / delete / list-keys call. Introduces
`ModuleStore`: a per-module handle carrying the pre-computed
`[u8; 32]` keccak prefix plus an `Arc<Database>` ref. Hashing
happens once, in `LocalStore::module(name)`.
let store: LocalStore = LocalStore::open(path)?;
let twap: ModuleStore = store.module("twap-monitor")?; // hash once
twap.set("watch:...", &bytes)?; // concat-only
twap.list_keys("watch:")?; // concat-only
HostState now carries `store: ModuleStore` directly; the previous
`(LocalStore, module_namespace: String)` pair collapsed to just the
`ModuleStore`. The `module_namespace` field stays on HostState
purely for log tagging (the host's `logging::log` impl tags every
line with it) — the namespace identity is encoded in `ModuleStore`'s
prefix.
Tests adapt: the suite previously called `store.set("ns", "k",
"v")`; it now calls `store.module("ns")?.set("k", "v")`. Added a
new test (`module_handles_share_underlying_data`) confirming
cloning a `ModuleStore` is an Arc bump, not a fresh DB view.
## Fuel + memory limits (review on engine_config.rs + engine.example.toml)
Per mfw78's gas-metering concern, surfaces the wasmtime budget on
`engine.toml` so the operator can cap a runaway module. Both knobs
are `Option<u64>` with built-in defaults (1B fuel, 64 MiB memory) —
operators only write the keys they want to override.
[engine.limits]
fuel_per_event = 1_000_000_000
memory_bytes = 67_108_864
main.rs wires the budget into wasmtime:
config.consume_fuel(true);
let limits = StoreLimitsBuilder::new().memory_size(cap).build();
store.limiter(|s| &mut s.limits);
store.set_fuel(limits_cfg.fuel())?; // initial seed
// ... init ...
store.set_fuel(limits_cfg.fuel())?; // refuel for on_event
HostState gains a `limits: StoreLimits` field. `ModuleLimits` lives
in engine_config.rs with `fuel()` / `memory()` accessors that
resolve the override against the defaults. Smoke test logs the
applied budget:
applied module resource limits fuel=1000000000 memory_bytes=67108864
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.
Summary
Mirror of the `twap-monitor` skeleton (BLEU-825) for the EthFlow path:
Independent of the twap-monitor stack — branches from `dev/m2-base` directly.
Linear: BLEU-831.
Test plan