Follow-up to #117 / #74. Today the executor hard-codes target_block = current + 1 and uses a fixed tip percentage. With mempool-triggered opps coming online (#117 + sim issue), we need a real ordering policy that distinguishes mempool-fresh from block-driven candidates and reacts to competition.
This is the policy layer between detection and bundle build. No new submission paths — still shadow-only — just smarter decisions recorded on the arbs row.
To do
Strategy enum on arbs
Policy
Tip ladder
Builder selection
Metrics
Out of scope (separate issue)
Done when
- 30-min live shadow run shows non-zero counts across at least two
strategy values in arbs table
- repeat-detection test: same simulated
path_hash published twice within 1s produces an escalated tip on second bundles row
- builder-selection test: mempool-triggered candidate produces a bundle row with
builders=["flashbots"] only; block-driven candidate produces a row with all four
Files touched
crates/grpc-server/src/engine.rs (build_new_arb)
crates/grpc-server/src/strategy.rs (new)
crates/common/src/types.rs (Strategy enum)
cmd/executor/main.go (mirror enum, builder selection)
internal/db/ledger.go (NewArb gains Strategy field)
migrations/0003_add_strategy_to_arbs.sql
config/strategy.yaml
Branch
feat/mempool-tracking-scaffold
Follow-up to #117 / #74. Today the executor hard-codes
target_block = current + 1and uses a fixed tip percentage. With mempool-triggered opps coming online (#117 + sim issue), we need a real ordering policy that distinguishes mempool-fresh from block-driven candidates and reacts to competition.This is the policy layer between detection and bundle build. No new submission paths — still shadow-only — just smarter decisions recorded on the
arbsrow.To do
Strategy enum on arbs
0003_add_strategy_to_arbs.sqladdingstrategy TEXT NOT NULL DEFAULT 'backrun_next_block'BackrunNextBlock,BackrunSameBlock,Skipped(with reason)protocol_label-style adapter so renaming the variant ripples to the DB bindingPolicy
BackrunSameBlockfor ultra-fresh mempool-triggered opps (target = current pending block, not next)BackrunNextBlockretained as default for block-driven oppspath_hashwas submitted within the last block — record inarbswithstrategy='skipped'+ reasonTip ladder
path_hashdetected ≥2 times within current block, escalate tip by Y bps per repeat (capped)bundles.tip_bps(already in schema)config/strategy.yaml— hot-reloadable via existingControlService.ReloadConfigBuilder selection
bundles.buildersJSONB (already wired)Metrics
aether_strategy_chosen_total{strategy}counteraether_tip_bps_chosenhistogram with bucket boundaries at common bps tiersaether_race_bumps_total{path_hash_bucket}(low-cardinality bucket ofpath_hash)Out of scope (separate issue)
Done when
strategyvalues inarbstablepath_hashpublished twice within 1s produces an escalated tip on secondbundlesrowbuilders=["flashbots"]only; block-driven candidate produces a row with all fourFiles touched
crates/grpc-server/src/engine.rs(build_new_arb)crates/grpc-server/src/strategy.rs(new)crates/common/src/types.rs(Strategy enum)cmd/executor/main.go(mirror enum, builder selection)internal/db/ledger.go(NewArb gains Strategy field)migrations/0003_add_strategy_to_arbs.sqlconfig/strategy.yamlBranch
feat/mempool-tracking-scaffold