[Reth 2.0, 가장 빠른 이더리움 노드 구현체]
Reth 2.0이 오늘 공식 출시됐습니다. 이더리움에서 가장 빠른 노드 구현체가 될 만큼, 성능에 초점을 맞춘 릴리즈이죠. 이번 릴리즈에 어떤 최적화들이 들어갔는지 자세히 보겠습니다.
[Reth가 달성한 수치: 1.7 GigaGas/sec, 디스크 240GB]
이더리움에서 모든 연산은 가스라는 단위로 측정됩니다. 송금은 21,000 가스, 복잡한 디파이 트랜잭션은 수십만 가스를 소모하죠. 이번 Reth는 초당 17억 가스어치의 연산을 처리할 수 있다고 주장하는데, 현재 이더리움 메인넷의 가스 리밋이 블록당 4,500만 가스 정도이니 이론적으로 초당 수십 블록을 처리할 수 있는 여유를 확보한 셈입니다. 이러한 성능 이점은 https://lab.ethpandaops.io/ethereum/execution/timings?range=24hours에서 드러납니다. 해당 대시보드는 각 클라이언트의 블록 검증 속도를 측정하는데, 최근 95% 이상의 블록에서 Reth가 가장 빠른 것으로 드러나죠.
디스크 사용량도 많은 최적화가 이루어졌습니다. 이더리움 풀 노드는 보통 수백 GB에서 TB 단위의 저장 공간을 요구하는데, Reth 2.0은 약 240GB, 스냅샷 다운로드 시 약 170GB까지 줄였습니다.
[어떻게 이걸 달성했나]
크게 세 가지 구조적 변화가 있습니다.
<1. Sparse Trie 캐시: 상태 루트 계산의 병목 해소>
이더리움의 모든 계정 잔액, 컨트랙트 데이터 등은 ‘상태(state)’라고 불리는 거대한 데이터셋에 저장됩니다. 매 블록마다 노드는 이 전체 상태를 요약한 단일 해시값, 즉 ‘상태 루트(state root)’를 계산해야 합니다. 블록이 올바른지 검증하는 핵심 과정이죠.
문제는 이 상태가 머클 패트리샤 트리(MPT) 구조로 저장된다는 점입니다. 트랜잭션이 계정 하나를 바꾸면, 그 계정에서 트리 꼭대기(루트)까지의 경로에 있는 모든 중간 노드를 다시 해싱해야 합니다. 상태가 수억 개 규모로 커질수록 트리는 깊어지고, 이 중간 노드들이 디스크 곳곳에 흩어져 있어 대량의 랜덤 I/O가 발생합니다. 이 디스크 I/O 비용이 상태 루트 계산의 실질적인 병목입니다.
Reth 1.0은 이미 "Sparse Trie"라는 기법으로 이걸 병렬화했습니다. 트랜잭션을 실행하는 동안 백그라운드에서 상태 루트를 동시에 계산하는 방식이죠. 하지만 매 블록마다 이 트라이의 작업용 복사본을 디스크에서 매번 불러와야 했기 때문에, 레이턴시를 일정 수준 이하로 낮추기 어렵다는 단점이 있었죠.
Reth 2.0의 Sparse Trie 캐시는 이 작업용 트라이를 블록이 바뀌어도 메모리에 계속 유지합니다. 블록 A에서 만든 트라이 구조를 블록 B에서 버리지 않고 재활용하는 거죠. 물론 잘 쓰이지 않는 데이터까지 전부 메모리에 올리는 것은 비효율적이니, 주기적인 프루닝을 통해 자주 쓰이는 데이터만 메모리에 올라오도록 합니다. 결과적으로 메인넷 블록 하나의 상태 루트 계산이 1~2ms로 줄었다고 하죠. 이전에는 이 단계가 전체 블록 처리 시간의 상당 부분을 차지했던 걸 고려하면, 사실상 병목이 사라진 것과 다름없습니다.
<2. 부분 증명(Partial Proofs): 디스크 읽기 절반으로 감소>
상태 루트를 계산하려면, 변경된 각 계정에 대해 '머클 증명'이라는 데이터를 트라이에서 가져와야 합니다. 문제는, 같은 블록 안에서 여러 트랜잭션이 비슷한 영역의 계정들을 건드리는 경우가 많다는 점입니다. 기존에는 매번 전체 경로를 디스크에서 처음부터 끝까지 읽어오는 방식을 사용하고 있어, 중복으로 인한 낭비가 컸었죠.
Reth 2.0의 부분 증명은 캐시에 이미 존재하는 상위 부분은 건너뛰고, 아직 없는 하위 부분만 디스크에서 가져옵니다. 이것만으로 블록당 증명 요청 수가 절반으로 줄었고, 디스크 I/O 부담이 크게 감소했습니다.
<3. 핫/콜드 계층형 스토리지: 20배 빠른 블록 저장>
노드가 저장하는 데이터는 성격이 다릅니다. ‘지금 이 순간의 잔액’처럼 자주 읽는 핫 데이터가 있고, ‘3년 전 블록의 트랜잭션’처럼 거의 안 보는 콜드 데이터가 있죠. 기존에는 이걸 전부 하나의 데이터베이스(MDBX)에 넣었습니다.
Reth 2.0은 이걸 세 계층으로 분리했습니다. MDBX에는 검증에 필요한 해시 상태만 남기고, 과거 변경 이력은 append-only 방식의 정적인 파일로, 빠른 검색을 위한 인덱스는 RocksDB로 옮겼습니다. Append-only라는 건 데이터를 수정하거나 삭제하지 않고 뒤에 계속 붙이기만 한다는 뜻인데, 이 방식이 과거 이력 저장에는 훨씬 효율적입니다.
이를 통해, Reth는 일반 블록 저장 시간을 평균 40ms, 기가가스급 대형 블록에 대해서도 400ms 수준까지 줄일 수 있었습니다. Reth 1.0.0에서 같은 크기 블록이 8.4초 걸렸으니, 약 20배 빨라진 것이죠. 데이터베이스 자체가 작아지면서 읽기 속도도 덩달아 빨라진다는 이점도 얻을 수 있습니다.
재밌는 부가 효과도 있습니다. 풀 노드에서 아카이브 노드로(혹은 그 반대로) 전환하려면 해당 파일만 마운트하거나 해제하면 됩니다. 예전에는 처음부터 다시 동기화해야 했던 걸 생각하면 큰 개선이죠.
이 계층형 아키텍처 덕분에 Reth에서도 ‘미니멀 모드’가 가능해졌습니다. 블록 검증에 꼭 필요한 해시 상태 테이블과 트라이 데이터만 저장하고, 나머지 히스토리와 인덱스는 전부 생략하는 설정입니다. 이를 통해, 메인넷 노드를 300GB 미만으로 돌릴 수 있죠.
[다음 Reth의 목표]
상태 루트 계산이 더 이상 병목이 아니게 되면서, 다음 타겟은 트랜잭션 실행 자체의 속도입니다. 두 가지 방향이 있습니다.
첫째, revmc를 통한 AOT/JIT 실행. 현재 EVM 바이트코드는 인터프리터 방식으로 한 줄씩 해석되는데, 이걸 네이티브 머신코드로 미리 컴파일(AOT)하거나 실행 시점에 컴파일(JIT)해서 실행 속도 자체를 끌어올리겠다는 겁니다.
둘째, 글램스터담(Glamsterdam) 하드포크에서 도입 예정인 BAL(Block-level Access List)을 활용한 완전 병렬 실행. 현재 트랜잭션은 같은 상태를 건드릴 수 있기 때문에 기본적으로 순차 실행되는데, BAL이 "이 트랜잭션이 어떤 상태에 접근하는지"를 미리 선언하게 해주면, 겹치지 않는 트랜잭션들을 안전하게 동시 실행할 수 있습니다.
[정리]
이더리움 실행 클라이언트의 발전이 점점 흥미로워지고 있습니다. Geth가 오랫동안 지배적이었으며, 성능은 Nethermind가 압도적이었던 시장에서, Reth가 공격적인 AI 사용을 기반으로 한 빠른 개발 속도로 상한선을 계속 끌어올리고 있는 모습이 인상적입니다.
앞으로 이더리움 클라이언트의 다양성과, 이 높아진 성능이 L2 등에서 어떻게 활용될지 지켜봐도 좋을 것 같습니다!
https://www.paradigm.xyz/2026/04/releasing-reth-2-0