From dc1c4566b26a3165c6a773e662c903343dca1f74 Mon Sep 17 00:00:00 2001 From: mfw78 Date: Fri, 24 Jul 2026 07:27:48 +0000 Subject: [PATCH] keeper: rename sweep to run, ConditionalSource to Poller --- crates/composable-cow/Cargo.toml | 10 +- crates/composable-cow/src/lib.rs | 12 +- .../composable-cow/src/{sweep.rs => run.rs} | 18 +- .../composable-cow/tests/{sweep.rs => run.rs} | 14 +- crates/cow-venue/src/client.rs | 6 +- crates/nexum-sdk/src/keeper.rs | 8 +- crates/nexum-sdk/src/lib.rs | 4 +- crates/nexum-sdk/tests/keeper.rs | 8 +- crates/videre-host/tests/platform.rs | 2 +- crates/videre-sdk/Cargo.toml | 6 +- crates/videre-sdk/src/keeper.rs | 159 +++++++++--------- crates/videre-sdk/src/lib.rs | 10 +- docs/00-overview.md | 4 +- docs/05-sdk-design.md | 18 +- docs/08-platform-generalisation.md | 4 +- docs/sdk.md | 2 +- modules/twap-monitor/Cargo.toml | 2 +- modules/twap-monitor/src/strategy.rs | 8 +- 18 files changed, 146 insertions(+), 149 deletions(-) rename crates/composable-cow/src/{sweep.rs => run.rs} (93%) rename crates/composable-cow/tests/{sweep.rs => run.rs} (98%) diff --git a/crates/composable-cow/Cargo.toml b/crates/composable-cow/Cargo.toml index e785b2cb..6d7c29e5 100644 --- a/crates/composable-cow/Cargo.toml +++ b/crates/composable-cow/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition.workspace = true license.workspace = true repository.workspace = true -description = "ComposableCoW keeper machinery: the conditional-order body, the structured poll Verdict with the deployed 1.x revert decoding quarantined behind LegacyRevertAdapter, and the sweep composition over the venue client." +description = "ComposableCoW keeper machinery: the conditional-order body, the structured poll Verdict with the deployed 1.x revert decoding quarantined behind LegacyRevertAdapter, and the run composition over the venue client." [lib] # Plain library, keeper-side only. The CoW venue crate is orderbook-only @@ -21,7 +21,7 @@ alloy-sol-types.workspace = true borsh.workspace = true cowprotocol = { version = "0.2.0", default-features = false } nexum-sdk = { path = "../nexum-sdk" } -# `sweep` slice: the keeper run over the typed CoW client on the +# `run` slice: the keeper run over the typed CoW client on the # `videre:venue/client` seam. cow-venue = { path = "../cow-venue", features = ["client", "assembly"], optional = true } videre-sdk = { path = "../videre-sdk", optional = true } @@ -30,12 +30,12 @@ tracing = { workspace = true, optional = true } [features] # The poll-loop composition conditional-commitment keepers share: # gate/journal discipline, pool submission, and retry dispatch. -sweep = ["dep:cow-venue", "dep:videre-sdk", "dep:tracing"] +run = ["dep:cow-venue", "dep:videre-sdk", "dep:tracing"] [dev-dependencies] proptest.workspace = true nexum-sdk-test = { path = "../nexum-sdk-test" } [[test]] -name = "sweep" -required-features = ["sweep"] +name = "run" +required-features = ["run"] diff --git a/crates/composable-cow/src/lib.rs b/crates/composable-cow/src/lib.rs index d4dc3680..d0eb35bb 100644 --- a/crates/composable-cow/src/lib.rs +++ b/crates/composable-cow/src/lib.rs @@ -3,18 +3,18 @@ //! ComposableCoW keeper machinery, kept out of the CoW venue: the //! conditional-order body ([`ComposableBody`]) and the structured poll //! seam ([`Verdict`]), with the deployed 1.x reverting wire quarantined -//! behind [`LegacyRevertAdapter`]. The `sweep` slice adds the shared -//! poll-loop composition ([`run`]) over the typed CoW venue client. +//! behind [`LegacyRevertAdapter`]. The `run` slice adds the shared +//! poll-loop composition ([`run`](run::run)) over the typed CoW venue client. #![cfg_attr(not(test), warn(unused_crate_dependencies))] #![warn(missing_docs)] pub mod body; pub mod poll; -#[cfg(feature = "sweep")] -pub mod sweep; +#[cfg(feature = "run")] +pub mod run; pub use body::ComposableBody; pub use poll::{IConditionalOrder, LegacyRevertAdapter, Verdict}; -#[cfg(feature = "sweep")] -pub use sweep::run; +#[cfg(feature = "run")] +pub use run::run; diff --git a/crates/composable-cow/src/sweep.rs b/crates/composable-cow/src/run.rs similarity index 93% rename from crates/composable-cow/src/sweep.rs rename to crates/composable-cow/src/run.rs index 01e0a702..a3ee56f2 100644 --- a/crates/composable-cow/src/sweep.rs +++ b/crates/composable-cow/src/run.rs @@ -1,8 +1,8 @@ -//! Keeper sweep: the poll-loop composition conditional- +//! Keeper run: the poll-loop composition conditional- //! commitment modules share. //! //! [`run`] walks the keeper watch set, polls each gate-ready -//! watch through a [`ConditionalSource`], and runs the +//! watch through a [`Poller`], and runs the //! [`Verdict`]'s effect: lifecycle outcomes update the gate and //! watch stores, `Post` drives one submission through the typed //! [`CowClient`] onto the `videre:venue/client` seam with the @@ -10,14 +10,14 @@ //! venue-and-body [`intent_id`] - and the keeper [`Retrier`] //! as the failure dispatch. //! -//! Store faults abort the sweep (the next tick replays it); +//! Store faults abort the run (the next tick replays it); //! submission failures never do - they fold into a //! [`RetryAction`] through the videre //! [`retry_action`] table, a `denied` refusal re-entering the CoW //! classification through its errorType prefix //! ([`classify_denied`]) so a one-shot row survives the coarse //! collapse, the ledger applies the effect, and the -//! sweep moves on. Diagnostics go through the guest `tracing` facade - +//! run moves on. Diagnostics go through the guest `tracing` facade - //! the same channel strategy code logs on - so module tests observe //! the composed behaviour with one capture. @@ -26,9 +26,7 @@ use cow_venue::assembly::{gpv2_to_order_data, order_data_to_body}; use cow_venue::{CowClient, CowIntent, CowIntentBody, SignedOrder, classify_denied, intent_id}; use cowprotocol::GPv2OrderData; use nexum_sdk::host::{Fault, LocalStoreHost}; -use nexum_sdk::keeper::{ - ConditionalSource, Gates, Journal, Retrier, RetryAction, Tick, WatchRef, WatchSet, -}; +use nexum_sdk::keeper::{Gates, Journal, Poller, Retrier, RetryAction, Tick, WatchRef, WatchSet}; use std::task::Poll; use videre_sdk::client::poll_once; @@ -43,7 +41,7 @@ use crate::Verdict; pub fn run(host: &H, venue: &CowClient, source: &S, tick: &Tick) -> Result<(), Fault> where H: LocalStoreHost, - S: ConditionalSource, + S: Poller, T: VenueTransport, { let watches = WatchSet::new(host); @@ -155,7 +153,7 @@ where tracing::error!("submitted {intent_id} but refusal-marker clear failed: {fault}"); } // The submit already succeeded; a journal-store fault here - // must not abort the sweep or unwind the accepted order. + // must not abort the run or unwind the accepted order. // Log and carry on - the already-submitted arm keeps the // next tick's re-post idempotent. if let Err(fault) = journal.record(&intent_id) { @@ -167,7 +165,7 @@ where ); } Ok(SubmitOutcome::RequiresSigning(_)) => { - // A sweep cannot sign; nothing is journalled, so the next + // A run cannot sign; nothing is journalled, so the next // tick surfaces the same ask afresh. tracing::warn!("{label} submit for {owner:#x} requires signing; not journalled"); } diff --git a/crates/composable-cow/tests/sweep.rs b/crates/composable-cow/tests/run.rs similarity index 98% rename from crates/composable-cow/tests/sweep.rs rename to crates/composable-cow/tests/run.rs index 567a1384..a466e14b 100644 --- a/crates/composable-cow/tests/sweep.rs +++ b/crates/composable-cow/tests/run.rs @@ -1,4 +1,4 @@ -//! Sweep acceptance tests: `run` over the generic store mocks with a +//! Run acceptance tests: `run` over the generic store mocks with a //! scripted venue transport on the `videre:venue/client` seam. use std::cell::{Cell, RefCell}; @@ -10,7 +10,7 @@ use cow_venue::assembly::{gpv2_to_order_data, order_data_to_body}; use cow_venue::{CowClient, CowIntent, CowIntentBody, CowVenue, SignedOrder}; use cowprotocol::{BuyTokenDestination, GPv2OrderData, OrderKind, SellTokenSource}; use nexum_sdk::host::LocalStoreHost as _; -use nexum_sdk::keeper::{ConditionalSource, Gates, Journal, Tick, WatchRef, WatchSet}; +use nexum_sdk::keeper::{Gates, Journal, Poller, Tick, WatchRef, WatchSet}; use nexum_sdk_test::{MockHost, capture_tracing}; use videre_sdk::client::sealed::SealedTransport; use videre_sdk::keeper::submission_key; @@ -22,7 +22,7 @@ use videre_sdk::{ const SEPOLIA: u64 = 11_155_111; /// Scripted venue transport: one submit outcome per queued entry, -/// every submit recorded. Quote, status, and cancel are off the sweep +/// every submit recorded. Quote, status, and cancel are off the run /// path. #[derive(Default)] struct MockVenue { @@ -77,7 +77,7 @@ fn client(venue: &MockVenue) -> CowClient<&MockVenue> { /// observes its own poll calls. struct FnSource(F); -impl ConditionalSource for FnSource +impl Poller for FnSource where F: Fn(&H, WatchRef<'_>, &[u8], &Tick) -> Verdict, { @@ -144,7 +144,7 @@ fn seed_watch(host: &MockHost) -> String { .unwrap() } -/// The encoded intent body the sweep submits for `order`. +/// The encoded intent body the run submits for `order`. fn intent_bytes(order: &GPv2OrderData) -> Vec { let order_data = gpv2_to_order_data(order).expect("known markers"); CowIntentBody::V1(CowIntent::Signed(SignedOrder { @@ -156,7 +156,7 @@ fn intent_bytes(order: &GPv2OrderData) -> Vec { .expect("body encodes") } -/// The intent-id the sweep journals for `order`: the venue-and-body +/// The intent-id the run journals for `order`: the venue-and-body /// key over the same signed body `run` derives pre-submit. fn intent_id(order: &GPv2OrderData) -> String { submission_key(&CowVenue::ID, &intent_bytes(order)) @@ -406,7 +406,7 @@ fn ready_with_unknown_marker_skips_submit_and_keeps_the_watch() { assert!(host.store.snapshot().contains_key(&key)); } -/// A sweep cannot sign: a `requires-signing` outcome is surfaced, not +/// A run cannot sign: a `requires-signing` outcome is surfaced, not /// journalled, so the next tick re-poses the same ask. #[test] fn requires_signing_is_surfaced_and_not_journalled() { diff --git a/crates/cow-venue/src/client.rs b/crates/cow-venue/src/client.rs index aa035281..e61e5b65 100644 --- a/crates/cow-venue/src/client.rs +++ b/crates/cow-venue/src/client.rs @@ -30,10 +30,10 @@ impl Venue for CowVenue {} /// or submit a foreign body. pub type CowClient = VenueClient; -/// Deterministic intent-id for `body`: the sweep's +/// Deterministic intent-id for `body`: the run's /// [`submission_key`] bound to [`CowVenue::ID`]. Derivable before any /// network work, so a keeper journals the same key whether it submits -/// through the sweep or directly. +/// through the run or directly. /// /// The key covers the encoded body, so a signed payload /// ([`CowIntent::Signed`](crate::CowIntent::Signed)) keys on its @@ -121,7 +121,7 @@ mod tests { assert_eq!( id, submission_key(&CowVenue::ID, &body.to_bytes().expect("body encodes")), - "the id must be exactly the key the generic sweep journals", + "the id must be exactly the key the generic run journals", ); assert!(id.starts_with("cow:0x")); diff --git a/crates/nexum-sdk/src/keeper.rs b/crates/nexum-sdk/src/keeper.rs index 726bdae4..115b9725 100644 --- a/crates/nexum-sdk/src/keeper.rs +++ b/crates/nexum-sdk/src/keeper.rs @@ -20,7 +20,7 @@ //! //! Two pieces drive the stores from the poll loop: //! -//! - [`ConditionalSource`] - the world-neutral poll seam: one watch in, +//! - [`Poller`] - the world-neutral poll seam: one watch in, //! one outcome out, at a given [`Tick`]. Implementations own the //! transport and the outcome shape. //! - [`Retrier`] - runs a [`RetryAction`]'s effect through the @@ -348,8 +348,8 @@ pub struct Tick { /// owns its own wire (an `eth_call`, an HTTP probe, a stub). /// /// A transient failure should surface as a retry-flavoured outcome, -/// not tear down the caller's sweep: `poll` is infallible by contract. -pub trait ConditionalSource { +/// not tear down the caller's run: `poll` is infallible by contract. +pub trait Poller { /// What one poll produces. type Outcome; @@ -362,7 +362,7 @@ pub trait ConditionalSource { /// (for example `"twap"`). Diagnostic only - no behaviour keys /// off it. fn label(&self) -> &'static str { - "conditional" + "poller" } } diff --git a/crates/nexum-sdk/src/lib.rs b/crates/nexum-sdk/src/lib.rs index 201aa1fd..9961cc24 100644 --- a/crates/nexum-sdk/src/lib.rs +++ b/crates/nexum-sdk/src/lib.rs @@ -37,7 +37,7 @@ //! - [`keeper`] - strategy-keeper stores over [`LocalStoreHost`]: //! the watch-set registry ([`WatchSet`]), block/epoch gate keys //! ([`Gates`]) and the receipt-keyed idempotency journal -//! ([`Journal`]); plus the [`ConditionalSource`] poll seam and the +//! ([`Journal`]); plus the [`Poller`] poll seam and the //! [`Retrier`] dispatching a [`RetryAction`] through the stores. //! //! - [`chain`] - typed chain access: alloy [`Chain`], @@ -94,7 +94,7 @@ //! [`WatchSet`]: keeper::WatchSet //! [`Gates`]: keeper::Gates //! [`Journal`]: keeper::Journal -//! [`ConditionalSource`]: keeper::ConditionalSource +//! [`Poller`]: keeper::Poller //! [`Retrier`]: keeper::Retrier //! [`RetryAction`]: keeper::RetryAction //! [`Chain`]: alloy_chains::Chain diff --git a/crates/nexum-sdk/tests/keeper.rs b/crates/nexum-sdk/tests/keeper.rs index f73c9adf..c2e2ea9f 100644 --- a/crates/nexum-sdk/tests/keeper.rs +++ b/crates/nexum-sdk/tests/keeper.rs @@ -8,8 +8,8 @@ use alloy_primitives::{Address, B256, address, b256}; use nexum_sdk::host::{Fault, LocalStoreHost as _}; use nexum_sdk::keeper::{ - ConditionalSource, Gates, Journal, NEXT_BLOCK_PREFIX, NEXT_EPOCH_PREFIX, REFUSED_PREFIX, - Retrier, RetryAction, Tick, WATCH_PREFIX, WatchRef, WatchSet, watch_key, + Gates, Journal, NEXT_BLOCK_PREFIX, NEXT_EPOCH_PREFIX, Poller, REFUSED_PREFIX, Retrier, + RetryAction, Tick, WATCH_PREFIX, WatchRef, WatchSet, watch_key, }; use nexum_sdk_test::MockHost; @@ -559,9 +559,9 @@ fn retry_action_labels_are_stable_snake_case() { /// keeper passes the stored params verbatim and the tick it judged /// the gates by. #[test] -fn conditional_source_sees_params_and_tick_verbatim() { +fn poller_sees_params_and_tick_verbatim() { struct EchoSource; - impl ConditionalSource for EchoSource { + impl Poller for EchoSource { type Outcome = (usize, u64, u64, u64, String); fn poll( &self, diff --git a/crates/videre-host/tests/platform.rs b/crates/videre-host/tests/platform.rs index 3011ee60..2dc39e33 100644 --- a/crates/videre-host/tests/platform.rs +++ b/crates/videre-host/tests/platform.rs @@ -818,7 +818,7 @@ async fn e2e_twap_monitor_boots_against_the_cow_adapter() { assert_eq!(supervisor.alive_count(), 1, "twap-monitor is alive"); // twap-monitor subscribes to Sepolia blocks (poll path); with no - // watches indexed the sweep is empty and the keeper stays alive. + // watches indexed the run is empty and the keeper stays alive. assert_eq!(supervisor.dispatch_block(block(11_155_111)).await, 1); assert_eq!(supervisor.alive_count(), 1); } diff --git a/crates/videre-sdk/Cargo.toml b/crates/videre-sdk/Cargo.toml index 0c87c63b..acc8a57e 100644 --- a/crates/videre-sdk/Cargo.toml +++ b/crates/videre-sdk/Cargo.toml @@ -4,7 +4,7 @@ version = "0.1.0" edition.workspace = true license.workspace = true repository.workspace = true -description = "Guest-side videre SDK: the VenueAdapter trait mirroring the venue-adapter world, the borsh-versioned IntentBody codec, the typed venue client over the native-AFIT transport seam, the generic keeper sweep assembler, and typed wrappers over the scoped transport imports." +description = "Guest-side videre SDK: the VenueAdapter trait mirroring the venue-adapter world, the borsh-versioned IntentBody codec, the typed venue client over the native-AFIT transport seam, the generic keeper run assembler, and typed wrappers over the scoped transport imports." [lib] # Plain library - adapters link this and emit their own cdylib for the @@ -36,10 +36,10 @@ videre-status-body = { path = "../videre-status-body" } http.workspace = true strum.workspace = true thiserror.workspace = true -# Best-effort fault logs on the sweep's non-critical store cleanups. +# Best-effort fault logs on the run's non-critical store cleanups. tracing.workspace = true wit-bindgen.workspace = true [dev-dependencies] -# In-memory `LocalStoreHost` behind the keeper sweep tests. +# In-memory `LocalStoreHost` behind the keeper run tests. nexum-sdk-test = { path = "../nexum-sdk-test" } diff --git a/crates/videre-sdk/src/keeper.rs b/crates/videre-sdk/src/keeper.rs index 6e64fdcd..945b0697 100644 --- a/crates/videre-sdk/src/keeper.rs +++ b/crates/videre-sdk/src/keeper.rs @@ -1,27 +1,25 @@ -//! The generic keeper sweep: one pass assembling the world-neutral -//! stores - [`WatchSet`] to [`Gates`] to [`ConditionalSource::poll`] to +//! The generic keeper run: one pass assembling the world-neutral +//! stores - [`WatchSet`] to [`Gates`] to [`Poller::poll`] to //! [`Retrier`] to [`Journal`] - and routing submissions through the //! [`VenueTransport`] seam. //! -//! [`Sweep`] is the shared poll outcome: the concrete -//! [`ConditionalSource::Outcome`] a keeper's sources produce so -//! [`Keeper::sweep`] can act on every one of them. The world-neutral +//! [`Outcome`] is the shared poll outcome: the concrete +//! [`Poller::Outcome`] a keeper's pollers produce so +//! [`Keeper::run`] can act on every one of them. The world-neutral //! primitives stay in `nexum_sdk::keeper`; this module only assembles //! them. use nexum_sdk::host::{Fault, LocalStoreHost}; -use nexum_sdk::keeper::{ - ConditionalSource, Gates, Journal, Retrier, RetryAction, Tick, WatchRef, WatchSet, -}; +use nexum_sdk::keeper::{Gates, Journal, Poller, Retrier, RetryAction, Tick, WatchRef, WatchSet}; use nexum_sdk::prelude::{hex, keccak256}; use crate::client::{VenueId, VenueTransport}; use crate::{SubmitOutcome, UnsignedTx, VenueFault}; -/// What one poll asks the sweep to do with its watch. +/// What one poll asks the run to do with its watch. #[derive(Clone, Debug, Eq, PartialEq)] #[non_exhaustive] -pub enum Sweep { +pub enum Outcome { /// Submit these encoded intent-body bytes to the bound venue. Submit(Vec), /// Nothing to do yet; the next tick re-polls. @@ -35,7 +33,7 @@ pub enum Sweep { Drop, } -/// A keeper: one conditional source bound to one venue, swept over the +/// A keeper: one poller bound to one venue, run over the /// keeper stores. pub struct Keeper { source: S, @@ -60,8 +58,8 @@ impl Keeper { } impl Keeper { - /// Sweep the watch set once at `tick`: poll every ready watch, - /// submit [`Sweep::Submit`] bodies through the venue seam, and + /// Run the watch set once at `tick`: poll every ready watch, + /// submit [`Outcome::Submit`] bodies through the venue seam, and /// run every other outcome and every venue refusal through the /// [`Retrier`]. The [`submission_key`] is checked against the /// `submitted:` [`Journal`] before every submit and recorded on @@ -69,20 +67,20 @@ impl Keeper { /// best-effort - so a journalled acceptance is never resubmitted. /// The record is not atomic with the submit: an acceptance whose /// journal write faults can still resubmit. A `requires-signing` - /// answer journals nothing and is surfaced afresh each sweep. - /// Store faults abort the sweep, bar the post-acceptance marker + /// answer journals nothing and is surfaced afresh each run. + /// Store faults abort the run, bar the post-acceptance marker /// clear; venue refusals never do - they fold into per-watch /// retry actions. - pub async fn sweep(&self, host: &H, tick: &Tick) -> Result + pub async fn run(&self, host: &H, tick: &Tick) -> Result where H: LocalStoreHost, - S: ConditionalSource, + S: Poller, { let watches = WatchSet::new(host); let gates = Gates::new(host); let retrier = Retrier::new(host); let journal = Journal::submitted(host); - let mut report = SweepReport::default(); + let mut report = RunReport::default(); for key in watches.list()? { let Some(watch) = WatchRef::parse(&key) else { @@ -100,7 +98,7 @@ impl Keeper { report.polled += 1; let action = match self.source.poll(host, watch, ¶ms, tick) { - Sweep::Submit(body) => { + Outcome::Submit(body) => { let key = submission_key(&self.venue, &body); if journal.contains(&key)? { report.duplicates += 1; @@ -111,7 +109,7 @@ impl Keeper { journal.record(&key)?; // The acceptance is journalled; the marker // clear is cleanup and must not abort the - // sweep. + // run. if let Err(fault) = retrier.clear_refusal(watch) { tracing::error!( %fault, @@ -128,9 +126,9 @@ impl Keeper { Err(fault) => retry_action(&fault), } } - Sweep::WaitBlock => RetryAction::TryNextBlock, - Sweep::Backoff { seconds } => RetryAction::Backoff { seconds }, - Sweep::Drop => RetryAction::Drop, + Outcome::WaitBlock => RetryAction::TryNextBlock, + Outcome::Backoff { seconds } => RetryAction::Backoff { seconds }, + Outcome::Drop => RetryAction::Drop, }; match action { RetryAction::Drop => report.dropped += 1, @@ -142,27 +140,27 @@ impl Keeper { } } -/// One sweep's tally, by watch disposition. +/// One run's tally, by watch disposition. #[derive(Clone, Debug, Default, PartialEq)] #[non_exhaustive] -pub struct SweepReport { +pub struct RunReport { /// Watches polled. pub polled: usize, /// Watches skipped by an unexpired gate. pub gated: usize, /// Watches skipped unread: a malformed key, or a row that vanished - /// mid-sweep. + /// mid-run. pub skipped: usize, /// Bodies the venue accepted, submission key newly journalled. pub submitted: usize, - /// Bodies whose key an earlier sweep had journalled, skipped + /// Bodies whose key an earlier run had journalled, skipped /// without a venue call. pub duplicates: usize, /// Watches left in place for a later tick. pub retried: usize, /// Watches dropped. pub dropped: usize, - /// Transactions the venue answered `requires-signing`; a sweep + /// Transactions the venue answered `requires-signing`; a run /// cannot sign, so the caller owns them. pub unsigned: Vec, } @@ -170,8 +168,8 @@ pub struct SweepReport { /// Deterministic pre-submit journal key: the venue id and the /// keccak-256 of the body. The hash is a fixed-length suffix, so the /// key is unambiguous whatever the venue id contains. Public so a -/// keeper journalling outside [`Keeper::sweep`] writes the key the -/// sweep checks. +/// keeper journalling outside [`Keeper::run`] writes the key the +/// run checks. pub fn submission_key(venue: &VenueId, body: &[u8]) -> String { format!("{venue}:{}", hex::encode_prefixed(keccak256(body))) } @@ -179,7 +177,7 @@ pub fn submission_key(venue: &VenueId, body: &[u8]) -> String { /// Fold a venue refusal into the retry action the ledger runs: the /// throttle hint becomes an epoch gate, transient failures retry next /// block, and refusals no retry can cure drop the watch. Public so a -/// keeper sweeping outside [`Keeper::sweep`] folds refusals the same +/// keeper running outside [`Keeper::run`] folds refusals the same /// way. pub fn retry_action(fault: &VenueFault) -> RetryAction { match fault { @@ -209,37 +207,37 @@ mod tests { use nexum_sdk::prelude::{Address, B256, hex, keccak256}; use nexum_sdk_test::MockLocalStore; - use super::{Keeper, Sweep, SweepReport}; + use super::{Keeper, Outcome, RunReport}; use crate::client::{VenueId, VenueTransport}; use crate::{IntentStatus, Quotation, SubmitOutcome, UnsignedTx, VenueFault}; - /// Drive a sweep on the test's synchronous boundary. + /// Drive a run on the test's synchronous boundary. fn run(future: F) -> F::Output { match crate::client::poll_once(future) { std::task::Poll::Ready(output) => output, - std::task::Poll::Pending => panic!("sweep futures complete in one poll"), + std::task::Poll::Pending => panic!("run futures complete in one poll"), } } /// Answers every poll with one programmed outcome. - struct StubSource(Sweep); + struct StubSource(Outcome); - impl nexum_sdk::keeper::ConditionalSource for StubSource { - type Outcome = Sweep; + impl nexum_sdk::keeper::Poller for StubSource { + type Outcome = Outcome; - fn poll(&self, _host: &H, _watch: WatchRef<'_>, _params: &[u8], _tick: &Tick) -> Sweep { + fn poll(&self, _host: &H, _watch: WatchRef<'_>, _params: &[u8], _tick: &Tick) -> Outcome { self.0.clone() } } /// Pops one programmed outcome per poll, from the back. - struct SeqSource(RefCell>); + struct SeqSource(RefCell>); - impl nexum_sdk::keeper::ConditionalSource for SeqSource { - type Outcome = Sweep; + impl nexum_sdk::keeper::Poller for SeqSource { + type Outcome = Outcome; - fn poll(&self, _host: &H, _watch: WatchRef<'_>, _params: &[u8], _tick: &Tick) -> Sweep { - self.0.borrow_mut().pop().unwrap_or(Sweep::WaitBlock) + fn poll(&self, _host: &H, _watch: WatchRef<'_>, _params: &[u8], _tick: &Tick) -> Outcome { + self.0.borrow_mut().pop().unwrap_or(Outcome::WaitBlock) } } @@ -299,7 +297,7 @@ mod tests { .expect("mock store accepts the watch") } - fn keeper(outcome: Sweep, venue: &StubVenue) -> Keeper { + fn keeper(outcome: Outcome, venue: &StubVenue) -> Keeper { Keeper::new(StubSource(outcome), venue, "stub") } @@ -308,9 +306,9 @@ mod tests { let host = MockLocalStore::default(); put_watch(&host); let venue = StubVenue::new(Ok(SubmitOutcome::Accepted(vec![0xA5, 0x5A]))); - let keeper = keeper(Sweep::Submit(b"body".to_vec()), &venue); + let keeper = keeper(Outcome::Submit(b"body".to_vec()), &venue); - let report = run(keeper.sweep(&host, &TICK)).expect("sweep runs"); + let report = run(keeper.run(&host, &TICK)).expect("keeper runs"); assert_eq!(report.polled, 1); assert_eq!(report.submitted, 1); assert_eq!(venue.submitted.borrow().as_slice(), [b"body".to_vec()]); @@ -320,8 +318,8 @@ mod tests { assert!(journal.contains(&key).expect("journal reads")); assert_eq!(WatchSet::new(&host).list().expect("list reads").len(), 1); - // A later sweep re-polls the watch but never re-posts the body. - let report = run(keeper.sweep(&host, &TICK)).expect("sweep runs"); + // A later run re-polls the watch but never re-posts the body. + let report = run(keeper.run(&host, &TICK)).expect("keeper runs"); assert_eq!(report.submitted, 0); assert_eq!(report.duplicates, 1); assert_eq!(venue.submitted.borrow().len(), 1); @@ -336,8 +334,8 @@ mod tests { .expect("marker writes"); let venue = StubVenue::new(Ok(SubmitOutcome::Accepted(vec![1]))); - let report = run(keeper(Sweep::Submit(b"body".to_vec()), &venue).sweep(&host, &TICK)) - .expect("sweep runs"); + let report = run(keeper(Outcome::Submit(b"body".to_vec()), &venue).run(&host, &TICK)) + .expect("keeper runs"); assert_eq!(report.submitted, 1); assert!( host.get(&watch.refused_key()) @@ -354,8 +352,8 @@ mod tests { host.fail_on("refused:", Fault::Unavailable("store down".into())); let venue = StubVenue::new(Ok(SubmitOutcome::Accepted(vec![1]))); - let report = run(keeper(Sweep::Submit(b"body".to_vec()), &venue).sweep(&host, &TICK)) - .expect("marker-clear fault must not abort the sweep"); + let report = run(keeper(Outcome::Submit(b"body".to_vec()), &venue).run(&host, &TICK)) + .expect("marker-clear fault must not abort the run"); assert_eq!(report.submitted, 1); let key = format!("stub:{}", hex::encode_prefixed(keccak256(b"body"))); assert!( @@ -373,20 +371,20 @@ mod tests { let venue = StubVenue::new(Ok(SubmitOutcome::Accepted(vec![1]))); // Polls pop from the back: `one` first, then `two`. let source = SeqSource(RefCell::new(vec![ - Sweep::Submit(b"two".to_vec()), - Sweep::Submit(b"one".to_vec()), + Outcome::Submit(b"two".to_vec()), + Outcome::Submit(b"one".to_vec()), ])); let keeper = Keeper::new(source, &venue, "stub"); assert_eq!( - run(keeper.sweep(&host, &TICK)) - .expect("sweep runs") + run(keeper.run(&host, &TICK)) + .expect("keeper runs") .submitted, 1 ); assert_eq!( - run(keeper.sweep(&host, &TICK)) - .expect("sweep runs") + run(keeper.run(&host, &TICK)) + .expect("keeper runs") .submitted, 1 ); @@ -407,15 +405,15 @@ mod tests { data: vec![0xFE], }; let venue = StubVenue::new(Ok(SubmitOutcome::RequiresSigning(tx.clone()))); - let keeper = keeper(Sweep::Submit(b"body".to_vec()), &venue); + let keeper = keeper(Outcome::Submit(b"body".to_vec()), &venue); - let report = run(keeper.sweep(&host, &TICK)).expect("sweep runs"); + let report = run(keeper.run(&host, &TICK)).expect("keeper runs"); assert_eq!(report.unsigned, vec![tx.clone()]); assert_eq!(report.submitted, 0); - // Nothing accepted, nothing journalled: the next sweep + // Nothing accepted, nothing journalled: the next run // surfaces the same transaction again. - let report = run(keeper.sweep(&host, &TICK)).expect("sweep runs"); + let report = run(keeper.run(&host, &TICK)).expect("keeper runs"); assert_eq!(report.unsigned, vec![tx]); } @@ -429,8 +427,8 @@ mod tests { .expect("gate writes"); let venue = StubVenue::new(Ok(SubmitOutcome::Accepted(vec![1]))); - let report = run(keeper(Sweep::Submit(b"body".to_vec()), &venue).sweep(&host, &TICK)) - .expect("sweep runs"); + let report = run(keeper(Outcome::Submit(b"body".to_vec()), &venue).run(&host, &TICK)) + .expect("keeper runs"); assert_eq!(report.gated, 1); assert_eq!(report.polled, 0); assert!(venue.submitted.borrow().is_empty()); @@ -442,7 +440,7 @@ mod tests { put_watch(&host); let venue = StubVenue::new(Ok(SubmitOutcome::Accepted(vec![1]))); - let report = run(keeper(Sweep::Drop, &venue).sweep(&host, &TICK)).expect("sweep runs"); + let report = run(keeper(Outcome::Drop, &venue).run(&host, &TICK)).expect("keeper runs"); assert_eq!(report.dropped, 1); assert!(WatchSet::new(&host).list().expect("list reads").is_empty()); } @@ -452,13 +450,13 @@ mod tests { let host = MockLocalStore::default(); put_watch(&host); let venue = StubVenue::new(Ok(SubmitOutcome::Accepted(vec![1]))); - let keeper = keeper(Sweep::Backoff { seconds: 30 }, &venue); + let keeper = keeper(Outcome::Backoff { seconds: 30 }, &venue); - let report = run(keeper.sweep(&host, &TICK)).expect("sweep runs"); + let report = run(keeper.run(&host, &TICK)).expect("keeper runs"); assert_eq!(report.retried, 1); // Still inside the backoff window: gated, not polled. - let report = run(keeper.sweep(&host, &TICK)).expect("sweep runs"); + let report = run(keeper.run(&host, &TICK)).expect("keeper runs"); assert_eq!(report.gated, 1); // At the threshold the gate opens again. @@ -466,7 +464,7 @@ mod tests { epoch_s: TICK.epoch_s + 30, ..TICK }; - let report = run(keeper.sweep(&host, &later)).expect("sweep runs"); + let report = run(keeper.run(&host, &later)).expect("keeper runs"); assert_eq!(report.polled, 1); } @@ -477,9 +475,9 @@ mod tests { let venue = StubVenue::new(Err(VenueFault::RateLimited { retry_after_ms: Some(2_500), })); - let keeper = keeper(Sweep::Submit(b"body".to_vec()), &venue); + let keeper = keeper(Outcome::Submit(b"body".to_vec()), &venue); - let report = run(keeper.sweep(&host, &TICK)).expect("sweep runs"); + let report = run(keeper.run(&host, &TICK)).expect("keeper runs"); assert_eq!(report.retried, 1); // 2500 ms rounds up to a 3 s epoch gate. @@ -488,7 +486,7 @@ mod tests { ..TICK }; assert_eq!( - run(keeper.sweep(&host, &at_2s)).expect("sweep runs").gated, + run(keeper.run(&host, &at_2s)).expect("keeper runs").gated, 1 ); let at_3s = Tick { @@ -496,7 +494,7 @@ mod tests { ..TICK }; assert_eq!( - run(keeper.sweep(&host, &at_3s)).expect("sweep runs").polled, + run(keeper.run(&host, &at_3s)).expect("keeper runs").polled, 1 ); } @@ -507,8 +505,8 @@ mod tests { put_watch(&host); let venue = StubVenue::new(Err(VenueFault::Denied("blocked".into()))); - let report = run(keeper(Sweep::Submit(b"body".to_vec()), &venue).sweep(&host, &TICK)) - .expect("sweep runs"); + let report = run(keeper(Outcome::Submit(b"body".to_vec()), &venue).run(&host, &TICK)) + .expect("keeper runs"); assert_eq!(report.dropped, 1); assert!(WatchSet::new(&host).list().expect("list reads").is_empty()); } @@ -518,12 +516,12 @@ mod tests { let host = MockLocalStore::default(); put_watch(&host); let venue = StubVenue::new(Err(VenueFault::Unavailable("down".into()))); - let keeper = keeper(Sweep::Submit(b"body".to_vec()), &venue); + let keeper = keeper(Outcome::Submit(b"body".to_vec()), &venue); - let report = run(keeper.sweep(&host, &TICK)).expect("sweep runs"); + let report = run(keeper.run(&host, &TICK)).expect("keeper runs"); assert_eq!(report.retried, 1); assert_eq!( - run(keeper.sweep(&host, &TICK)).expect("sweep runs").polled, + run(keeper.run(&host, &TICK)).expect("keeper runs").polled, 1 ); } @@ -533,7 +531,8 @@ mod tests { let host = MockLocalStore::default(); let venue = StubVenue::new(Ok(SubmitOutcome::Accepted(vec![1]))); - let report = run(keeper(Sweep::WaitBlock, &venue).sweep(&host, &TICK)).expect("sweep runs"); - assert_eq!(report, SweepReport::default()); + let report = + run(keeper(Outcome::WaitBlock, &venue).run(&host, &TICK)).expect("keeper runs"); + assert_eq!(report, RunReport::default()); } } diff --git a/crates/videre-sdk/src/lib.rs b/crates/videre-sdk/src/lib.rs index 3594f2b5..5bdec44d 100644 --- a/crates/videre-sdk/src/lib.rs +++ b/crates/videre-sdk/src/lib.rs @@ -29,11 +29,11 @@ //! [`poll_once`](client::poll_once) completes their futures on the //! synchronous guest boundary. //! -//! - [`keeper`](mod@keeper) - the generic sweep assembler: -//! [`Keeper::sweep`] runs the world-neutral `nexum_sdk::keeper` +//! - [`keeper`](mod@keeper) - the generic run assembler: +//! [`Keeper::run`] runs the world-neutral `nexum_sdk::keeper` //! stores over a -//! [`ConditionalSource`](nexum_sdk::keeper::ConditionalSource) -//! producing the shared [`Sweep`] outcome, submitting through the +//! [`Poller`](nexum_sdk::keeper::Poller) +//! producing the shared [`Outcome`] outcome, submitting through the //! [`VenueTransport`] seam. //! //! - [`transport`] - typed wrappers over the world's scoped imports: @@ -87,7 +87,7 @@ pub use adapter::VenueAdapter; pub use body::{BodyError, IntentBody}; pub use client::{ClientError, HostVenues, Quoted, Venue, VenueClient, VenueId, VenueTransport}; pub use faults::VenueFault; -pub use keeper::{Keeper, Sweep, SweepReport, retry_action}; +pub use keeper::{Keeper, Outcome, RunReport, retry_action}; /// Derive [`IntentBody`] on the outer per-venue version enum. See /// [`videre_macros::IntentBody`]. pub use videre_macros::IntentBody; diff --git a/docs/00-overview.md b/docs/00-overview.md index c5d0a6e3..768448e1 100755 --- a/docs/00-overview.md +++ b/docs/00-overview.md @@ -270,13 +270,13 @@ The SDK ships as two crate pairs: `nexum-sdk`, the generic module-author SDK (ho | | `Fault` + the `HostFault` trait - the shared failure vocabulary and per-interface typed errors (`ChainError`) with `?` support | | | `chain::{eth_call_params, parse_eth_call_result}` + `chain::chainlink` - JSON-RPC plumbing helpers | | | `config` / `address` - config-table lookups, decimal scaling, address parsing | -| | `keeper::{WatchSet, Gates, Journal, Retrier, ConditionalSource}` - the conditional-commitment strategy keeper: watch registry, poll gates, receipt journal, retry dispatch over the local-store seam | +| | `keeper::{WatchSet, Gates, Journal, Retrier, Poller}` - the conditional-commitment strategy keeper: watch registry, poll gates, receipt journal, retry dispatch over the local-store seam | | | `http::{fetch, Fetch, FetchError, FetchOptions}` - allowlisted outbound HTTP over wasi:http on the standard `http` crate's `Request` / `Response` types | | | `tracing` + `bind_host_via_wit_bindgen!` - guest tracing facade and the per-module adapter macro | | | `prelude::*` - alloy primitives in one import | | `shepherd-sdk` | `cow::{CowApiHost, CowHost}` - the cow-api trait and orderbook host bound | | | `cow::{order, composable, error}` - CoW Protocol bridging (`gpv2_to_order_data`, `Verdict`, `LegacyRevertAdapter`, `RetryAction`, `classify_api_error`) | -| | `cow::run` - the shared poll-loop composition: sweep the keeper watch set, poll a `ConditionalSource`, submit `Ready` orders behind the `submitted:` journal guard and retry ledger | +| | `cow::run` - the shared poll-loop composition: run the keeper watch set, poll a `Poller`, submit `Ready` orders behind the `submitted:` journal guard and retry ledger | | | `bind_cow_host_via_wit_bindgen!` - the CoW layering of the generic adapter macro | | | `prelude::*` - cowprotocol order / signing / orderbook surface in one import | | `nexum-sdk-test` | `MockHost` + per-trait `MockChain` / `MockLocalStore` / `MockLogging` + `capture_tracing` for native-Rust strategy tests | diff --git a/docs/05-sdk-design.md b/docs/05-sdk-design.md index 1512ee47..af944182 100755 --- a/docs/05-sdk-design.md +++ b/docs/05-sdk-design.md @@ -48,7 +48,7 @@ nexum-sdk/ # universal module SDK (host-neutral, domain-free ├── prelude.rs # alloy primitive re-exports (Address, B256, Bytes, U256, keccak256) ├── host.rs # ChainHost / LocalStoreHost / LoggingHost + supertrait Host; Fault, ChainError, RpcError ├── wit_bindgen_macro.rs # bind_host_via_wit_bindgen! - generates WitBindgenHost + converters - ├── keeper.rs # WatchSet, Gates, Journal, ConditionalSource, Retrier + ├── keeper.rs # WatchSet, Gates, Journal, Poller, Retrier ├── chain/ # eth_call_params, parse_eth_call_result, chainlink AggregatorV3 reader ├── events.rs # native alloy Log assembly from the wire ChainLog record ├── config.rs # (key, value) config-table lookups, decimal scaling @@ -64,7 +64,7 @@ videre-sdk/ # venue SDK: both venue sides ├── adapter.rs # VenueAdapter trait (init + the five intent functions) ├── body.rs # IntentBody trait + BodyError (versioned borsh codec) ├── client.rs # Venue, VenueId, VenueClient, VenueTransport, HostVenues - ├── keeper.rs # Keeper::sweep - the generic sweep assembler; Sweep, SweepReport + ├── keeper.rs # Keeper::run - the generic run assembler; Outcome, RunReport ├── transport.rs # HostChain, HostMessaging, http, BoundedFetch ├── faults.rs # VenueFault + conversions across wire fault / SDK fault / VenueError ├── rt.rs # completes async keeper handlers on the sync guest boundary @@ -76,7 +76,7 @@ videre-test/ # venue conformance kit └── src/ # CodecVectors, HeaderGoldens, MockTransport, reference venue cow-venue/ # the CoW venue, as feature slices -composable-cow/ # ComposableCoW keeper machinery (body, poll seam, sweep) +composable-cow/ # ComposableCoW keeper machinery (body, poll seam, run) ``` `nexum-sdk` is host-neutral and domain-free: any module targeting the @@ -198,10 +198,10 @@ The `Guest`/`export!` shape the macro emits follows the `strategy.rs` (pure logic, tested against `&impl Host`) / `lib.rs` (handlers plus the macro attribute) split from ADR-0009. The keeper primitives in `nexum_sdk::keeper` - `WatchSet`, `Gates`, `Journal`, -`ConditionalSource`, `Retrier` - give conditional-commitment modules +`Poller`, `Retrier` - give conditional-commitment modules a shared set of `LocalStoreHost` conventions instead of hand-rolled key schemes; `videre_sdk::keeper` assembles them into the generic -sweep. +run. ## Venue persona: `videre-sdk` @@ -290,11 +290,11 @@ synchronous guest boundary. A `From` impl onto the wire fault is emitted, so `?` applies to client calls inside handlers. -`videre_sdk::keeper::Keeper::sweep` assembles the world-neutral +`videre_sdk::keeper::Keeper::run` assembles the world-neutral `nexum_sdk::keeper` stores - `WatchSet` to `Gates` to -`ConditionalSource::poll` to `Retrier` to `Journal` - over the +`Poller::poll` to `Retrier` to `Journal` - over the `VenueTransport` seam, so a conditional-commitment keeper writes one -`poll` producing the shared `Sweep` outcome and inherits the whole +`poll` producing the shared `Outcome` outcome and inherits the whole gate/journal/retry pass. ### Testing: `nexum-sdk-test` and `videre-test` @@ -444,7 +444,7 @@ the venue stays orderbook-only: poll seam (`Verdict`, with the deployed 1.x reverting wire quarantined behind `LegacyRevertAdapter`, per [ADR-0013](adr/0013-composable-cow-structured-poll.md)), and the - `sweep` slice composing the poll loop over the typed `CowClient`. + `run` slice composing the poll loop over the typed `CowClient`. The shipped CoW keepers - `modules/twap-monitor`, `modules/ethflow-watcher` - are ordinary `#[videre_sdk::keeper]` diff --git a/docs/08-platform-generalisation.md b/docs/08-platform-generalisation.md index fc9023d9..fab96f38 100755 --- a/docs/08-platform-generalisation.md +++ b/docs/08-platform-generalisation.md @@ -975,7 +975,7 @@ The SDK mirrors the architecture, one crate per layer, with no re-export between - **`nexum-sdk` (shipped)** - the universal Rust SDK for any module targeting `nexum:host/event-module`. It ships the host-trait seam (`ChainHost`, `LocalStoreHost`, `LoggingHost`, supertrait `Host`), `Fault` / `ChainError`, the `bind_host_via_wit_bindgen!` adapter macro, the `#[nexum_sdk::module]` attribute macro, chain / config / address helpers, the `http` fetch seam over wasi:http, the keeper store primitives, and the guest tracing facade. Would additionally provide `HostTransport` (alloy `Transport` trait over `chain::request` / `chain::request-batch`), `provider(chain_id)`, `TypedState` (serde over `local-store`), `RemoteStore`, `Messaging`, and `Signer` typed wrappers as future direction. Any module author - CoW, DeFi, gaming, whatever - uses this. -- **`videre-sdk` (shipped)** - the venue layer, serving both venue sides: the `VenueAdapter` trait under `#[videre_sdk::venue]` for adapter authors, and the `IntentBody` codec, typed `VenueClient` and `#[videre_sdk::keeper]` for keeper authors, plus the generic sweep assembler and the `videre-test` conformance kit alongside. +- **`videre-sdk` (shipped)** - the venue layer, serving both venue sides: the `VenueAdapter` trait under `#[videre_sdk::venue]` for adapter authors, and the `IntentBody` codec, typed `VenueClient` and `#[videre_sdk::keeper]` for keeper authors, plus the generic run assembler and the `videre-test` conformance kit alongside. - **Per-venue crates (shipped for CoW)** - each domain ships as crates on the venue layer, not as an SDK layer: `cow-venue` (body codec, typed client, adapter component) and `composable-cow` (conditional-order keeper machinery). A new domain adds its own. @@ -1008,7 +1008,7 @@ For **non-Rust** module authors (JavaScript, Python, Go, C++), the SDK is unnece | `shepherd:cow` WIT package | CoW event-ABI package of record (`cow-events` only; the legacy `cow-api` read path and `shepherd` world are retired) | | Venue adapter components | The domain-extension mechanism: `#[videre_sdk::venue]` components installed into the videre platform (`cow-venue` shipped) | | `nexum-sdk` crate (shipped) | Universal Rust SDK: host-trait seam (ADR-0009), Fault / ChainError, bind macro, module macro, chain / config / address helpers, keeper store primitives, guest `http` helper, tracing facade | -| `videre-sdk` crate (shipped) | Venue Rust SDK: VenueAdapter + venue macro, IntentBody codec, typed VenueClient + keeper macro, sweep assembler; `videre-test` conformance kit alongside | +| `videre-sdk` crate (shipped) | Venue Rust SDK: VenueAdapter + venue macro, IntentBody codec, typed VenueClient + keeper macro, run assembler; `videre-test` conformance kit alongside | | Content-addressed distribution | Platform-agnostic (Swarm/IPFS, ENS discovery, hash verification) | | Host Adapter | Platform-specific implementation of universal interfaces | diff --git a/docs/sdk.md b/docs/sdk.md index 1e93cd36..a465dff3 100644 --- a/docs/sdk.md +++ b/docs/sdk.md @@ -5,7 +5,7 @@ primitives, ABI helpers, an effect-trait seam for testing, the `#[nexum_sdk::module]` attribute macro and per-module adapter macro, and a `prelude` that keeps boilerplate out of module crates. `videre-sdk` layers the venue surface on top: the typed venue client, -the intent-body codec, the `VenueAdapter` seam and the keeper sweep. +the intent-body codec, the `VenueAdapter` seam and the keeper run. Modules that talk to a venue depend on both crates and import each directly (nothing is re-exported between them). diff --git a/modules/twap-monitor/Cargo.toml b/modules/twap-monitor/Cargo.toml index 53e29409..a9a91c9d 100644 --- a/modules/twap-monitor/Cargo.toml +++ b/modules/twap-monitor/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace = true crate-type = ["cdylib"] [dependencies] -composable-cow = { path = "../../crates/composable-cow", features = ["sweep"] } +composable-cow = { path = "../../crates/composable-cow", features = ["run"] } cow-venue = { path = "../../crates/cow-venue", features = ["client"] } nexum-sdk = { path = "../../crates/nexum-sdk" } videre-sdk = { path = "../../crates/videre-sdk" } diff --git a/modules/twap-monitor/src/strategy.rs b/modules/twap-monitor/src/strategy.rs index 92c5970c..c027be23 100644 --- a/modules/twap-monitor/src/strategy.rs +++ b/modules/twap-monitor/src/strategy.rs @@ -12,7 +12,7 @@ //! //! The module owns decode and evaluate only: log decoding into the //! keeper watch set, and the `getTradeableOrderWithSignature` poll -//! behind [`ConditionalSource`]. Gate discipline, the `submitted:` +//! behind [`Poller`]. Gate discipline, the `submitted:` //! journal, submission through the venue registry, and retry dispatch live in //! the shared composition (`composable_cow::run`). @@ -28,7 +28,7 @@ use cowprotocol::{ use nexum_sdk::chain::{eth_call_params, parse_eth_call_result}; use nexum_sdk::events::Log; use nexum_sdk::host::{ChainError, ChainHost, Fault, LocalStoreHost}; -use nexum_sdk::keeper::{ConditionalSource, Tick, WatchRef, WatchSet, watch_key}; +use nexum_sdk::keeper::{Poller, Tick, WatchRef, WatchSet, watch_key}; use videre_sdk::VenueTransport; /// Block fields the poll path reads on every dispatch. @@ -237,10 +237,10 @@ fn remove_watch( /// TWAP conditional source: decode the stored row's /// `ConditionalOrderParams` and evaluate /// `getTradeableOrderWithSignature` on chain. A row this source cannot -/// decode polls again next block rather than tearing down the sweep. +/// decode polls again next block rather than tearing down the run. struct TwapSource; -impl ConditionalSource for TwapSource { +impl Poller for TwapSource { type Outcome = Verdict; fn poll(&self, host: &H, watch: WatchRef<'_>, params: &[u8], tick: &Tick) -> Verdict {