Skip to content

Feat/hash pinned source reads - #1364

Draft
DylanVerstraete wants to merge 4 commits into
usc-devfrom
feat/hash-pinned-source-reads
Draft

DylanVerstraete wants to merge 4 commits into
usc-devfrom
feat/hash-pinned-source-reads

Conversation

@DylanVerstraete

Copy link
Copy Markdown
Contributor

Description of proposed changes


When merging this PR:

  • For PRs against usc-dev use the "Squash and merge" button
  • For PRs against usc-testnet/main use the "Create a merge commit" button
  • Hotfixes against usc-testnet/main should use the "Squash and merge" button

Practical tips for PR review:

  • All GitHub Actions report PASS
  • Newly added code/functions have unit tests
    • Coverage tools report all newly added lines as covered
    • The positive scenario is exercised
    • Negative scenarios are exercised, e.g. assert on all possible errors
    • Assert on events triggered if applicable
    • Assert on changes made to storage if applicable
  • Modified behavior/functions - try to make sure above test items are covered
  • Integration tests are added if applicable/needed

@gluwa-bot

gluwa-bot commented Sep 15, 2026

Copy link
Copy Markdown
Contributor

Overview

Image reference gluwa/creditcoin3:latest gluwa/creditcoin3:latest
- digest dfb918c3c546 d5325595a227
- tag latest latest
- provenance 7e92a94 e985266
- vulnerabilities critical: 3 high: 16 medium: 21 low: 4 unspecified: 13 critical: 2 high: 13 medium: 11 low: 3 unspecified: 11
- platform linux/amd64 linux/amd64
- size 430 MB 431 MB (+622 kB)
- packages 405 404 (-1)
Base Image ubuntu:26.04
also known as:
latest
resolute
ubuntu:26.04
also known as:
latest
resolute
rolling
- vulnerabilities critical: 1 high: 7 medium: 12 low: 1 unspecified: 2 critical: 1 high: 5 medium: 2 low: 0
Labels (1 changes)
  • ± 1 changed
  • 3 unchanged
-org.opencontainers.image.created=2026-06-27T04:19:04.617438+00:00
+org.opencontainers.image.created=2026-08-17T09:02:45.677319+00:00
 org.opencontainers.image.description=The Ubuntu container image maintained by Canonical

Ubuntu is a Debian-based Linux operating system that runs from the desktop to the cloud, to all your internet connected things.
It is the world's most popular operating system across public clouds and OpenStack clouds.
It is the number one platform for containers; from Docker to Kubernetes to LXD, Ubuntu can run your containers at scale.
Fast, secure and simple, Ubuntu powers millions of PCs worldwide.

 org.opencontainers.image.title=ubuntu
 org.opencontainers.image.version=26.04
Policies (2 improved, 0 worsened)
Policy Name gluwa/creditcoin3:latest gluwa/creditcoin3:latest Change Standing
Default non-root user No Change
No copyleft licenses ⚠️ 373 ⚠️ 361 -12 Improved
No fixable critical or high vulnerabilities ⚠️ 19 ⚠️ 15 -4 Improved
No high-profile vulnerabilities No Change
No outdated base images ⚠️ ⚠️ No Change
No unapproved base images No Change
Supply chain attestations No Change
Packages and Vulnerabilities (47 package changes and 15 vulnerability changes)
  • ➖ 1 packages removed
  • ♾️ 46 packages changed
  • 337 packages unchanged
  • ✔️ 15 vulnerabilities removed
