Skip to content

spec 1.7.0 alpha.5 + BAL UI#648

Merged
pk910 merged 61 commits intomasterfrom
pk910/spec-1.7.0-alpha.5
Apr 21, 2026
Merged

spec 1.7.0 alpha.5 + BAL UI#648
pk910 merged 61 commits intomasterfrom
pk910/spec-1.7.0-alpha.5

Conversation

@pk910
Copy link
Copy Markdown
Member

@pk910 pk910 commented Apr 20, 2026

Gloas v1.7.0-alpha.5 spec + Block Access List UI

Brings dora in line with consensus-specs v1.7.0-alpha.5 and ports the EIP-7928 Block Access List UI forward onto the new spec shape.

Why

The alpha.4 → alpha.5 Gloas spec drops the double state transition entirely. Payload envelopes no longer drive a state transition; every state change flows through the consensus block, which processes the parent payload's execution requests at the start of process_block. This is a substantial simplification (fork-choice no longer tracks per-payload states, envelopes lose their slot/state_root commitments, etc.) and our replay/indexer machinery needs to follow.

Separately, the alpha.5 release folds EIP-7928 (Block Access List) into the Gloas payload. We had a UI for BAL prepared on eip7928-support — that branch was pinned to a very old master and could not merge cleanly, so the UI is ported forward instead and wired to the new gloas.ExecutionPayload.BlockAccessList byte slice.

What changes

1. State transition — tracks spec alpha.5

The process_execution_payload state transition is gone. Instead, process_block now starts with process_parent_execution_payload, which consumes block.body.parent_execution_requests + state.latest_execution_payload_bid (still the parent's bid at that point) and applies the parent's deposits / withdrawal requests / consolidation requests, settles the parent's builder payment with epoch-aware indexing, and updates state.latest_block_hash.

indexer/beacon/statetransition:

  • Removed ApplyExecutionPayload, processExecutionPayload, IsPrePayloadState — payloads no longer transition state, so there is no "pre-payload" vs "post-payload" split.
  • Added processParentExecutionPayload and settleBuilderPayment. Called as the first step of applyBlock for Gloas+ states (before processBlockHeader, per spec order).
  • PrepareEpochPreState no longer takes a payload parameter; it just advances slots.
  • applyExecutionRequests extracted as a shared helper between processOperations (pre-Gloas) and processParentExecutionPayload (Gloas+); pre-Gloas guard added explicitly around the block.ExecutionRequests() path.
  • setAvailabilityBit now takes a slot (it's used for the parent slot from within processParentExecutionPayload).

indexer/beacon/epochstate.go:

  • The replay loop no longer has a "for Gloas: apply payload between blocks" branch. Each block's post-block HTR now already reflects the parent's payload (applied inside that block's processing), matching the block's header state_root — so the verification check is uniform across Fulu and Gloas.
  • API-fallback path drops the payload-lookup/pass to PrepareEpochPreState.

Net reduction of ~100 lines in statetransition code. No DB schema changes.

2. Block Access List UI (EIP-7928)

History-only merge commit (-s ours) of origin/eip7928-support preserves authorship for the original EIP-7928 contributor (Toni Wahrstätter / nerolation) and the subsequent UI work. No code is taken from the merge itself; the UI is re-applied on top of the current master state:

  • templates/slot/block_access_list.html — new, ~1980-line UI template rendering storage writes/reads, balance/nonce/code diffs, and a tx inspector/comparison modal.
  • templates/slot/slot.html + overview.html — new "Access List" tab and a BAL Hash row, nil-safe against pre-Gloas blocks.
  • utils/bal.go — RLP types and DecodeBlockAccessList.
  • utils/format.goIsSystemContract, GetSystemContractName, CalculateBalanceDiff helpers.
  • utils/templateFucs.go — registers the three new template funcs.
  • types/models.go + types/models/slot.goSystemContract + the SlotPageBlockAccessListEntry tree, plus SystemContracts / TransactionDetails / BlockAccessListHash / BlockAccessList fields on the slot page data.
  • handlers/slot.go:
    • Registers the new template.
    • ?action=parse-access-list endpoint for the UI's inspector (POSTed RLP → decoded JSON).
    • getSlotPageBlockData reads BAL bytes directly from executionPayload.Gloas.BlockAccessList, decodes via utils.DecodeBlockAccessList, and maps with convertBALToModel.
    • buildSlotPageData populates TransactionDetails and SystemContracts (from ChainService.GetSystemContractAddresses()).

3. BAL persistence in blockdb

The BAL is ephemeral on nodes (pruned after a few days), but we want to keep it forever in blockdb once seen. The blockdb already has separate BalVersion/BalData components and a write guard that only adds components the store doesn't have (newFlags &^ existingFlags) — a re-delivered payload with an empty BAL cannot overwrite a stored one.

Wiring added so the guard actually gets something to guard:

  • indexer/beacon/block_helper.go — new MarshalBlockAccessList / UnmarshalBlockAccessList with format version 1 and the shared compressionFlag. Empty input → (0, nil, nil) so StoredFlagsFromBlockData classifies it as absent.
  • indexer/beacon/block.go writeToBlockDb — now also persists the payload envelope and the BAL (extracted from block.executionPayload.Message.Payload.BlockAccessList). Previously only header+body were being written.
  • cmd/dora-utils/blockdb_sync.go — populates BalVersion/BalData from the fetched envelope.

Impact notes

  • ExecutionRequest slot attribution in state: because Gloas alpha.5 applies requests in the next block's process_parent_execution_payload, our PendingDeposits[].Slot for deposits delivered via a payload is now one slot higher than it was in alpha.4. This is a 1-slot cosmetic shift that does not affect the finalized-slot gate in epoch processing.
  • DB attribution of requests: unchanged. writedb.go continues to attribute deposits/withdrawal-requests/consolidation-requests to the block that delivered the payload (origin slot), sourced from the envelope. The spec's "orphaned = empty parent_execution_requests" signalling is equivalent to the existing "next bid's parent_block_hash" check, so payloadStatus semantics are preserved.
  • Payload is 1-to-0-or-1 per block: once a block's payload is stored we never replace it, so the "new data drops BAL → no update" rule that protects BAL also protects payload bytes.

Testing

  • go build ./... — clean.
  • go test ./... -count=1 — all packages pass.
  • golangci-lint run --new-from-rev=origin/master — 0 issues.

Credits

Block Access List UI originally contributed by @nerolation (EIP-7928 support, commit 57f111e9), with subsequent UI iteration on the eip7928-support branch. History preserved via -s ours merge commit 11766d69.

pk910 and others added 21 commits February 18, 2026 06:42
The eip7928-support branch introduced the Block Access List (EIP-7928)
UI and was based on an old base commit. A direct merge would create
large conflicts. Merging with -s ours retains the branch history and
authorship of prior contributors (notably Toni Wahrstätter @nerolation
for the initial EIP-7928 support) while leaving the working tree
unchanged. The BAL UI is ported forward as a separate follow-up
commit and wired to the Gloas v1.7.0-alpha.5 BlockAccessList type.
@pk910 pk910 added the build-docker-image Automatically build docker image for PR branch label Apr 21, 2026
@pk910 pk910 merged commit e81d2b6 into master Apr 21, 2026
14 checks passed
@pk910 pk910 deleted the pk910/spec-1.7.0-alpha.5 branch April 21, 2026 09:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

build-docker-image Automatically build docker image for PR branch

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants