Skip to content

feat(sdk): submit appData hash-only and retire resolve_app_data - #261

Merged
mfw78 merged 4 commits into
developfrom
feat/m1-appdata-hash-only
Jul 14, 2026
Merged

feat(sdk): submit appData hash-only and retire resolve_app_data#261
mfw78 merged 4 commits into
developfrom
feat/m1-appdata-hash-only

Conversation

@mfw78

@mfw78 mfw78 commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Submit CoW orders with appData as the 32-byte on-chain hash and retire the resolve_app_data round-trip, so the module no longer fetches the full appData document before submission.
  • Bump cowprotocol 0.1 -> 0.2 to pick up the hash-only OrderCreationAppData constructor, patched via [patch.crates-io] to the nullislabs/cow-rs fork rev 17fc0c5 until a release with the constructor ships.

Changes

  • Delete crates/shepherd-sdk/src/cow/app_data.rs (269 lines) and its mod.rs/lib.rs/README references.
  • Rework modules/twap-monitor/src/strategy.rs to submit order.appData verbatim (the hex digest, appDataHash absent) with no preceding appData GET.
  • Remove the now-redundant GET /api/v1/app_data/{hash} route from tools/orderbook-mock and the matching 404 branch in twap-monitor.
  • Migrate stop-loss and a shepherd-cow-host test off the deprecated from_signed_order_data; drop the serde_json dependency from the SDK.

Test plan

Notes for reviewer

Closes #133

@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 502175c to d8d2622 Compare July 7, 2026 23:05
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 066df38 to 6b637de Compare July 7, 2026 23:05
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from d8d2622 to aab2605 Compare July 8, 2026 00:42
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 6b637de to 2a1eef0 Compare July 8, 2026 00:42
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from aab2605 to 23d5dde Compare July 8, 2026 01:18
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 2a1eef0 to 5305424 Compare July 8, 2026 01:18
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 23d5dde to f100e81 Compare July 8, 2026 01:44
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 5305424 to 4ecf3ab Compare July 8, 2026 01:44
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from f100e81 to 0b8ccac Compare July 8, 2026 02:10
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 4ecf3ab to 326e9a2 Compare July 8, 2026 02:10
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 0b8ccac to 7b20447 Compare July 8, 2026 02:19
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 326e9a2 to 416847a Compare July 8, 2026 02:19
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 7b20447 to 02558d2 Compare July 8, 2026 02:22
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 416847a to f97a6b6 Compare July 8, 2026 02:22
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 02558d2 to b97c09d Compare July 8, 2026 03:03
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from f97a6b6 to ac16274 Compare July 8, 2026 03:03
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from b97c09d to bd2df3e Compare July 8, 2026 04:59
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from ac16274 to 2bf2d96 Compare July 8, 2026 04:59
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from bd2df3e to 46aeba6 Compare July 8, 2026 05:30
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 2bf2d96 to e8d4dc8 Compare July 8, 2026 05:30
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 46aeba6 to bd6e9e8 Compare July 8, 2026 06:21
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from e8d4dc8 to e33bad0 Compare July 8, 2026 06:21
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from bd6e9e8 to 39fe2ee Compare July 8, 2026 06:39
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from e33bad0 to f6317b9 Compare July 8, 2026 06:39
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 39fe2ee to 3ef293a Compare July 8, 2026 07:06
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from f6317b9 to bb52ae5 Compare July 8, 2026 07:06
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 3ef293a to 6f8eee3 Compare July 8, 2026 07:20
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from bb52ae5 to a9fecf3 Compare July 8, 2026 07:20
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 6f8eee3 to 9eba535 Compare July 8, 2026 07:35
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from a9fecf3 to e384beb Compare July 8, 2026 07:35
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 866cb96 to e0d3644 Compare July 8, 2026 09:02
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from c4daed6 to 4ccd7ee Compare July 8, 2026 09:02
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from e0d3644 to 911ac0d Compare July 8, 2026 09:18
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 4ccd7ee to 43148e6 Compare July 8, 2026 09:18
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 9ea4356 to 7a99595 Compare July 8, 2026 12:09
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 43148e6 to 3fef207 Compare July 8, 2026 12:09
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 7a99595 to 8492152 Compare July 8, 2026 12:20
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 3fef207 to 3da7cc2 Compare July 8, 2026 12:20
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 8492152 to c460137 Compare July 8, 2026 12:49
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 3da7cc2 to 4f0e73e Compare July 8, 2026 12:49
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from c460137 to 7b945f0 Compare July 8, 2026 13:36
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 4f0e73e to 2ad1455 Compare July 8, 2026 13:36
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 7b945f0 to 0d65afb Compare July 8, 2026 14:07
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 2ad1455 to a7f18ac Compare July 8, 2026 14:07
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 0d65afb to 9986684 Compare July 8, 2026 22:33
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from a7f18ac to 388a0cf Compare July 8, 2026 22:33
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 9986684 to 45fea52 Compare July 8, 2026 23:05
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 388a0cf to 2f0f0ff Compare July 8, 2026 23:05
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 45fea52 to 76376ec Compare July 8, 2026 23:24
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 2f0f0ff to 11bd146 Compare July 8, 2026 23:24
@mfw78
mfw78 force-pushed the fix/fault-train-hardening branch from 76376ec to 9e503f7 Compare July 8, 2026 23:29
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 11bd146 to 05db954 Compare July 8, 2026 23:29
Base automatically changed from fix/fault-train-hardening to develop July 8, 2026 23:34
@mfw78
mfw78 force-pushed the feat/m1-appdata-hash-only branch from 05db954 to 0359b40 Compare July 9, 2026 02:09
@mfw78
mfw78 changed the base branch from develop to docs/typed-fault-review-nits July 9, 2026 02:16

@lgahdl lgahdl left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed the full diff. Solid simplification — hash-only submission with watch-tower parity is clearly the right shape, and −546 lines including the whole resolve_app_data module plus its mock route is a real maintenance win. The test rewrite is careful (the appDataHash-absence assertion being load-bearing is a nice catch). Three non-blocking observations:

  1. stop-loss asymmetry: twap-monitor moves to OrderCreation::new_app_data_hash_only, but stop-loss stays on the document-shape OrderCreation::new. If that's deliberate (stop-loss authors its own doc so the digest always matches), a one-line comment at the stop-loss call site would stop the next reader from "fixing" it into hash-only; if it's not deliberate, hash-only would let stop-loss drop its remaining serde_json usage too.

  2. Replacement coverage for the deleted 404 test: poll_ready_skips_submit_when_app_data_hash_not_mirrored covered the unmirrored-digest path; its post-change equivalent (orderbook rejects INVALID_APP_DATAclassify_api_error dispatches backoff rather than tight-looping) doesn't have a strategy-level test in this diff. If that lives upstack in #242/#259's sweep, a pointer in the PR body would close the loop; if not, it's worth one test since this is the exact path the old code handled specially.

  3. Horizon check vs manual clocks: the 0.2.0 constructor's one-year valid_to horizon reads the wall clock, which in guest builds is the WASI clock — under the harness ManualClock override, guest time can sit arbitrarily far from realistic validTo values, so harness-driven submit paths could spuriously classify orders as beyond-horizon (or never). Tests here handle it via valid_to_in(), which is right; flagging the interaction mostly as a cross-ref to #169/#172 where the horizon-check consequences are being tracked, in case the manual-clock angle isn't on the radar there.

(The [patch.crates-io] documentation in Cargo.toml is exactly what our docs sweep in #311 points at — nice that the comment names the drop condition.)

mfw78 and others added 4 commits July 14, 2026 03:28
The orderbook rejection envelope has an optional structured data field
(e.g. a minimum-fee quote) that the retired host-error envelope
round-tripped in full but the typed order-rejection dropped. Add
data: option<string> to the record, populate it host-side from the
parsed envelope, and thread it through the SDK mirror and the
wit-bindgen conversion so no rejection information is lost end to end.
Nothing guest-side decodes the orderbook ApiError JSON any more: the
host parses the envelope once into the typed order-rejection and the
classifier dispatches on that. The re-export and its comment described
the retired flow, so remove them from the prelude surface.
…_app_data

The orderbook accepts OrderCreation appData as the bare signed digest
and joins the pre-registered document on its side, so the pre-submit
GET /api/v1/app_data/{hash} was a redundant round-trip against the
same database that validates the submission, plus a 404 dead end
watch-tower does not have.

Bump cowprotocol to 0.2.0, patched to the cow-rs rev that exposes
OrderCreation::new_app_data_hash_only (the OrderCreationAppData::Hash
wire shape, which omits appDataHash - the orderbook's untagged decoder
would otherwise read the body as the full-document shape and reject
it) and scopes the js_sys clock fallback to browser wasm32 so the
constructor's valid_to horizon check reads WASI SystemTime instead of
emitting a wasm-bindgen import no wasmtime host can satisfy.

twap-monitor now submits order.appData verbatim; an unregistered
digest rejects as InvalidAppData and classify_api_error dispatches the
backoff, matching watch-tower exactly. Delete shepherd-sdk's
resolve_app_data module and the orderbook-mock's now-unused appData
GET route, and drop the sdk's serde_json dependency that existed only
for that lookup.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr-train Part of the current stacked PR train; lands in sequence, do not merge out of order.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

sdk: submit appData hash-only and retire resolve_app_data

2 participants