Changes for packages of type deb (35 changes)
Package Version
gluwa/creditcoin3:latest
Version
gluwa/creditcoin3:latest
♾️ base-files 14ubuntu6.1 14ubuntu6.2
♾️ bsdutils 1:2.41.3-3ubuntu2 1:2.41.3-3ubuntu2.2
♾️ curl 8.18.0-1ubuntu2.3 8.18.0-1ubuntu2.5
♾️ diffutils 1:3.12-1 1:3.12-1ubuntu0.1
♾️ gnu-coreutils 9.7-3ubuntu2 9.7-3ubuntu2.1
♾️ gpgv 2.4.8-4ubuntu3 2.4.8-4ubuntu3.1
♾️ libattr1 1:2.5.2-4 1:2.5.2-4ubuntu0.1
♾️ libaudit-common 1:4.1.2-1build1 1:4.1.2-1ubuntu0.1
♾️ libaudit1 1:4.1.2-1build1 1:4.1.2-1ubuntu0.1
♾️ libblkid1 2.41.3-3ubuntu2 2.41.3-3ubuntu2.2
♾️ libbz2-1.0 1.0.8-6build2 1.0.8-6ubuntu0.1
♾️ libc-bin 2.43-2ubuntu2.3 2.43-2ubuntu2.4
♾️ libc-gconv-modules-extra 2.43-2ubuntu2.3 2.43-2ubuntu2.4
♾️ libc6 2.43-2ubuntu2.3 2.43-2ubuntu2.4
♾️ libcurl4t64 8.18.0-1ubuntu2.3 8.18.0-1ubuntu2.5
♾️ libgcrypt20 1.12.0-2ubuntu1 1.12.0-2ubuntu1.1
♾️ libmount1 2.41.3-3ubuntu2 2.41.3-3ubuntu2.2
♾️ libpam-modules 1.7.0-5ubuntu3.1 1.7.0-5ubuntu3.2
♾️ libpam-modules-bin 1.7.0-5ubuntu3.1 1.7.0-5ubuntu3.2
♾️ libpam-runtime 1.7.0-5ubuntu3.1 1.7.0-5ubuntu3.2
♾️ libpam0g 1.7.0-5ubuntu3.1 1.7.0-5ubuntu3.2
♾️ libpq5 18.4-0ubuntu0.26.04.1 18.6-0ubuntu0.26.04.1
♾️ libsmartcols1 2.41.3-3ubuntu2 2.41.3-3ubuntu2.2
♾️ libssh2-1t64 1.11.1-1ubuntu0.26.04.3 1.11.1-1ubuntu0.26.04.4
♾️ libssl3t64 3.5.5-1ubuntu3.3 3.5.5-1ubuntu3.5
♾️ libsystemd0 259.5-0ubuntu3.3 259.5-0ubuntu3.4
♾️ libudev1 259.5-0ubuntu3.3 259.5-0ubuntu3.4
♾️ libuuid1 2.41.3-3ubuntu2 2.41.3-3ubuntu2.2
♾️ login 1:4.16.0-2+really2.41.3-3ubuntu2 1:4.16.0-2+really2.41.3-3ubuntu2.2
♾️ mount 2.41.3-3ubuntu2 2.41.3-3ubuntu2.2
♾️ openssl 3.5.5-1ubuntu3.3 3.5.5-1ubuntu3.5
♾️ openssl-provider-legacy 3.5.5-1ubuntu3.3 3.5.5-1ubuntu3.5
♾️ perl-base 5.40.1-7ubuntu0.1 5.40.1-7ubuntu0.3
♾️ util-linux 2.41.3-3ubuntu2 2.41.3-3ubuntu2.2
♾️ zlib1g 1:1.3.dfsg+really1.3.1-1ubuntu3 1:1.3.dfsg+really1.3.1-1ubuntu3.1
Changes for packages of type golang (6 changes)
Package Version
gluwa/creditcoin3:latest
Version
gluwa/creditcoin3:latest
♾️ github.com/canonical/pebble 1.31.1-0.20260528050051-33f10658d3fd 1.32.2-0.20260721212935-faa1696b477d
♾️ github.com/gorilla/websocket 1.5.1 1.5.3
critical: 0 high: 0 medium: 1 low: 0
Removed vulnerabilities (1):
  • medium : GHSA--w67g--5rqw--f597
golang.org/x/net 0.40.0
critical: 1 high: 2 medium: 7 low: 0
Removed vulnerabilities (10):
  • critical : CVE--2026--39821
  • high : CVE--2026--46600
  • high : CVE--2026--33814
  • medium : CVE--2026--25680
  • medium : CVE--2026--42506
  • medium : CVE--2026--42502
  • medium : CVE--2026--27136
  • medium : CVE--2026--25681
  • medium : CVE--2025--58190
  • medium : CVE--2025--47911
♾️ golang.org/x/sys 0.33.0 0.46.0
critical: 0 high: 0 medium: 0 low: 1
Removed vulnerabilities (1):
  • low : CVE--2026--39824
♾️ golang.org/x/term 0.32.0 0.44.0
♾️ stdlib 1.26.3 1.26.5
critical: 1 high: 6 medium: 4 low: 0 unspecified: 2 critical: 1 high: 5 medium: 2 low: 0
Removed vulnerabilities (5):
  • high : CVE--2026--42504
  • medium : CVE--2026--27145
  • medium : CVE--2026--42507
  • unspecified : CVE--2026--42505
  • unspecified : CVE--2026--39822
Changes for packages of type npm (6 changes)
Package Version
gluwa/creditcoin3:latest
Version
gluwa/creditcoin3:latest
♾️ @types/node 26.1.2 22.7.5
♾️ node-gyp 13.0.1 13.0.2
♾️ picomatch 4.0.5 4.0.7
♾️ undici 8.10.0 8.10.2
♾️ undici-types 8.3.0 6.21.0
♾️ ws 8.21.2 8.21.3

