OP Stack은 오래된 시퀀서 빌드 작업을 시작 전에 버리도록 고쳤다

Optimism의 op-node는 이미 더 최신 블록을 알고 있는데도, 이전 블록을 부모로 삼은 새 블록 생성 요청이 뒤늦게 도착하면 그 작업을 실행하지 않고 현재 상태에서 다시 시작하도록 바꿨다.

L2의 시퀀서는 사용자의 거래를 모아 새 L2 블록을 만든다. 블록은 항상 직전 블록을 부모로 삼아 이어져야 한다. 그런데 네트워크 지연이나 상태 갱신 순서 때문에, 시퀀서가 이미 블록 101을 알고 있는 상황에서 “블록 100 위에 다음 블록을 만들어라”는 오래된 요청이 도착할 수 있다.

이 요청을 그대로 처리하면 존재하지 않거나 이미 버려진 가지(orphaned parent)를 기준으로 블록을 만들려 시도한다. 결국 엔진 오류, 불필요한 재시도, 상태 혼동으로 이어질 수 있다.

이번 변경은 무엇인가

2026-07-27 21:02 UTC에 반영된 변경이다. op-node는 시퀀서가 시작한 빌드 요청이 현재 unsafeHead와 다른 부모를 가리키면 이를 stale(오래된) 요청으로 기록하고, 실행 엔진에 블록 생성을 요청하지 않는다. 대신 현재 unsafe head를 기준으로 forkchoice update를 다시 보낸다.

코드/구조에서는 어떤 차이인가

실제 Go diff를 읽기 쉽게 줄인 의사코드다.

  // 이전: 요청이 오면 엔진에 빌드를 맡김
  engine.build(attributes.parent)

  // 변경: 현재 상태와 부모가 맞는지 먼저 확인
  if !attributes.isDerived && attributes.parent != unsafeHead {
      log("stale build start")
      requestForkchoiceUpdate(unsafeHead)
      return
  }
  engine.build(attributes.parent)

unsafeHead는 아직 L1에서 확정되지는 않았지만 op-node가 현재 가장 앞선 것으로 보고 있는 L2 블록이다. 테스트도 오래된 부모를 넣었을 때 엔진의 빌드 시도가 0회이고, forkchoice update만 발생하는지 확인한다.

왜 이것이 중요한가

롤업은 거래 처리량뿐 아니라 상태 전환의 순서가 맞아야 한다. 이미 폐기된 부모를 기준으로 빌드를 시작하면 최종 블록이 틀리지는 않더라도, 운영 중인 노드가 불필요한 오류와 재시도에 흔들릴 수 있다. 이번 변경은 잘못된 작업을 “실패한 뒤 정리”하는 대신 “시작하기 전 거절”하는 방식이다.

쉬운 비유

문서의 최신본이 11판인데, 누군가 10판을 기반으로 수정본을 만들라는 지시를 늦게 보낸 상황과 같다. 수정 작업을 시작한 뒤 충돌을 해결하는 대신, 처음부터 최신본을 기준으로 다시 지시한다.

블록체인 발전 흐름에서의 의미

L2의 신뢰성은 증명 시스템만으로 결정되지 않는다. 시퀀서·노드·실행 엔진 사이의 이벤트 순서와 복구 로직도 실제 운영 품질을 만든다. 롤업이 서비스 인프라가 될수록 이런 상태 머신 안전장치가 중요해진다.

OpenZeppelin은 잘못된 멀티서명 입력을 revert 대신 ‘유효하지 않음’으로 처리한다

멀티서명 지갑이 깨진 형식의 서명 데이터를 받았을 때 계약 전체가 revert하지 않고, 서명이 유효하지 않다는 false를 반환하도록 바꿨다.

멀티서명은 한 사람의 서명 대신 여러 서명자의 동의가 있어야 거래를 승인하는 방식이다. 계정 추상화(ERC-4337) 환경에서는 paymaster나 account가 서명 검증 결과를 보고 “이 요청을 처리할 수 있는가”를 판단한다.

기존 코드의 abi.decode(signature, (bytes[], bytes[]))는 입력 바이트의 형식이 깨졌을 때 revert할 수 있다. 즉, 단지 틀린 서명이 들어왔을 뿐인데 검증 함수가 정상적인 실패값을 돌려주지 못하고 실행 자체를 중단한다.

이번 변경은 무엇인가