Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Setup and shape

audience: ai

Before any code runs, the searcher author fixes three things: the crate-level dependencies, the searcher-α coalition shape, and the TDX posture for the parts of the handshake Flashbots requires attested.

This chapter is the shortest in Part II. Its only job is to put the CoalitionConfig and the testnet-1a reference constants on the page so the next six chapters have something to reference.

Dependencies

The searcher depends on four published crates plus the builder crate that exposes the lattice handshake:

Cargo.toml, [dependencies]
mosaik          = "0.3"     # primitives
zipnet          = "0.5"     # sealed submission + unseal
builder         = "0.3"     # exposes LatticeConfig::testnet_1a()
coalition       = "0.1"     # this book's crate once published
tokio           = { version = "1", features = ["full"] }

The exact minor versions are pinned in Flashbots’ testnet-1a release notes; updating the searcher past a new release note is a coalition-level operation covered in sustainability. Until the coalition crate lands, every struct below is a specification shape, not a library symbol.

The testnet-1a reference constant

The builder crate publishes each Flashbots-operated instance’s LatticeConfig as a const function, returning the instance’s stable id and its per-organism content hashes:

use builder::LatticeConfig;

const TESTNET_1A: LatticeConfig<'static> =
    LatticeConfig::testnet_1a();

TESTNET_1A.stable_id() is the (instance_name, network_id) blake3 that Flashbots publishes on the testnet-1a release page. It does not change across Flashbots’ internal rotations — only across a retirement-and-republish sequence (see contributors — rotations). The searcher folds this stable id verbatim into searcher-α’s COA_LATTICES.

The searcher-α coalition

searcher-α is the smallest coalition that satisfies the example’s thesis: one standalone organism (the searcher itself) referencing one lattice (testnet-1a) through a CoalitionConfig fingerprint.

use coalition::{
    CoalitionConfig, OrganismRef,
    COALITION_ROOT_SEED, SCHEMA_VERSION_U8,
};

const SEARCHER_ORG: OrganismRef<'static> = OrganismRef {
    role:         "searcher",
    stable_id:    const_blake3!(
        b"instance|searcher-α.searcher|", UNIVERSE.bytes()
    ),
    content_hash: None, // pinned only when TDX is required
};

pub const SEARCHER_ALPHA: CoalitionConfig<'static> =
    CoalitionConfig {
        schema_version:    SCHEMA_VERSION_U8,
        coalition_seed:    COALITION_ROOT_SEED,
        instance_name:     "searcher-α",
        lattices:          &[TESTNET_1A.stable_id()],
        organisms:         &[SEARCHER_ORG],
        atlas:             None,
        almanac:           None,
        chronicle:         None,
        compute:           None, // added in chapter 5
        randomness:        None,
        ticket_issuer:     None,
        retirement_policy: Default::default(),
    };

Three structural notes on the shape above:

  • Coalition names are operator-scoped, not universe- scoped. The string searcher-α need not be unique across mosaik; uniqueness is delivered by the blake3 fingerprint SEARCHER_ALPHA.stable_id() = blake3(intent ‖ content ‖ acl) folding every field above.
  • Member-by-reference. COA_LATTICES carries TESTNET_1A.stable_id(), not a fresh derivation. searcher-α is not a re-build of the Flashbots lattice; it is a coalition that references the Flashbots lattice as a member, voluntarily, from its own operator context.
  • Open catalogs. All module fields are None at this chapter. Later chapters add Compute (inference) and Chronicle (sustainability). No coalition is forced to ship any basic service.

What the searcher agent exposes

The searcher exposes three mosaik primitives and nothing else:

  • Stream<Observation> — evidence-pointed summaries of market state that went into each submission. Consumers following the searcher’s reasoning read this.
  • Stream<SealedSubmissionIntent> — the public intent of each bundle the searcher sealed through the shuffle. The payload is a sealed blob the lattice’s unseal committee opens (chapter 6).
  • Map<CycleId, OutcomeReport> — per-cycle self- reports (realised PnL, inclusion rate, refund receipts). Feeds the accuracy-reputation organism in chapter 7.

Streams carry intent and evidence pointers; sealed payloads ride a separate shuffle channel so the public commits never leak bundle content.

TDX posture

Flashbots’ testnet-1a release publishes TDX Measurements for the parts of the pipeline it requires attested:

testnet-1a surfaceRoleTDX Measurements pinned by Flashbots
zipnet::seal write-sideSubmissionyes
unseal committee membersDecryptionyes
offer read-side (order flow)Market intelyes (attested-read-only)
tally::Refunds read-sideAttributionyes (attested-read-only)
relay downstreamSubmissionout of scope for searchers

The searcher’s own TDX posture is a policy choice:

  • Non-TDX searcher. Simpler deployment; the searcher’s runtime policy can drift freely between Config republications (see ai/sustainability.md — what the Config pins). Cannot meet any Flashbots requirement that the searcher itself present attested Measurements, so some write-side surfaces will refuse its bonds.
  • TDX searcher (recommended). The searcher image carries its own Measurements; SEARCHER_ORG.content_hash folds them. Flashbots’ write-side TicketValidator composition admits the searcher’s attested identity; other searchers and shared reputation organisms treat the searcher’s own Measurements as a policy pin.

Either posture is supported by the mechanics in binding. The chapters assume TDX searcher unless explicitly noted.

Repository layout

The searcher’s repository tree, post-setup:

searcher-alpha/
  Cargo.toml
  src/
    coalition.rs             # SEARCHER_ALPHA const
    content.rs               # SearcherContent struct
    policy/                  # black-box strategy code
      mod.rs
      mev_searcher.rs
      market_maker.rs        # variant, chapter-end notes
    organism.rs              # Organism::searcher(&network, &Config)
    bin/
      searcher.rs            # Tokio entrypoint

Each module above is introduced in a subsequent chapter. This chapter introduces none of it beyond the coalition.rs constant shown above.

Market-maker variant — differences at setup

  • The coalition’s instance_name is typically mm-β or similar, not searcher-α.
  • SEARCHER_ORG.role becomes "market-maker".
  • COA_LATTICES still carries testnet-1a.stable_id() — the market-maker also binds against the same lattice; it differs in what write-side surface it uses (submission).
  • The market-maker’s public surface drops observations in favour of a quotes Stream<Quote> and a fills Collection<FillId, FillReport>. The sealed-submission intent stream remains but carries QuoteUpdates.
  • TDX posture is identical. The Measurements set Flashbots requires of the searcher’s submission path is the same set the market-maker must bond against.

Cross-references