72 Commits

Author SHA1 Message Date
moudyellaz
124bbee6c6 Merge origin/dev 2026-07-23 23:59:36 +02:00
erhant
8d09ffd733 feat(sequencer): two-tier chain state and multi-sequencer support
Decentralized-sequencing foundation: a shared chain_state crate (two-tier
head/final ChainState, apply_block, AcceptOutcome, StallReason, and the
absorbed channel-consistency machinery), turn-gated block production, the
publisher follow path for adopted/orphaned/finalized peer blocks, and
persistence that keeps disk order equal to apply order under the chain lock.

Rebased onto dev after #600/#606: chain_consistency is absorbed into
chain_state, the sequencer bootstrap's verify_and_reconstruct is re-wired
onto the two-tier ChainState (reconstruction applies channel history
through the final tier and persists via the follow-path primitives), and
test fixtures adopt the SequencerSetup builder extended with
with_bedrock_signing_key.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-23 11:43:57 +03:00
moudyellaz
72195ce09e Merge origin/dev 2026-07-23 02:43:53 +02:00
Daniil Polyakov
e3442c695f fix(sequencer): fix silent reconstruction when only genesis was committed 2026-07-21 22:46:47 +03:00
Daniil Polyakov
2d5489c04e feat(sequencer): bootstrap state from Bedrock 2026-07-21 22:46:25 +03:00
moudyellaz
f4a5d85c65 refactor(cross-zone): seed cross-zone config via genesis transactions 2026-07-21 15:19:16 +02:00
moudyellaz
a806ebb94a refactor(cross-zone)!: register cross-zone programs as base builtins
BREAKING CHANGE: GenesisAction::DeployProgram and IndexerConfig.deploy_programs are removed. The cross-zone programs (inbox, outbox, ping_sender, ping_receiver, bridge_lock, wrapped_token) are now base builtins in testnet_initial_state, because program bytecode exceeds the genesis block inscription limit, so they cannot be shipped through genesis transactions.
2026-07-21 10:50:41 +02:00
moudyellaz
9380198eb9 refactor(cross-zone): use the Balance alias for holding amounts and debug-log skipped replays 2026-07-16 12:44:36 +02:00
moudyellaz
fea373e317 fix(indexer): record cross-zone dispatch keys as seen only after the block applies
verify_block populated the seen-set before accept_block, so a dispatch verified in a block that then parked poisoned seen without the inbox ever recording the key on chain, letting a later forged dispatch reuse the key to skip re-derivation. verify_block now returns the verified keys and the ingest loop records them via record_seen only on AcceptOutcome::Applied, so seen mirrors the inbox's on-chain seen-shard.
2026-07-14 21:38:50 +02:00
moudyellaz
a16e22c46c refactor!(cross-zone): deploy programs at genesis instead of builtins
Cross-zone builtin programs are no longer registered in the production
genesis. A zone that participates declares the ones it uses via a new
GenesisAction::DeployProgram (sequencer) and a matching deploy_programs
list (indexer), both resolved through CrossZoneProgram and registered
with with_programs. Cross-zone genesis accounts (inbox config,
wrapped-token config) are seeded through the state constructor for a
receiving zone, and bridge-lock holdings are seeded from their actions
regardless of receiving config, dropping V03State::insert_genesis_account.
GenesisAction amounts now use the Balance alias. Documents cross_zone as
the reference LEZ adapter and the bridge demo as not production-safe.

The sequencer's DeployProgram set and the indexer's deploy_programs are
configured separately, so both nodes now log a deterministic genesis
fingerprint (V03State::genesis_fingerprint) at startup: equal values
confirm the two genesis states agree, a mismatch flags a divergent
deploy set.

BREAKING CHANGE: the genesis state root changes (cross-zone builtins are
out of production genesis) and the sequencer/indexer configs gain the
DeployProgram / deploy_programs list that cross-zone-participating zones
must set.
2026-07-13 19:12:24 +02:00
moudyellaz
de2dc8e04d fix(indexer): accept a replayed cross-zone dispatch instead of halting
The Option B verifier returned Err on a cross-zone dispatch whose message key
was already in its seen set, and that halts indexer ingestion. A legitimate
re-delivery, for example after a sequencer restart re-injects, could then
permanently stall an honest indexer. The inbox already treats a re-delivered
message as an idempotent no-op on chain, so the verifier now continues past an
already-seen key instead of bailing. Forgery detection on first-seen dispatches
is unchanged.

Also notes that one pinned block-signing key per peer is sufficient until
decentralized sequencing, and strengthens the replay test so it only passes via
the seen-key short-circuit.
2026-07-13 11:06:49 +02:00
moudyellaz
eff31df9ce Merge origin/dev 2026-07-11 01:12:00 +02:00
erhant
ce37428e1e fix(indexer): handle park_undeserializable errors properly 2026-07-10 18:35:01 +03:00
erhant
d22f8b540b refactor(indexer): make put_block own the breakpoint schedule
`RISC0_DEV_MODE=1 RISC0_SKIP_BUILD=1 cargo test -p storage -p indexer_core`
2026-07-10 18:35:01 +03:00
erhant
280885532b refactor(indexer): rename AcceptOutcome::ApplyFailed to RetryableFailure 2026-07-10 18:35:01 +03:00
erhant
9587cf96be refactor(indexer): remove now-redundant last_breakpoint_id meta cell 2026-07-10 18:35:01 +03:00
erhant
2e49cdfd9c fix(indexer): harden stall durability and breakpoint guards w.r.t. Copilot review 2026-07-10 18:35:01 +03:00
erhant
ff6d40f4df fix(indexer): retry apply failures before parking 2026-07-10 18:35:01 +03:00
erhant
07eaf1021a fix(indexer): do not park immediately on possibly-transient apply failures 2026-07-10 18:35:01 +03:00
erhant
ed6a3f56dd fix(indexer): snapshot breakpoint state from the validated scratch state 2026-07-10 18:35:01 +03:00
erhant
93c311be3b fix(indexer): initial prep for breakpoint fix 2026-07-10 18:35:01 +03:00
erhant
88736d7421 fix(indexer): keep track of L1 slot of last inscription for correct tracking 2026-07-10 18:35:01 +03:00
erhant
f99d7fef59 chore: clippy docfix + bump crossbeam-epoch (RUSTSEC-2026-0204) 2026-07-10 18:35:01 +03:00
erhant
025105b570 fix(indexer): allow recovery from parked-and-stalled store (w.r.t Copilot review)
refactor(indexer): move chain-consistency code within a dedicated file
2026-07-10 18:35:01 +03:00
erhant
1ca3de47b9 chore: docfix w.r.t Copilot 2026-07-10 18:35:00 +03:00
erhant
2c395b95a6 chore: fix typos, enable ignored test 2026-07-10 18:35:00 +03:00
erhant
f563f675ac fix(indexer): tend to @schouhy reviews, allow re-applied old blocks 2026-07-10 18:35:00 +03:00
erhant
0985df9059 chore: typo fix ChainConsistency [skip ci] 2026-07-10 18:35:00 +03:00
erhant
16888478dd refactor(indexer): tend to several reviews by @schouhy 2026-07-10 18:35:00 +03:00
erhant
82a16f1ab7 fix(indexer): use better error types, tend to few @Arjentix PR review 2026-07-10 18:35:00 +03:00
erhant
f94a63d8cf fix(indexer)!: address several reviews, use better return types with conversions, some docfixes
BREAKING CHANGE: dropping the serde rename attrs changes the FFI
`query_status` JSON: `state` values are now variant-cased
(`caught_up` -> `CaughtUp`) and fields snake_case
(`indexedBlockId` -> `indexed_block_id`, `lastError` -> `last_error`).
Consumers (lez-indexer-module, lez-explorer-ui) must update their parsing.
2026-07-10 18:35:00 +03:00
erhant
da95e86083 chore: very small comment about future fix [skip ci] 2026-07-10 18:35:00 +03:00
erhant
b5ed8548d5 fix(indexer): catch the edge case of re-using the last valid tip on restart 2026-07-10 18:35:00 +03:00
erhant
255a94c8ed fix(indexer): attend to copilot comments, rm Store error from a park case 2026-07-10 18:35:00 +03:00
erhant
aceb863ff2 chore: rm redundant unit test [skip ci] 2026-07-10 18:35:00 +03:00
erhant
db48877ca6 fix(indexer): run the chain-identity check even when the store is parked 2026-07-10 18:35:00 +03:00
erhant
2b5379a0c7 fix(indexer): run the chain-identity check even when the store is parked 2026-07-10 18:35:00 +03:00
erhant
66434256da fix(indexer): detect chain reset via anchor block, **not** deterministic genesis
test `RISC0_DEV_MODE=1 RISC0_SKIP_BUILD=1 cargo test -p indexer_core`
2026-07-10 18:35:00 +03:00
erhant
b989974f90 chore: greatly increase timeout 2026-07-10 18:35:00 +03:00
erhant
aa46b69b79 feat(indexer): add startup genesis-consistency check
test `RISC0_DEV_MODE=1 RISC0_SKIP_BUILD=1 cargo test -p indexer_core`
2026-07-10 18:35:00 +03:00
erhant
a583c1f21a test(indexer): cover stall recovery and full StallReason roundtrip
test `RISC0_DEV_MODE=1 RISC0_SKIP_BUILD=1 cargo test -p indexer_core`
2026-07-10 18:35:00 +03:00
erhant
b71b01f94b chore: fix linter 2026-07-10 18:35:00 +03:00
erhant
de55d2699b feat(indexer): park ingest loop on bad blocks instead of skipping
`RISC0_DEV_MODE=1 RISC0_SKIP_BUILD=1 cargo test -p indexer_core`
2026-07-10 18:35:00 +03:00
erhant
c49cc7bc29 refactor(indexer): use "stall reason" instead of "chain breaker" 2026-07-10 18:35:00 +03:00
erhant
e28cceffab feat(indexer): add Stalled status and chain breaker snapshot
test `RISC0_DEV_MODE=1 RISC0_SKIP_BUILD=1 cargo test -p indexer_core --lib status`
2026-07-10 18:35:00 +03:00
erhant
6ab6455482 feat(indexer): add accept_block with chain-linkage check and atomic apply
test `RISC0_DEV_MODE=1 RISC0_SKIP_BUILD=1 cargo test -p indexer_core --lib accept_tests`
2026-07-10 18:35:00 +03:00
erhant
5b2c387fe9 feat(indexer): persist ChainBreaker in RocksDB meta
test `RISC0_DEV_MODE=1 RISC0_SKIP_BUILD=1 cargo test -p storage -p indexer_core --lib chain_breaker`
2026-07-10 18:35:00 +03:00
erhant
60265ed438 feat(indexer): add BlockIngestError enum, fix linting 2026-07-10 18:35:00 +03:00
erhant
03f92abbcf refactor(indexer): rename execute_on_state and drop indexer-side tx checks
test with:
RISC0_DEV_MODE=1 RISC0_SKIP_BUILD=1 cargo test -p common -p storage -p indexer_core
2026-07-10 18:35:00 +03:00
Artem Gureev
1b4d8fbcf4
Merge pull request #550 from logos-blockchain/artem/viewing-key-binding
feat!: viewing key and ciphertext binding
2026-07-08 20:17:37 +04:00