devops

Optimism Derivation 파이프라인 본문

Layer2

Optimism Derivation 파이프라인

vata500 2023. 8. 17. 20:51
반응형

L2 옵티미즘의 derivation이 어떻게 진행되는지를 정리해보려고 한다. derivation은 L2 체인을 derive하기 위해서 L1으로 부터 L2 derivation input을 읽는 과정이다. 내가 이해한 바로는 L1으로부터 필요한 정보를 가져와 L2 체인을 실행과 운영에 활용하는 것이다.

https://github.com/ethereum-optimism/optimism/blob/develop/specs/derivation.md

이 과정이 필요한 이유는 Layer2는 Layer1의 보안에 의존하기 때문에 트랜잭션 실행부터 Layer1 calldata 전송의 비용과 Layer2의 비용 산정, Deposit과 Withdraw를 안정적으로 진행할 수 있기 때문이다.

Layer2라면 아주 중요한 파트 중 하나이며, 여기서 L2가 읽는 derivation input은 아래와 같다.

  • L1 block attributes(block number, timestamp, basefee)
  • deposits
  • sequencer batches
  • system configuration

여기서 batcher transaction은 batcher라는 노드에 의해서 데이터 가용성을 위해 제출된 트랜잭션이다. 이 트랜잭션은 하나 혹은 그 이상의 full frame을 전달하는데, 채널의 frame은 여러 배처 트랜잭션 간에 분할될 수 있다.

L2 derivation 파이프라인

이 파이프라인의 아키텍쳐는 다음과 같은 단계로 구성되어있다.

  1. L1 Traversal
  2. L1 Retrieval
  3. Frame Queue
  4. Channel Bank
  5. Channel Reader(Batch Decoding)
  6. Batch Queue
  7. Payload Attributes Derivation
  8. Engine Queue

데이터 플로우는 밖(시작)에서 부터 안(끝)으로 들어온다고 보면 된다. 여기서 밖은 L1, 안은 L2다. 재밌는 건 데이터의 주문은 반대로 진행된다. 이말은 즉슨, '마지막 스테이지에서 진행된 어떤 데이터가 있다면 그건 가장 먼저 처리된다는 것'이다.

공식문서에서는 외부(L1)에서 처리되기 전에 먼저 내부(L2)에서 가능한 많은 조치를 취한다고 되어 있는데, L2에서 L1에 calldata를 보낼 때 최대한 압축하는 것처럼 효율적인 처리가 가능한 내부에서 작업해야 대기시간과 비용을 줄일 수 있다고 보는 듯하다.

우선 Channel과 Frame에 대한 개념을 짚고가자.

Channel

채널은 압축된 sequencer batch의 순서를 말한다. 더나은 압축률을 얻고 데이터 가용성에 대한 비용을 절감하기 위해 그룹화한다고 보면 된다. 그리고 이 채널은 batch transaction 전송을 위해 프레임(frame)으로 분할 할 수 있다. 채널은 타임스탬프과 임의의 값으로 고유하게 식별된다.

Frame

프레임은 채널의 데이터 청크라고 보면 된다. Batcher 트랜잭션은 하나 이상의 프레임을 전송하는 것으로, 프레임으로 채널을 분할하면 채널이 너무 커서 단일 batcher transaction에 포함되지 않는 문제를 막을 수 있다.

1) L1 Traversal

L1 Traversal은 다음 L1 Block의 헤더를 읽어온다. 정상적인 작동에서는 새로운 L1 Block이 생성되지만 L1 re-org가 발생하면 이전 Block을 읽어올 수 도 있다.

2) L1 Retrieval

L1 Retrieval 단계에서는 외부(L1 Traversal)에서 가져온 블록을 읽고 여기서 데이터를 추출한다. 롤업은 각 트랜잭션에 대해서 블록의 batcher transactions으로 작동한다. 

  • 수신자는 batcher inbox 주소를 통해서 받는다.
  • 발신자는 반드시 L1 block과 매치되는 System config로부터 로드된 batcher 주소와 일치해야한다.

3) Frame Queue

프레임 큐는 한 번에 하나의 데이터 트랜잭션을 버퍼링하고 다음 단계에 사용할 채널 프레임으로 디코딩된다. 

4) Channel Bank

채널 뱅크 단계에서는 L1 Retrieval 단계에서 기록된 채널 뱅크의 버퍼링 관리를 담당한다. 

5) Channel Reader (디코딩)

