EIP-6122 타임스탬프 기반 포크ID 검사 (Forkid checks based on timestamps)

최종 확정 · 네트워크·노드 · 원문 상태 Final · 2022-12-13 작성

노드가 서로의 체인 설정을 식별하는 포크ID(forkid) 계산을 블록 번호뿐 아니라 타임스탬프로 예약된 포크에도 맞게 바꿉니다. 머지 이후 포크가 시간 기준으로 예약되기 때문입니다.

왜 필요한가

작업증명 시절 이더리움은 포크를 블록 번호로 예약했습니다. 그런데 지분증명 합의 계층은 포크를 슬롯 번호로 예약하고 슬롯은 시간 기반 단위입니다. 머지(The Merge) 이후 합의 계층과 실행 계층이 같은 시점에 포크하려면 실행 계층도 타임스탬프로 포크를 예약할 수밖에 없습니다. 하지만 노드들이 서로를 식별하는 포크ID(forkid)는 블록 번호만 전제로 만들어졌습니다. 포크ID는 피어의 체인 설정을 빠르게 파악해 잘못 설정됐거나 다른 네트워크용으로 설정된 피어를 끊어내는 장치입니다. 이 장치가 P2P 네트워크를 더 믿을 만하게 만드는데, 타임스탬프 기반 포크를 반영하지 못하면 식별이 제대로 작동하지 않습니다. 그래서 포크ID 계산에 타임스탬프를 넣도록 업데이트합니다.

무엇이 바뀌나

지금

EIP-6122 이후

누구에게 영향이 있나

심층 설명

FORK_HASH: 제네시스 해시와 지난 포크의 CRC32 체크섬

FORK_HASH는 제네시스 해시와 이미 지난 포크들의 블록 번호 또는 타임스탬프를 IEEE CRC32로 체크섬한 4바이트 값입니다. 포크 지점은 오름차순으로 넣고 여러 포크가 같은 블록이나 같은 시각에 적용되면 그 값은 한 번만 체크섬합니다. 블록 번호와 타임스탬프 모두 uint64 정수로 보고 빅엔디언으로 인코딩해 넣습니다. 체인이 제네시스부터 프런티어(Frontier)가 아닌 룰셋으로 시작하도록 설정돼 있어도 그것은 포크로 치지 않습니다.

FORK_NEXT: 다음 포크 지점

FORK_NEXT는 다음에 올 포크의 블록 번호 또는 타임스탬프를 담는 uint64 값이고 알려진 다음 포크가 없으면 0입니다. 원문은 FORK_NEXT에서 그 값이 블록 번호인지 타임스탬프인지 구분하는 것은 중요하지 않다고 명시합니다. 테스트 케이스에서 보듯 이 값은 상대 피어가 앞으로 올 포크를 알고 있는지, 즉 소프트웨어 업데이트가 필요한 상태인지 판정하는 데 쓰입니다.

계산 예시: 홈스테드 위의 타임스탬프 포크

홈스테드(Homestead) 위에 타임스탬프 1668000000에 가상의 포크가 예약된 체인이라면 FORK_HASH는 CRC32(<genesis-hash> || uint64(1150000) || uint64(1668000000))로 계산되고 값은 0xcb37b2ee입니다. 블록 번호 1150000(홈스테드)과 타임스탬프 1668000000이 똑같이 uint64 빅엔디언으로 이어서 체크섬에 들어갑니다. 블록 번호와 타임스탬프를 한 흐름으로 다루므로 체계가 둘로 갈라지지 않습니다.

추가 규칙: 블록 포크 먼저, 타임스탬프 포크 나중

타임스탬프로 예약하는 포크는 메인넷이든 사설 네트워크든 블록으로 예약한 포크와 같은 시점이거나 그 뒤에 와야 합니다(MUST). 또 원격 피어의 포크ID를 검증하는 구현은 들어온 포크ID를 먼저 블록 기준으로 거르고 그다음 타임스탬프 기준으로 걸러야 합니다. Rationale에 따르면 상하이(Shanghai) 업그레이드가 타임스탬프로 예약되면서 이 업데이트가 필요해졌고 모든 블록 기반 포크가 시간 기반 포크보다 앞서므로 검사 순서도 블록이 먼저입니다.

하위 호환성: 피어가 끊기는 것이 목적

이 변경은 포크ID 계산을 약간 바꿉니다. 그 결과 이 변경을 적용한 노드는 타임스탬프로 예약된 포크가 발생하는 순간부터 변경을 적용하지 않은 피어를 끊게 됩니다. 원문은 이것이 예상된 일일 뿐 아니라 애초에 포크ID가 존재하는 목적 그 자체라고 설명합니다. 설정이 맞지 않는 노드를 빨리 끊어내는 것이 포크ID의 역할이기 때문입니다.

테스트 케이스: 포크ID 값과 수락·거절 판정

원문은 메인넷 설정에 출금(withdrawals)을 타임스탬프 1668000000에, 머지 넷스플릿 블록을 18000000에 둔 구성으로 두 벌의 테스트를 제시합니다. 첫 번째는 체인 진행에 따른 포크ID 값을 검증합니다. 예를 들어 상하이 구간에서는 Hash 0xc1fdf181, Next 0이 됩니다. 두 번째는 로컬 노드가 원격 포크ID를 수락할지 거절할지 판정하는 케이스들입니다. 단순히 동기화가 늦은 피어는 수락하고 업데이트가 필요한 오래된 원격 피어는 ErrRemoteStale로, 로컬 쪽이 호환되지 않거나 뒤처진 경우는 ErrLocalIncompatibleOrStale로 거절합니다.

보안과 상태

원문 Security Considerations 절은 알려진 보안 위험이 없다고 밝힙니다. 이 EIP는 네트워킹(Networking) 카테고리의 표준 트랙 제안이고 상태는 Final이라 내용이 더 바뀌지 않습니다. 포크ID 체계를 처음 정의한 EIP-2124를 requires로 전제하며 체크섬 입력에 타임스탬프를 추가하는 방식으로 기존 체계를 확장합니다.

EIP 원문 · ← EIPs