Ethereum 노드는 블록 안 거래들을 무조건 한 줄로 처리하지 않고, 미리 공개된 접근 목록을 단서로 삼아 안전 조건이 갖춰진 블록에서 병렬 처리를 시도하게 됐다.
블록은 여러 거래의 묶음이다. 거래 A가 어떤 계정의 잔액을 바꾸고 거래 B가 바로 그 잔액을 읽을 수 있으므로, 전통적으로 노드는 거래를 순서대로 실행한다. 이 방식은 결과가 명확하지만 CPU 코어를 많이 활용하기 어렵다.
BAL(Block Access List)은 블록 전체가 읽거나 쓸 계정·저장소 위치를 나타내는 목록이다. 이 목록이 정확하다면 서로 충돌하지 않는 거래를 나눠 실행하거나, 필요한 상태를 미리 읽어 올 수 있다. 다만 병렬 결과가 순차 실행 결과와 단 한 비트라도 달라지면 합의 오류가 된다.
Geth는 2026-07-28 13:17 UTC에 Amsterdam 이후 BAL을 가진 블록에 대해
supportsParallelExecution(...) 조건을 통과할 때 병렬 처리 경로를 선택하도록
구현했다. 추적기(tracer)가 켜졌거나 운영자가 병렬 실행을 끄면 기존 순차 경로를
사용한다. 테스트는 병렬·순차 실행의 state root, receipts, gas, 재생성 BAL과
requests hash가 같은지 비교한다.
출처: https://github.com/ethereum/go-ethereum/commit/454ca784c5aa2129ff5c9d168c4bf66fc4283d02
아래는 실제 diff의 제어 흐름을 단순화한 의사코드다.
기존 방식
state = open(parentState)
if prefetchEnabled:
backgroundPrefetch(all transactions)
execute transactions in order on state
변경 방식
if block has BAL and parallel execution is supported:
reader = sharedCache + prefetch(block.accessList, CPU cores)
state = openWith(reader)
execute through BAL-driven parallel processor
else:
use the existing sequential path
assert(parallel.stateRoot == committedBlock.stateRoot)
assert(parallel.receipts == sequential.receipts)
노드 운영자에게는 블록 처리량을 높일 수 있는 길이 열리지만, 이는 “더 빨리 실행한다”보다 “합의 결과는 기존과 완전히 같다”가 먼저인 기능이다. 그래서 코드가 병렬 경로의 활성 조건을 좁게 두고, 순차 경로와의 동등성 테스트를 함께 추가한 점이 중요하다. 사용자는 간접적으로 더 많은 활동을 처리할 수 있는 기반의 혜택을 받을 수 있지만, 이 커밋만으로 특정 처리량 향상을 단정할 수는 없다.
쉬운 비유
한 명의 계산원이 영수증을 전부 처리하던 매장에서, 어떤 장바구니가 서로 다른 진열대만 건드린다는 목록을 확인한 뒤에만 여러 계산대를 동시에 여는 것과 비슷하다.
이는 실행 레이어의 확장성 흐름이다. L2만 빨라지는 것이 아니라, L1 실행 클라이언트도 접근 패턴을 명시하고 이를 검증 가능한 방식으로 활용해 다중 코어를 쓰려 한다. 중요한 제약은 성능 최적화가 합의 규칙을 바꾸거나 결과를 달리해서는 안 된다는 점이다.