채널 리더 단계에서는 가져온 채널의 압축을 풀고 풀린 바이트 스트림에서 batch를 구문 분석한다. 

6) Batch Queue

배치 버퍼링 과정에서 배치는 타임스탬프를 기준으로 재정렬된다. 일부 시간에 배치가 누락되거나 더 높은 타임스탬프를 가진 배치가 존재하면 이 공백을 메우기 위한 빈 배치도 생성된다.

안전한 L2 Head(L1에서 derive되는 마지막 블록)의 타임스탬프 바로 뒤에 하나의 배치가 있을 때, 배치는 다음 단계로 푸쉬된다. 그리고 배치의 상위 해시도 L2 Head의 해시와 일치해야한다.

배치의 4가지 형식

  • drop : 배치가 유효하지 않으며 버퍼에서 제거할 수 있음
  • accept : 배치가 유효하여 처리되어야함
  • undecided : L1 정보가 부족하여 필터링 진행이 불가함
  • future : 배치가 유효할 순 있으나 아직 처리할 수 없는 상황임

7) Payload Attributes Derivation 

이전 단계에서 얻은 배치를 인스턴스 PayloadAttributes 구조로 변환한다. 이런 구조는 block을 파악하기 위한 트랜잭션을 인코딩한다.

이 단계에선 L1 Retrieval 단계와 독립적으로 자체적인 System configuration 복사본을 유지하며, 시스템 구성은 L1 에포크가 변경될 때마다 L1 로그 이벤트로 업데이트된다.

PayloadAttribute : L1으로부터 불러온 L2의 derivation input에서 파생된 개체로, L2 블록 구성을 위해 실행 엔진으로 전달된다. 이 페이로드속성은 블록을 인코딩한다.

8) Engine Queue

엔진 대기열 단계에서 PayloadAttributes 구조거 버퍼링되어 실행 엔진으로 보내져, 드디어 실행이된다. 실행과 동시에 실행의 결과인 L2블록이 생성된다.

여기서 L2 블록은 3가지 레퍼런스를 가진다.

  • unsafe L2 head : 이것은 최신 헤드이지만, L1에서 derive되지 않은 안전하지 않은 블록이다. 시퀀서 모드 혹은 시퀀서로부터 unsafe한 동기화에서 가져온다.
  • safe L2 head : 이 블록은 L1 체인에서 완전히 derive된 것이다.
  • finalized L2 head : 이 블록까지 포함되는 모든 것은 L1 체인에서 finalized된 상태로 완전히 derive되었다고 볼 수 있다.

L1 블록은 각각 derive된 위 상태와 함께 최근에 처리된 safe L2 블록의 head 레퍼런스 히스토리를 버퍼링한다. 이 히스토리가 완전하진 않으나 후에 L1의 finality 시그널은 L2 finality 시그널로 변환된다.


Deriving Payload Attributes

모든 L2 블록은 L1 데이터로 부터 파생(derive)된다. 그래서 payload attribute를 빌드해야하고 PayloadAttributesV1 오브젝트로 표시된다. 이 오브젝트에는 추가적인 transactions와 noTxPool 필드가 포함된다.

Deriving Transaction list

각 L2 블록은 시퀀서에 의해서 만들어진다. 시퀀서 배치로부터 목표 L2 블록 넘버를 일치시켜야한다. 만약 L1 체인이 목표 L2 블록넘버를 포함하지 않고 있으면 빈 배치가 만들어 질 수 도있다. 배치는 그래서 시퀀싱 에포크 넘버, L2 timestamp 그리고 트랜잭션 리스트를 가지고 있다.

블록은 시퀀싱 에포크의 일부분으로 넘버는 L1 블록과 매치된다. L1 블록은 L1 attribute를 derive,유저의 deposit하는데 사용된다.

결론적으로 PayloadAttributesV1은 다음 트랜잭션들을 포함해야한다. 

  • 하나 혹은 하나 이상의 deposited 트랜잭션들
  • 0 혹은 그 이상의 시퀀싱 트랜잭션들(보통 L2 유저에 의해서 서명된 트랜잭션들 혹은 시퀀서의 배치를 포함)
PayloadAttributesV1: {
    timestamp: QUANTITY
    random: DATA (32 bytes)
    suggestedFeeRecipient: DATA (20 bytes)
    transactions: array of DATA
    noTxPool: bool
    gasLimit: QUANTITY or null
}
반응형
Comments