From 2188ef03b943393c9ff3925a439d4f1797c4c174 Mon Sep 17 00:00:00 2001 From: brunota20 Date: Fri, 19 Jun 2026 10:15:19 -0300 Subject: [PATCH] chore(sdk + twap-monitor): hex helpers via alloy_primitives::hex::encode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit mfw78 review of PR #8 (https://github.com/nullislabs/shepherd/pull/8) flagged "we already pull alloy, so pulling hex via there is really not much of a deal". The PR #47 (COW-1074) commit acc9654 then introduced two new custom hex helpers that recreate the same antipattern at a different scope: - `crates/shepherd-sdk/src/cow/app_data.rs::encode_hex` - 32-byte hash → `0x...`. Used by `resolve_app_data` to format the orderbook lookup path. - `modules/twap-monitor/src/strategy.rs::hex_short` - 8-byte prefix → `0x...…`. Used to format `appData` hashes in INFO log lines. Both crates already depend on `alloy-primitives` (sdk: 1.6, twap-monitor: 1.5), so the swap is a one-liner per call site: - `encode_hex(b)` → `format!("0x{}", alloy_primitives::hex::encode(b))` - `hex_short(b)` → `format!("0x{}…", alloy_primitives::hex::encode(&b[..8]))` Both functions keep their old signature so callers (`resolve_app_data` in the SDK, every `host.log` line in twap-monitor strategy) need no changes. Comments on both helpers now explicitly reference mfw78's PR #8 guidance so the next person tempted to hand-roll a `0123456789abcdef` table has a hook. Validation: cargo test -p shepherd-sdk -p twap-monitor: 32 + 23 passed; cargo clippy --all-targets -- -D warnings: clean; cargo fmt --check: clean; zero em-dash drift. Why this PR sits in a separate branch rather than amending PR #47: PR #47 is already In Review, and #48/#49/#50 stack on top of it. Amending would require force-pushing 4 branches. A small follow-up PR keeps each one bisectable and lets mfw78 review the alloy alignment in isolation. AI assistance disclosure: drafted by Claude (Opus 4.7, 1M context) while sweeping all open PRs for the same antipatterns mfw78 flagged on PRs #8 and #9. --- crates/shepherd-sdk/src/cow/app_data.rs | 14 +++++--------- modules/twap-monitor/src/strategy.rs | 13 ++++--------- 2 files changed, 9 insertions(+), 18 deletions(-) diff --git a/crates/shepherd-sdk/src/cow/app_data.rs b/crates/shepherd-sdk/src/cow/app_data.rs index 29aed1c4..1406d9d7 100644 --- a/crates/shepherd-sdk/src/cow/app_data.rs +++ b/crates/shepherd-sdk/src/cow/app_data.rs @@ -80,16 +80,12 @@ pub fn resolve_app_data( }) } +/// Lowercase `0x`-prefixed hex of a 32-byte appData hash. Delegates +/// to [`alloy_primitives::hex::encode`] (alloy is already a direct +/// dependency of this crate) per mfw78's PR #8 guidance against +/// carrying our own hex formatters. fn encode_hex(bytes: &[u8; 32]) -> String { - const HEX: &[u8; 16] = b"0123456789abcdef"; - let mut out = String::with_capacity(2 + 64); - out.push('0'); - out.push('x'); - for b in bytes { - out.push(HEX[(b >> 4) as usize] as char); - out.push(HEX[(b & 0xf) as usize] as char); - } - out + format!("0x{}", alloy_primitives::hex::encode(bytes)) } /// Parse the orderbook's `/api/v1/app_data/{hash}` response shape: diff --git a/modules/twap-monitor/src/strategy.rs b/modules/twap-monitor/src/strategy.rs index dacd393b..77b030b5 100644 --- a/modules/twap-monitor/src/strategy.rs +++ b/modules/twap-monitor/src/strategy.rs @@ -233,16 +233,11 @@ fn outcome_label(o: &PollOutcome) -> &'static str { /// Render the first 8 bytes of an `appData` hash as `0x12345678…` /// for log lines. Full 32-byte hex is too noisy for an INFO log; /// 8 bytes is unique enough to grep against the orderbook. +/// +/// Delegates to [`alloy_primitives::hex::encode`] per mfw78's PR #8 +/// guidance against carrying our own hex formatters. fn hex_short(bytes: &[u8; 32]) -> String { - const HEX: &[u8; 16] = b"0123456789abcdef"; - let mut out = String::with_capacity(2 + 16 + 1); - out.push_str("0x"); - for b in &bytes[..8] { - out.push(HEX[(b >> 4) as usize] as char); - out.push(HEX[(b & 0xf) as usize] as char); - } - out.push('…'); - out + format!("0x{}…", alloy_primitives::hex::encode(&bytes[..8])) } fn watch_key(owner: &Address, params_hash: &B256) -> String {