[Release 76] - 2026-04-17
This is a recommended release focused on response signing, ClickHouse data lifecycle management, and query-path efficiency. Key highlights include RFC 9421 HTTP Message Signatures for cryptographically verifiable gateway responses, tag-based TTL rules for ClickHouse-exported data so operators can expire indexed rows by tag or uploader, and a major ClickHouse schema consolidation into a single partitioned transactions table with bloom filter skip indexes and native projections. It also adds per-host APEX_ARNS_NAME mapping, Parquet export partition progress in the status API, and a clickhouse-import --flat-dir mode. GraphQL gets two performance improvements — skipping SQLite for heights already covered by ClickHouse and skipping the owner.key fetch when only owner.address is selected — plus a fix for duplicate transaction results from ClickHouse and correctly-populated indexedAt / blockPreviousBlock fields.
Added
-
RFC 9421 HTTP Message Signatures for Gateway Responses: The gateway can now sign responses using RFC 9421 HTTP Message Signatures, allowing clients to cryptographically verify response integrity and origin. Controlled by
HTTPSIG_ENABLED(default: false) with an Ed25519 key auto-generated atHTTPSIG_KEY_FILE(default:data/keys/httpsig.pem).HTTPSIG_BIND_REQUEST(default: true) binds each response to the triggering request via@method;reqand@path;req. An attestation linking the key to the operator wallet is uploaded to Arweave on startup whenHTTPSIG_UPLOAD_ATTESTATION=trueandOBSERVER_WALLETis set. HTTPSIG response metadata is documented in OpenAPI for/ar-io/infoand data endpoints. -
Tag-Based TTL Rules for ClickHouse-Exported Data: Operators can now expire rows in the ClickHouse
transactionstable by tag content or uploader owner address. Rules are declared inconfig/clickhouse-ttl-rules.yaml(copy from the committed.example.yamltemplate) and loaded at the top of everyclickhouse-auto-importcycle into four source tables, with exact-match lookups going through refreshingCOMPLEX_KEY_HASHEDdictionaries and prefix matches falling back to scanned tables. Native TTL enforcement deletes rows whenexpires_atelapses. Supports a top-leveldefault_ttl_secondsfallback and per-rulenever_expire: trueexemptions (precedence: exempt > shortest TTL match > default > NULL). v1 applies only to rows imported after rules are loaded; no backfill. The loader fails open on missing/malformed rules to avoid blocking imports. -
Per-Host
APEX_ARNS_NAMEMapping:APEX_ARNS_NAMEnow accepts a comma-separated list of values positionally mapped toARNS_ROOT_HOSTentries (e.g.,APEX_ARNS_NAME=turbo,ar-iowithARNS_ROOT_HOST=arweave.dev,g8way.io). A single value still applies to all hosts. -
Parquet Export Partition Progress in Status API: The admin status endpoint and the
parquet-exportCLI poll loop now surface the current partition range and completed/total partition counts while a Parquet export is in progress. -
clickhouse-import --flat-dirmode:scripts/clickhouse-importaccepts a flat directory of Parquet files named<table>-minHeight:<min>-maxHeight:<max>-rowCount:<n>.parquet(blocks / transactions / tags all in the same directory), as an alternative to the default<table>/data/height=<min>-<max>/*.parquetHive layout.
Changed
-
ClickHouse schema consolidation: The ClickHouse GQL backend now uses a single
transactionstable with partitioning by height, bloom filter skip indexes onidandtags, and native projections for owner and recipient queries, replacing the previous four-table design (transactions,id_transactions,owner_transactions,target_transactions). Column codecs (Delta + ZSTD) andLowCardinalityoncontent_type/signature_typereduce storage. The GQL query layer useshasAnyfor multi-value tag filters and tuple-comparison cursor pagination. Requires ClickHouse 24.8 or later and a one-time full re-import from Parquet — seedocs/parquet-and-clickhouse-usage.md. -
Skip SQLite for Heights Covered by ClickHouse in GraphQL: Opt-in optimization in
CompositeClickHouseDatabaseraises the SQLite fallback'sminHeightto(clickhouseMax - buffer + 1)and skips the SQLite call entirely when the adjusted range is empty. Controlled byCLICKHOUSE_SQLITE_MIN_HEIGHT_ENABLED(default: false), with a configurable safety buffer (default: 10 heights) and a cached ClickHouse max-height lookup (default TTL: 60s). Degrades to prior behavior on lookup failure. -
GraphQL
owner.keyFetch Skipped When Onlyowner.addressRequested: Splitting theTransaction.ownerresolver into field-levelOwner.addressandOwner.keyresolvers lets GraphQL skip the per-row owner key fetch unlesskeyis explicitly selected. Memoization on theOwnerparent still fetches the key only once when multiple aliased selections or overlapping fragments request it in the same query. -
Default ClickHouse Image Bumped to 26.3: The default ClickHouse container image used by
clickhouse-auto-importis now 26.3. -
Observer Image Updated:
OBSERVER_IMAGE_TAGbumped to include epoch source fixes.
Fixed
-
ClickHouse GQL
indexedAtandblockPreviousBlockfields: These fields were previously always returned asundefinedbecause the base SELECT omitted the corresponding columns. They are now populated. -
Duplicate GraphQL Transaction Results from ClickHouse: The
transactionstable usesReplacingMergeTree(inserted_at), which only deduplicates during background merges. Queries now useFINALso GraphQL returns a single edge per id instead of every un-merged version. -
Tag Headers on Manifest-Resolved Responses: When a manifest path resolves to an inner data item,
X-Arweave-Tag-*headers are now populated from the resolved inner item rather than the manifest transaction. -
Turbo Fallback Narrowed to Module-Not-Found: The optional Turbo upload path now falls back only on module-not-found (instead of swallowing unrelated errors) and requires an explicit trigger header before signing.
Image SHAs
ENVOY_IMAGE_TAG:6934e519fb98a46da4c17bdfa51d66225428b7c0CORE_IMAGE_TAG:e032ac521e43b8c987c0da55064f8eb55055c2ceCLICKHOUSE_AUTO_IMPORT_IMAGE_TAG:fb56b2b0203819c2ea439cdb14bb34229da66dafLITESTREAM_IMAGE_TAG:be121fc0ae24a9eb7cdb2b92d01f047039b5f5e8OBSERVER_IMAGE_TAG:21098d2ab630348d56339a745f020374a699d378