Skip to content

feat: harden indexing for production v1 - #1

Open
ozcnii wants to merge 1 commit into
melonges:masterfrom
ozcnii:feat/production-v1
Open

feat: harden indexing for production v1#1
ozcnii wants to merge 1 commit into
melonges:masterfrom
ozcnii:feat/production-v1

Conversation

@ozcnii

@ozcnii ozcnii commented Aug 28, 2026

Copy link
Copy Markdown

Summary

  • add canonical/provisional/finalized block lifecycle with bounded reorg rollback and promotion for PostgreSQL and MongoDB
  • validate block identity across RPC, decoding, cache, and atomic storage commits
  • protect the API with bearer auth, SSRF-safe RPC validation, strict CORS defaults, bounded queries, liveness/readiness, and worker status metrics
  • add production Compose/Helm deployment, encrypted PostgreSQL backup/restore tooling, MongoDB restore runbook, monitoring, CI, and release metadata for v1.0.0

Verification

  • cargo fmt --all -- --check
  • clippy, tests, and release builds for PostgreSQL, PostgreSQL+webhook, MongoDB, and MongoDB+webhook
  • MongoDB ignored Compose integration test
  • production Compose config, Helm lint/template policy checks, scripts, dashboard JSON, CI YAML, secret scan, and git diff --check

Operational follow-up

Before production rollout, revoke/rotate historical credentials, complete an encrypted off-host backup/restore drill with measured RPO/RTO, and configure ingress/TLS/rate-limit/egress policy.

@ozcnii
ozcnii force-pushed the feat/production-v1 branch from ae5116d to 08c18fb Compare August 28, 2026 20:22
@melonges

melonges commented Aug 29, 2026

Copy link
Copy Markdown
Owner

I reviewed the commit with a focus on reorg handling, finality promotion, storage invariants, RPC hardening, and API security.

Overall, I like the direction and the new canonical block model is a significant improvement. However, I found a few issues I would address before merging:

High

1. Canonical parent/child relationship is not enforced

commit_block() validates that an existing block at the same height has the same hash/parent, but it does not verify that:

block.parent_hash == canonical_blocks(block_number - 1).block_hash

This means a newly inserted block can theoretically become part of the canonical ledger without being connected to the previous canonical block.

I would enforce this invariant transactionally in both PostgreSQL and MongoDB.

2. Finalized sink delivery has a crash window

promote_finalized() marks results as finalized and commits the transaction before the sink batches are actually submitted.

So this sequence is possible:

  1. DB transaction commits finalized
  2. process crashes
  3. sink batch is never delivered
  4. on restart the block is no longer provisional, so it won't be reconstructed again

This gives us a potential lost finalized event. I think finalized sink delivery needs a durable outbox / delivery state with retry semantics.

Medium

3. Rollback is height-based rather than block-identity-based

Both adapters delete results using:

block_number > ancestor

Now that result identity includes block_hash, I would prefer rollback to explicitly identify and remove the orphaned block hashes. This makes the fork handling much more robust and less dependent on implicit canonical invariants.

4. promote_finalized(finalized_head) is semantically confusing

The worker passes promotion_height, which already incorporates CONFIRMATION_DEPTH, but the storage API calls the argument finalized_head.

I'd rename this to promotion_height throughout the storage layer to avoid accidentally passing the raw RPC finalized height in the future.

5. MongoDB is missing the equivalent promotion index

Promotion queries:

chain_id + finality + block_number

Postgres has an index for this, but MongoDB appears to only index (chain_id, block_number) and (chain_id, block_hash). I would add a matching compound index.

Minor

  • Consider enforcing a minimum API token length/entropy rather than only checking that it is non-empty.
  • Swagger/OpenAPI is currently unauthenticated. That's probably acceptable, but it would be worth making this an explicit production decision.
  • Add a regression test for DNS rebinding / changing DNS resolution between validation and subsequent requests.
  • The 0.8 → 1.0 migration is effectively reset/reindex for existing data; I would make that breaking migration requirement very explicit in the release documentation.

Positive notes

The following parts look particularly good:

  • Explicit BlockMetadata with block hash + parent hash.
  • Receipt validation against both block number and block hash.
  • Fail-closed Blocked state for reorgs crossing finalized data.
  • Moving sink delivery from provisional commits to finalized promotion.
  • API authentication, body-size limits, CORS hardening.
  • CI coverage across Postgres/MongoDB and webhook/non-webhook builds.

So overall: strong architectural direction, but I would fix the canonical-chain invariant and finalized sink delivery semantics before merging.

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