… source node's block tags

The existing maturity strategies are all fixed block offsets: `EvmSafe` and
`EvmFinalized` are the Ethereum-epoch approximations (32 / 64 blocks) and mean
64 s / 128 s on a 2 s rollup, where they say nothing about L1 posting. A fixed
count also cannot follow a stalled batcher.

This adds two on-chain strategy strings, `RpcSafe` and `RpcFinalized`, that the
off-chain components resolve through `eth_getBlockByNumber("safe" | "finalized")`
on the source node. On Ethereum that tracks justification / finality; on OP-Stack
and Arbitrum rollups it tracks L1 batch inclusion / L1 finality. The existing
strategies keep their exact behaviour, so no live chain changes schedule.

- primitives: `MaturityStrategy::{RpcSafe, RpcFinalized}`, `RpcBlockTag`,
  `rpc_tag()`; pallet validator accepts the new strings (runtime wasm changes,
  no spec bump here).
- eth: `Maturity { FixedLag, Tag }` with `mature_height`, and
  `Client::get_block_number_by_tag` walking fallback providers like block fetches.
- streams: tip and roots streams take `maturity` instead of `finalization_lag`
  and resolve it per head; the roots stream fetches the whole newly mature range
  so a `safe` head that jumps by a batch is handled.
- attestor / archiver: resolve the on-chain strategy via
  `stream_eth::maturity_from_strategy`.
- continuity / proof-gen: `confirmation_tag` makes the prover confirm blocks on
  the same boundary the attestors attest on; the not-confirmed error reports the
  effective window.

Verified with mock-RPC tests and live on Base Sepolia (Chainstack): attested
heights stayed 2-12 blocks below the node's `safe` head and never above it,
advancing in bursts as batches posted to L1.
…d provider

`ArchiverEthProvider` forwards every live-node call to its ETH fallback but
inherited the erroring default for `get_block_number_by_tag`, so a proof server
configured with an `archiver_url` on an `RpcSafe` / `RpcFinalized` chain would
fail `get_confirmed_last_block`. Forward it like `get_last_block`, teach the mock
provider fixed `safe` / `finalized` heights, and cover both the tag-based
confirmed tip and the archiver forwarding with tests.
…econnect on an unserved tag

Review follow-ups (#1330):

- proof-gen: `block_confirmation_depth` pinned in config while the on-chain
  MaturityStrategy is RpcSafe/RpcFinalized now fails startup instead of
  warning. A fixed depth cannot reproduce a tag schedule, so the prover would
  confirm blocks the attestors have not attested. Depth-vs-depth
  disagreements keep the existing WARN.

- continuity: `get_block_number_by_tag` preserves the typed
  `FailedToGetBlockByTag` cause (was stringified) and `run()` returns it
  without the reconnect-and-retry loop: a node answering `null` for a tag is
  a permanent property of that node, and reconnecting only churned the shared
  client for every other in-flight request. Classifier
  `eth::anyhow_chain_is_unsupported_block_tag` with tests.
…ne fetched

First step of making the attestor the maturity authority: before anything
starts following its boundary, its own source reads have to be internally
consistent.

get_block and get_block_receipts are two separate height-keyed calls, and a
provider URL is commonly a load balancer over many nodes, so the pair can be
answered by peers on opposite sides of a reorg. Today that is inferred
indirectly, and only sometimes: try_from_fetched_block recomputes the
transaction and receipt roots and compares them with the header, which
detects the mismatch for blocks that have transactions but skips the check
entirely for empty blocks, and reports it as BlockHeaderRootsMismatch, a
root that failed to reproduce rather than the actual fault.

Receipts already carry the hash of the block they belong to. Comparing it
with the fetched block's hash is exact, costs no extra round trip, and names
the real problem. New Error::ReceiptsBlockMismatch is classified with the
other payload inconsistencies, so it walks to the next provider rather than
triggering a reconnect, matching how the root mismatch is handled today.

Receipts whose block_hash is absent are skipped rather than rejected: the
field is optional in the RPC schema and some providers omit it, and those
payloads still face the root check exactly as before.

Tests: mismatched hashes are rejected and classify for the fallback walk;
matching hashes get past the check; an absent block_hash is treated as
unverifiable rather than a mismatch; the empty-block carve-out is unchanged.
@DylanVerstraete
DylanVerstraete force-pushed the feat/hash-pinned-source-reads branch from 77d81fa to 21cb372 Compare September 16, 2026 08:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants