Skip to content

Backfill from contract genesis on first boot: set start_block once nexum-runtime#381 lands #676

Description

@mfw78

Problem

Both keepers build their entire state from logs, and an event trigger opens at head when no cursor is stored.

A fresh daemon is therefore permanently blind to anything that happened before it first ran. A ComposableCoW conditional order is registered by a ConditionalOrderCreated log and can stay live for weeks, so a TWAP created last month and halfway through execution is never polled and never submitted. No later block can recover it.

resume = true (landed in shepherd#675) fixes the restart case by persisting a cursor. It does not help the first boot, which has no cursor to resume from.

Blocked on

nullislabs/nexum-runtime#381 adds an optional start_block to the event trigger. It seeds the cursor only while no stored cursor exists, so it backfills once and then yields to the store forever.

Do not set start_block in a manifest before the pin bump. CoreTrigger does not use deny_unknown_fields, so the currently pinned runtime (fd16db7) parses the key and silently ignores it. The manifest would look configured while doing nothing.

Deployment blocks, resolved from the deploy transactions

ComposableCoW is the same CREATE2 address on every chain, 0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74, but the deployment block differs per chain.

Contract Chain Address Block Date
ComposableCoW mainnet (1) 0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74 17883049 2023-08-10
ComposableCoW Sepolia (11155111) 0xfdaFc9d1902f4e0b84f65F49f244b32b31013b74 5072748 2024-01-12
CoWSwapEthFlow Sepolia (11155111) 0xbA3cB449bD2B4ADddBc894D8697F5170800EAdeC 7541028 2025-01-21

Sources: cowprotocol/composable-cow networks.json for the ComposableCoW deploy transactions, and the contract creation transaction for the EthFlow deployment. Each block number is the block of the recorded deployment transaction.

EthFlow has had multiple per-network and per-version deployments, unlike ComposableCoW's single CREATE2 address, so the mainnet EthFlow address and its block must be resolved separately rather than assumed to carry.

Work

  1. Bump the nexum-runtime pin in shepherd from fd16db7 to the merge commit of nexum-runtime#381. This must happen in lock-step with the same bump in videre, because both repos pin the same rev and a split pin resolves two copies of nexum-runtime whose Extension seam types do not match.
  2. Set start_block on all three event triggers in modules/twap-monitor/component.toml and modules/ethflow-watcher/component.toml, using the table above.
  3. Revisit the numbers as part of shepherd#657 when the chain moves to mainnet, since both the chain id and the EthFlow address change.

Cost of the first backfill

Mainnet ComposableCoW from 17883049 is roughly 5.4M blocks. The bulk phase chunks at the operator-declared log range and commits a durable frontier per chunk, so the scan resumes at the last completed chunk if interrupted rather than restarting. max_lookback stays unset, because a cap drops the oldest missed blocks, which is the loss this fixes.

AI Assistance: Claude Code used for tracing the cursor-seeding path and resolving the deployment blocks.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions