Skip to main content
Backfill applies a function to historical source rows and writes derived data for the corresponding bundle. Use the same transformation as per-block computation, with a historical input and output context.

Chain and historical context

A bundle identifies a partition of source data. It does not select the EVM state for every function read. If your function queries historical state, obtain the correct block identifier from each source row and pass it to the read.

Prerequisites

  • A bundle deployment with access to the source data files and BlockDB BatchWrite.
  • A compatible target block table and permission to overwrite its selected bundle.
  • The source schema required by the transformation.
  • Historical node data when the function also performs EVM reads.

Submit one bundle

Pass the source_code from per-block computation to this helper. Use your source table, target table, and selected bundle number.
The input and output use the same number. For a range, submit only the intended bundle numbers and retain each task and writer result. Keep a record of failed or unknown submissions before deciding which work to repeat.

Backfill a bundle range

backfill_block_bundles submits an inclusive range of bundle numbers. BlockBundleCallConfigTemplate supplies the shared trigger configuration. The helper calls for_bundle(number) on the input and block-table writer templates so both use the same bundle number.
Use the same table and function prerequisites as the single-bundle example. A writer template has no block_bundle yet; instantiate it with for_bundle(number) before submitting an individual task. The range helper performs that step for you. The helper returns a BackfillSummary with succeeded, failed_bundles, and failure_codes. By default it aborts if the first bundle fails. These counters describe task outcomes; they do not establish storage-side job completion.

Define a reusable pipeline

Pipeline groups trigger tables, a function, and a target table. Trigger.params uses SOURCE_ROW to place the input record in the function arguments. Reuse the EVM trace transformation above:
Create pipe with make_pipeline(source_table, target_table, source_code), then choose the operation: Choose heights available in your source tables. Bundle numbers passed to backfill_block_bundles and block heights passed to Pipeline.backfill are different units. Exact boundary processing and update() also require a block deployment. Add lookup-only upstream tables through Pipeline(depends=[...]). They constrain readiness but do not trigger calls or supply arguments. The pipeline chooses the writer from the target table kind; Pipeline(condition=...) forwards a condition only for normal-table output. During the subscription phase, update() does not backfill height gaps. Fill historical gaps explicitly with backfill(). Normal-table and time-table targets start subscribing without the initial block catch-up.

Confirm completion

For a real block-table bundle write, the writer result includes job_id. A successful task confirms BatchWrite submission, not storage-side job completion. Record the job identifier and confirm its BlockDB status and target read conditions before marking the range ready. A computation with no output is not by itself proof that a source partition was complete. Check source availability and the intended overwrite semantics, especially when all rows are filtered out.

Handle partial failures

Continue reading