Skip to content

Make rollback point-aware for Byron EBB and same-slot successor blocks #89

Description

@satran004

Problem

Yano receives rollback targets as a ChainSync Point containing both slot and hash, but parts of the rollback path currently reduce that point to a slot:

  • DirectRocksDBChainState.rollbackTo(Long slot) resolves the canonical entry using slot-based mappings.
  • DefaultUtxoStore.rollbackTo(RollbackEvent) retains the first delta satisfying delta.slot() <= targetSlot and does not compare the target hash.

This is ambiguous at a Byron epoch boundary:

preceding main:  block N,   slot < S
EBB:             block N,   slot S
successor main:  block N+1, slot S

The EBB shares its block number with its predecessor and its slot with its successor. After the successor main block has been applied, rollback to the EBB at slot S must remove successor state at S. Slot-only rollback can instead retain the successor or resolve its hash.

This can also affect post-store compensation: if application of the successor main block fails, tipBeforeStore can be the same-slot EBB and compensation must restore that exact point.

Ouroboros Consensus models non-genesis points as (slot, headerHash) and matches the complete point during header and ledger rewind. Yano should preserve the same identity through its rollback pipeline.

Proposed scope

  • Add a point-aware ChainState rollback API, for example rollbackTo(Point), and propagate the ChainSync target hash instead of discarding it.

  • Distinguish an EBB from the regular block at the same slot using the existing EBB and main-block indexes.

  • Update DefaultUtxoStore.rollbackTo so a delta is retained only when:

    delta.slot < target.slot
        or
    delta.slot == target.slot && delta.blockHash == target.hash
    
  • Reverse a same-slot delta whose hash differs from the target hash.

  • Require a hash for non-origin canonical rollback points. Fail closed when an equal-slot delta lacks sufficient hash identity.

  • Audit other rollback-capable stores and compensation/reconciliation callers to ensure none silently reduce an exact point to slot-only identity.

  • Preserve or deliberately deprecate the slot-only ChainState API after callers migrate.

No RocksDB schema or index migration is expected: UTXO deltas already store the block hash, and ChainState already stores EBB hashes separately from main-block slot mappings.

Acceptance criteria

  • Rollback to main N retains its matching delta and point.
  • Given main N -> EBB N -> main N+1, rollback to the EBB removes state from main N+1 and restores the exact EBB ChainState tip.
  • Rollback to main N+1 at the same slot retains its matching-hash delta.
  • A same-slot hash mismatch is never accepted as the target point.
  • Post-store compensation from the successor main block to the preceding EBB completes at the exact expected hash.
  • Origin rollback remains correct.
  • Existing current-era rollback behavior remains unchanged for ordinary distinct-slot points.
  • Direct RocksDB and in-memory ChainState implementations have equivalent point-aware behavior.
  • Tests cover missing target hashes and legacy/malformed deltas without hashes and verify fail-closed behavior.

Context

Proposed ADR-041 now includes exact point-aware rollback as part of the Byron main-block UTXO application decision. This issue tracks the ChainState, UTXO, compensation, and rollback-audit portion of that ADR so the same-slot EBB recovery behavior is implemented and verified with the feature.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions