이더리움 7-블록 re-org : 왜 발생했을까?

Seongwan Park
slcf
Published in
9 min readJun 5, 2022

Reviewed by Woojin Jeong

원문 링크 : https://barnabe.substack.com/p/pos-ethereum-reorg?sd=fs&s=r
본 글은 Ethereum Foundation 의 Barnabé Monnot 가 작성한 내용을 위주로 정리한 글이며, 필자의 개인적인 견해 와 추가적인 설명 또한 반영하였다.

약 일주일 전인 5월 25일, 이더리움 비콘 체인에서 7-블록 re-org (블록이 재구성되는 현상) 가 발생하였다는 소식이 들렸다. 이 사실을 처음으로 알게 된 것은 Paul Hauner였고, Gnosis 체인의 설립자인 Martin Köppelmann가 트위터에 소식을 처음 알렸다. 이로 인해 PoS 합의방식의 안정성에 대해 의문이 제기되었다. 이더리움의 비콘체인 런치 이후 가장 큰 규모의 리오그였고, 사실상 비콘체인 출시 이후 처음 비정상적인 상황으로 인식된 사건이었다.

https://twitter.com/koeppelmann/status/1529458000011972610

필자를 포함한 많은 리서처, 이더리움 홀더들이 이번 re-org의 원인을 궁금해하고 있었는데 Ethereum Foundation의 리서처인 Barnabé가 전후상황을 잘 정리해주어서, 그 내용을 소개하고자 한다.

re-org가 발생한 이유를 크게 살펴보면, 다음 3가지의 상황이 맞물려서 발생한 것이다.

  1. 먼저 한 slot (slot 3887074) 내에 block proposer가 늦게 블록을 제안해서, validator들이 보는 상황이 서로 달라졌다. (terence.eth에 따르면 로컬 노드에서 관측된 바로는, 블록 도착 시간이 12.23초 늦었다고 한다)
  2. proposer boost 업데이트는 소프트 포크를 통해 진행되었기 때문에 소프트웨어 업데이트를 한 validator들은 proposer boost를 사용하고 있었지만, 업데이트를 안 한 validator들은 사용하지 않고 있었다. 이로 인해 validator들이 서로 다른 fork choice 규칙을 따르고 있었다. (proposer boost 는 블록이 4s 내에 잘 생성되었을 때 부여하는 가산점과 비슷한 개념이다.)
  3. fork choice 규칙을 어떤 타이밍을 기준으로 계산하고 적용해야 하는지에 대한 잘못된 구현체가 꽤 많이 돌아다니고 있었다.

글의 뒷부분에서도 언급하겠지만, 이번 re-org가 비콘 체인의 finality를 해치거나 지연시킨 것은 아니다. finalized된 블록이 revert되는 모순적인 상황이 발생한 것은 아니라는 뜻이다. 다만 블록이 finalized 되기 전 7블록이 버려지는 혼란스러운 상황이 있었을 뿐이다.

포크 발생 상황

출처 : https://barnabe.substack.com/p/pos-ethereum-reorg?sd=fs&s=r
출처 : https://beaconscan.com/

먼저 전체적인 상황을 간단하게 보면 위와 같다. 숫자로 표시된 네모는 블록을 의미하고, 빨간 원의 크기는 블록이 투표받은 attestation 의 수에 비례한다.

74번째 블록과 75번째 블록이 거의 동시에 만들어져 포크가 발생하였다. 이후 76~81 번째 proposer 들은 75번째 블록 뒤에 이어서 블록을 쌓았는데, 그 사이에 74번째 블록의 attestation이 계속 증가하여 75~81 블록보다 더 많은 weight을 받았다. 82번째 proposer가 74번째 블록 뒤에 블록을 만들며 75~81번째 블록은 re-org되었다. 단계별로 조금 더 자세히 살펴보자.

먼저, 73번째 slot에 블록이 정상적인 시간 범위 내에서 만들어졌고 attester들도 이 블록에 대해 문제 없이 attestation을 진행하였다.

그러나 74번째 slot에서는 블록이 뒤늦게 만들어졌고 75번째 slot에서 만들어진 block과 거의 동시에 만들어졌다. Proposer boost는 이와 같은 상황에서 블록 생성시간의 데드라인 (약 12s) 을 더 잘 준수한 75번째 블록에 더 많은 weight를 주도록 구현되었다. 74번째 블록은 늦게 만들어졌기 때문에 proposer boost를 받지 못한다.

Proposer boost spec

따라서 proposer boost를 사용하지 않는 attester들은 74번째 블록에 attest하였는데, 하필 74,75번째 블록 중 2/3 이상의 attestation을 받은 블록은 없었다. proposer boost를 사용하지 않는 attester가 조금 더 많았기 때문에 74번째 블록을 포함한 체인이 조금 더 큰 weight를 가지게 되었다.

다음 블록인 76번째 블록은 74번째 블록이 아닌 75번째 블록 뒤에 생성되었다. 76번째 블록의 proposer가 더 큰 weight를 가지는 위쪽 체인이 아닌, 아래쪽 체인 뒤에 이어붙인 이유는 다음과 같다. 76번째 proposer는 proposer boost가 적용된 클라이언트를 사용하고 있었는데, 75번째 블록이 boost를 받을 수 있는 시간대에 들어왔고 74번째 블록은 늦게 들어왔기 때문에 75번째 블록에 대해 추가적인 weight가 반영되어 75번째 블록을 head로 인식하게 된 것이다. 76번째 블록 proposer 입장에서 본 상황은 다음과 같았다.

74번째 블록의 attestation 수 < 75번째 블록의 attestation 수 + proposer boost

한편, 76번째 블록의 attester들 중 proposer boost를 사용하는 attester들은 proposer와 마찬가지의 이유로 76번째 블록이 담긴 아래쪽 체인에 attest하였고, proposer boost를 사용하지 않는 attester들은 74번째 블록에 attest하였다. 그래서 시간이 갈수록 74번째 블록에 더 많은 attestation이 쌓여가는 것을 확인할 수 있다. (빨간 원의 크기)

77~81번째 블록에서도 76번째 블록에서와 같은 일이 벌어졌다. 예컨대 77번째 블록의 proposer가 proposer boost를 사용하고 있었고, 76번째 블록에 boost weight가 추가적으로 더해져 아래 체인에 블록을 이어붙인 것이다. 77번째 블록의 attester들 중 일부는 74, 일부는 77번째 블록에 attest하여 74번째 블록의 attestation 수가 계속 커졌다.

(참고 : PoW와는 다르게 비콘 체인의 PoS에서는 longest chain rule이 적용되지 않는다. 비콘 체인에서는 fork choice rule로 LMD GHOST를 사용하는데, justified된 체인들 중 더 높은 height를 가진 체인이 선택되는 것을 기억하자. 위 상황에서는 2/3 이상의 attestation을 받은 체인이 없으므로 두 체인 모두 justified되지 않은 상황이다. 따라서 attestation의 수와 proposer boost 여부에 의존한다.)

포크 상황은 82번째 블록에서 마무리되었다. 82번째 블록의 proposer는 76~81번째 블록의 proposer들과는 다르게 proposer boost를 적용하지 않는 클라이언트를 사용하고 있었기 때문에, 81번째 블록과 74번째 블록의 선택 상황에서 attestation의 수가 더 많은 74번째 블록을 선택한 것이다.

82번째 블록은 boost를 받을 수 있는 시간에 생성되었고, 따라서 그 이후의 블록들을 만드는 proposer들은 proposer boost를 사용하는지 여부에 관계없이 82번째 블록이 담긴 위의 체인에 더 높은 weight를 부여하게 된다. 이로써 75~81번째 블록에 담긴 트랜잭션들은 무효가 되었다.

생각

비콘체인 역사가 길진 않지만, 7블록의 re-org 는 여태 있었던 re-org 중 가장 큰 규모였다. 이와 같은 일이 만약 빈번히 발생하게 되면 이론상으로는 꽤 심각한 이중지불 상황이 생길 가능성도 있다. 다행히도 비콘 체인은 아직까지는 실제 트랜잭션을 담지 않기 때문에 당장은 큰 문제가 발생하지 않았다. 또한 re-org가 발생한 이유를 생각해보면 이더리움의 합의 알고리즘인 Casper FFG+LMD GHOST 이 가지는 근본적인 문제라기보다는, 일부 노드만이 소프트웨어 업데이트를 진행했기 때문이다. 게다가 이더리움 PoS 에서 보장하는 finality 가 깨진 것도 아니다. 블록들이 finalized 되기까지 7블록이 revert되는 난잡한 상황이 있었던 것이다. 어쨌든간에 합의 레이어 단에서 문제가 없다 하더라도 이번 일과 같이 구현 단에서 다른 버전의 클라이언트들이 합의 문제를 일으킬 수 있음을 인지할 수 있었다. 프로토콜 업데이트를 진행할 때 이를 설계하는 이더리움 프로토콜 연구자들, 개발자 측에서 앞으로 조금 더 보수적으로 접근할 것으로 예상한다. 실제 피해가 없었기에 큰 이슈가 되지는 않았으나, 이번 사건을 통해 이더리움이 한층 더 완전한 블록체인에 가까워지기를 바란다.

--

--

Seongwan Park
slcf
Editor for

Four Pillars Researcher / Decipher / Ph.D candidate in Blockchain