Hyperledger Besu의 합의 알고리즘: QBFT와 IBFT
최근에 Besu 체인의 검증자 노드를 하나씩 내려보며 장애 테스트를 진행했는데, 검증자 4개 중 2개를 내리자 블록 생성이 멈추는 것을 확인했습니다. 1개만 내렸을 때는 문제없이 동작했고요. 동작 원리를 더 자세히 파악하고자 QBFT 합의 알고리즘을 공부했습니다.
Besu가 지원하는 PoA 합의 프로토콜 중 QBFT와 IBFT 2.0은 엔터프라이즈 환경에서 핵심적인 역할을 합니다. 이 글에서는 BFT 계열 합의 알고리즘의 배경부터 QBFT와 IBFT 2.0의 동작 원리, 그리고 두 프로토콜의 차이점까지 정리해보겠습니다.
1. BFT 계열 합의 알고리즘
비잔틴 장군 문제
분산 시스템에서 합의를 이루는 것은 쉽지 않습니다. 특히 네트워크 내에 악의적인 노드가 존재할 수 있는 환경에서는 더욱 그렇습니다. 이 문제를 1982년 Lamport 등이 비잔틴 장군 문제(Byzantine Generals Problem)로 정의했습니다.
비잔틴 장군 문제는 여러 장군이 메신저를 통해 공격 여부를 합의해야 하는 상황에서, 배신자가 존재하더라도 충실한 장군들이 동일한 결정을 내릴 수 있는지를 다루는 문제입니다. 블록체인에 대입하면 일부 노드가 장애를 일으키거나 거짓 데이터를 전송하는 상황에서도 올바른 합의에 도달할 수 있는지를 의미합니다.
BFT(Byzantine Fault Tolerance)는 이러한 비잔틴 결함을 견딜 수 있는 시스템의 능력을 말합니다. BFT를 만족하는 시스템은 전체 노드 N개 중 비잔틴 노드 f개를 허용하기 위해 N ≥ 3f + 1을 만족해야 합니다. 즉, 전체 노드의 1/3 미만(f < N/3)이 악의적이어도 정상적으로 합의에 도달할 수 있습니다. 예를 들어 비잔틴 노드 1개를 허용하려면 최소 4개의 노드가 필요합니다.
Safety와 Liveness
합의 알고리즘이 보장해야 하는 두 가지 핵심 속성이 있습니다.
| 속성 | 의미 | 블록체인에서의 해석 |
|---|---|---|
| Safety | 문제없는 노드 사이에서 잘못된 합의가 이루어지지 않음 | 동일한 높이에서 서로 다른 두 블록이 확정되지 않음 (포크 방지) |
| Liveness | 문제없는 노드들은 반드시 합의에 도달함 | 트랜잭션이 제출되면 결국 블록에 포함됨 |
FLP Impossibility 정리에 따르면 비동기 네트워크에서 Safety와 Liveness를 완벽하게 동시에 충족하는 합의 알고리즘은 존재하지 않습니다. 따라서 합의 알고리즘의 선택은 결국 두 속성 사이에서 어떤 것을 더 우선시할 것인지에 대한 결정입니다.
PoW 기반의 나카모토 합의는 Liveness를 우선하여 잘못된 합의가 발생하더라도 어떠한 경우에도 블록을 생성합니다. 반면 BFT 계열 합의는 Safety를 우선하여 합의에 문제가 있다면 블록을 생성하지 않습니다.
PBFT 개요
PBFT(Practical Byzantine Fault Tolerance)는 1999년 Castro와 Liskov가 제안한 합의 알고리즘으로, 기존의 BFT가 동기식 네트워크에서만 동작하던 한계를 극복하고 비동기 네트워크에서도 합의를 이룰 수 있도록 설계되었습니다.
PBFT의 합의 과정은 다음과 같이 진행됩니다.
- Pre-Prepare: 리더(Primary)가 클라이언트 요청을 수집하여 블록을 제안하고 모든 검증자에게 전파
- Prepare: 제안을 받은 검증자들이 검증 후 나머지 검증자들에게 Prepare 메시지를 전파
- Commit:
2f + 1개 이상의 Prepare 메시지를 수신하면 Commit 메시지를 전파 (N = 3f + 1일 때 이는 전체의 약 2/3 이상) - Reply:
2f + 1개 이상의 Commit 메시지가 모이면 블록을 확정하고 클라이언트에 응답
PBFT는 즉시 완결성(Immediate Finality)을 보장하기 때문에 한번 확정된 블록은 뒤집히지 않습니다. 다만 모든 참가자가 전원과 통신해야 하므로 메시지 복잡도가 O(N²)로, 참여 노드 수가 증가하면 성능이 크게 저하된다는 한계가 있습니다.
2. IBFT (Istanbul Byzantine Fault Tolerance)
IBFT 1.0의 한계
IBFT 1.0은 PBFT를 블록체인 환경에 맞게 구현한 합의 알고리즘입니다. 그러나 PegaSys의 연구원 Roberto Saltini가 IBFT 1.0을 구현하는 과정에서 Safety와 Liveness에 이론적 결함이 있음을 증명했습니다. Clearmatics 팀도 독립적으로 동일한 문제를 확인했습니다.
Safety 결함: 동일한 높이에서 서로 다른 블록이 확정되는 문제
IBFT 1.0의 Safety 결함은 정족수(Quorum)가 충분하지 않았던 것이 핵심 원인입니다.
IBFT 1.0에서는 블록을 확정하기 위해 필요한 동의 수가 3에 불과했습니다 (N=5 기준). BFT 이론상 N ≥ 3f + 1이므로 N=5일 때 f=1(비잔틴 노드 1개 허용)이고, 정상 노드는 4개입니다. 그런데 정족수가 3이면 정상 노드 4개를 두 그룹(각각 2개)으로 나눌 수 있습니다.
이때 비잔틴 제안자가 다음과 같이 행동할 수 있었습니다.
검증자: V1(비잔틴 제안자), V2, V3, V4, V5 (N=5, 정족수=3)
1) V1이 V2, V3에게 블록 A를 제안 → V1 + V2 + V3 = 3 → 블록 A 확정
2) V1이 V4, V5에게 블록 B를 제안 → V1 + V4 + V5 = 3 → 블록 B 확정
→ 동일한 높이에서 블록 A와 블록 B가 모두 확정됨 (Safety 위반!)
비잔틴 제안자 V1이 자기 자신을 양쪽 정족수에 모두 포함시키면서, 서로 다른 검증자 집합에 서로 다른 블록을 제안하여 각각 합의를 이끌어내는 것입니다. 정족수가 3이기 때문에 두 집합이 겹치지 않아도(V1 제외) 각각 합의에 성공할 수 있었습니다.
Liveness 결함: 블록 잠금으로 인한 합의 교착 상태
IBFT 1.0에서는 검증자가 특정 블록에 대해 Prepare 단계를 통과하면 해당 블록에 잠기는(locked) 메커니즘이 있었습니다. 잠긴 검증자는 라운드 체인지가 발생하더라도 자신이 잠긴 블록만 수용할 수 있었습니다.
문제는 비잔틴 노드가 단 하나만 존재해도 다음과 같은 교착 상태가 발생할 수 있다는 것입니다.
검증자: V1(비잔틴), V2, V3, V4, V5
Round 1: V1이 블록 A를 제안 → V2, V3만 Prepared → V2, V3는 블록 A에 잠김
Round 2: 라운드 체인지 발생 → 새로운 제안자가 블록 B를 제안
→ V4, V5는 블록 B를 수용하려 하지만
→ V2, V3는 블록 A에 잠겨있어서 블록 B를 거부
→ 블록 A도, 블록 B도 정족수를 확보하지 못함
→ 네트워크가 영구적으로 멈춤 (Liveness 위반!)
IBFT 1.0에서는 라운드 체인지 시 항상 새로운 블록을 제안하도록 설계되어 있었기 때문에, 이전 라운드에서 잠긴 검증자와 새 라운드의 제안이 충돌하여 합의가 영원히 이루어지지 않는 상황이 발생했습니다.
IBFT 2.0의 개선점
ConsenSys의 연구팀(PegaSys)이 IBFT 1.0의 결함을 분석한 뒤, 이를 해결하기 위해 IBFT 2.0을 설계했습니다. 주요 개선 사항은 다음과 같습니다.
정족수 상향(Super-majority)
합의에 필요한 정족수를 ⌊2N/3⌋ + 1로 변경. 예를 들어 N=5일 때 정족수가 기존 3에서 4(⌊10/3⌋ + 1 = 4)로 상향되어, 비잔틴 제안자가 서로 다른 검증자 집합과 동시에 합의를 이루는 것을 방지. 정족수가 4이면 비잔틴 제안자를 제외한 정상 노드 4개 중 3개가 필요하므로, 두 집합으로 분리하는 것이 불가능해짐
라운드 체인지 프로토콜 개선 PBFT의 View Change 프로토콜에서 영감을 받아, 라운드 체인지 시 이전 라운드에서 커밋된 블록이 있다면 새로운 라운드에서도 해당 블록을 재사용하도록 변경. 이를 통해 IBFT 1.0의 블록 잠금 메커니즘이 불필요해지면서 Liveness 결함이 해소됨
동적 검증자 관리 다수결 투표를 통해 검증자를 추가하거나 제거할 수 있는 기능 추가
IBFT 2.0의 합의 과정
IBFT 2.0의 합의 과정은 PBFT와 유사하게 3단계로 진행됩니다.
- Pre-Prepare: 제안자가 새로운 블록을 생성하여 모든 검증자에게 전파
- Prepare: 검증자들이 블록을 검증하고 Prepare 메시지를 전파.
⌊2N/3⌋ + 1개 이상의 Prepare 메시지를 수신하면 Prepared 상태 진입 - Commit: Prepared 상태에 도달한 검증자들이 Commit 메시지를 전파.
⌊2N/3⌋ + 1개 이상의 Commit 메시지를 수신하면 블록 확정
제안자가 응답하지 않거나 비정상적으로 동작하는 경우에는 Round Change를 통해 다음 검증자가 새로운 제안자로 선출됩니다. requesttimeoutseconds 설정값에 의해 타임아웃이 발생하면 라운드 체인지가 트리거됩니다.
IBFT 2.0에서 각 블록은 PBFT의 체크포인트와 동일한 역할을 합니다. 즉, 블록 하나가 확정될 때마다 안정적인 전역 상태에 도달합니다.
3. QBFT (Quorum Byzantine Fault Tolerance)
QBFT 개요
QBFT는 ConsenSys가 JP Morgan과 협력하여 개발한 합의 프로토콜로, IBFT 2.0의 한계를 보완하고 엔터프라이즈 환경에 최적화하여 설계되었습니다. 현재 Hyperledger Besu에서 권장하는 엔터프라이즈급 합의 프로토콜이며, GoQuorum과 Besu 모두에서 구현되어 상호 운용이 가능합니다.
QBFT의 정상 합의 흐름(Normal Case)은 IBFT 2.0과 동일합니다. Propose → Prepare → Commit 3단계를 거치며, ⌊2N/3⌋ + 1개 이상의 메시지를 수신해야 다음 단계로 진입합니다. 메시지 복잡도도 정상 상황에서는 둘 다 O(N²)으로 같습니다.
그렇다면 QBFT는 무엇이 다른 걸까요? 핵심 차이는 라운드 체인지(Round Change)가 발생했을 때에 있습니다.
IBFT 2.0의 라운드 체인지 문제
IBFT 2.0에서는 제안자가 응답하지 않아 타임아웃이 발생하면 라운드 체인지가 진행됩니다. 이때 각 검증자는 Round Change 메시지를 전파하는데, 이 메시지에는 자신이 이전 라운드에서 수신했던 Prepare 메시지들의 전체 목록이 포함됩니다.
IBFT 2.0 Round Change 메시지 구조:
┌─────────────────────────────────────────────┐
│ Round Change Message │
│ ├── 새로운 라운드 번호 │
│ ├── Prepared Certificate (선택) │
│ │ ├── Proposal 메시지 1개 │
│ │ └── Prepare 메시지 최대 N개 ← 문제! │
│ └── 서명 │
└─────────────────────────────────────────────┘
새로운 제안자가 라운드를 시작하려면 ⌊2N/3⌋ + 1개의 Round Change 메시지를 수집해야 합니다. 각 Round Change 메시지 안에 최대 N개의 Prepare 메시지가 포함되어 있으므로, 새로운 제안자가 처리해야 하는 메시지의 총량은 최대 O(N) × O(N) = O(N²)이고, 이 과정이 검증자마다 반복되므로 전체 라운드 체인지의 메시지 복잡도는 O(N³) 까지 치솟을 수 있습니다.
검증자 수가 적을 때에는 체감이 크지 않지만, 검증자가 늘어나면 라운드 체인지 한 번에 소모되는 네트워크 대역폭이 급격히 증가합니다. 특히 네트워크가 불안정해서 라운드 체인지가 연달아 발생하면 합의 복귀가 심각하게 지연되거나, 최악의 경우 합의가 멈출 수 있었습니다.
QBFT의 핵심 개선: 라운드 체인지 최적화
QBFT는 Henrique Moniz의 IBFT 논문에서 제안한 방식을 기반으로 라운드 체인지 프로토콜을 재설계했습니다. 핵심 변경 사항은 다음과 같습니다.
1) Piggyback 방식으로 메시지 전파 구조 변경
QBFT에서는 Round Change 메시지에 Prepare 메시지 전체를 포함시키는 대신, 새로운 제안자가 Proposal 메시지에 필요한 증명(Prepared Certificate, Round Change Certificate)을 Piggyback 방식으로 함께 실어 보냅니다. 이를 통해 각 검증자가 개별적으로 Prepare 메시지 목록을 전송할 필요가 없어졌습니다.
QBFT Round Change 흐름:
1) 각 검증자 → 새 제안자: Round Change 메시지 (Prepare 목록 포함하지 않음)
2) 새 제안자: ⌊2N/3⌋ + 1개의 Round Change 메시지 수집
3) 새 제안자 → 모든 검증자: Proposal + Round Change Certificate를 Piggyback
4) 각 검증자: Piggyback된 증명을 검증하고 Prepare 단계 진입
→ 라운드 체인지 메시지 복잡도: O(N³) → O(N²)로 감소
2) 합의 멈춤(Consensus Stall) 완화
IBFT 2.0에서는 과도한 라운드 체인지가 반복될 때 메시지 폭증으로 인해 합의가 멈추는 현상이 보고되었습니다. QBFT는 라운드 체인지 시 교환되는 메시지 양 자체가 줄었기 때문에, 네트워크가 불안정한 환경에서도 더 빠르게 합의에 복귀할 수 있습니다.
3) GoQuorum과 Besu 간 상호 운용성
IBFT 2.0은 GoQuorum과 Besu에서 각각 독립적으로 구현되어 있어 상호 운용이 보장되지 않았습니다. QBFT는 EEA(Enterprise Ethereum Alliance)에서 공식 스펙으로 정의되었고, GoQuorum과 Besu 모두 이 스펙을 따르도록 구현되어 동일 네트워크에서 두 클라이언트를 혼용할 수 있습니다.
IBFT 2.0과의 차이점 요약
| 비교 항목 | IBFT 2.0 | QBFT |
|---|---|---|
| 정상 합의 흐름 | Propose → Prepare → Commit | 동일 |
| 정상 합의 메시지 복잡도 | O(N²) |
동일 |
| 라운드 체인지 메시지 복잡도 | O(N³) |
O(N²)로 개선 |
| 라운드 체인지 시 메시지 전파 | 각 검증자가 Prepare 목록을 개별 전송 | Piggyback 방식으로 제안자가 일괄 전파 |
| 합의 멈춤 | 반복적 라운드 체인지 시 발생 가능 | 완화됨 |
| 공식 스펙 | 없음 (각 클라이언트별 구현) | EEA 공식 스펙 존재 |
| 상호 운용성 | GoQuorum, Besu 간 미보장 | GoQuorum + Besu 혼용 가능 |
검증자 관리 방식
QBFT는 두 가지 검증자 관리 방식을 지원합니다.
블록 헤더 기반 (Block Header Validator Selection)
- 제네시스 블록의
extraData에 초기 검증자 목록 포함 - JSON-RPC API(
qbft_proposeValidatorVote)를 사용하여 투표로 검증자 추가/제거 - 설정이 단순하고 직관적
스마트 컨트랙트 기반 (Contract Validator Selection)
- 검증자 목록을 스마트 컨트랙트로 관리
- 제네시스 파일의
alloc섹션에 컨트랙트를 사전 배포 가능 - 컨트랙트 함수를 호출하는 트랜잭션을 통해 검증자 변경
- 더 유연한 거버넌스 로직 구현 가능
4. 어떤 프로토콜을 선택해야 할까?
3번 섹션에서 정리한 것처럼 QBFT와 IBFT 2.0은 정상 합의 흐름이 동일하고, 차이는 라운드 체인지 처리에 있습니다. 실무에서 선택할 때 고려할 포인트를 정리하면 다음과 같습니다.
QBFT를 선택해야 하는 경우
- 신규 프라이빗 네트워크를 구축하는 경우 (Besu 공식 권장)
- GoQuorum과 Besu 노드를 혼용해야 하는 경우
- 스마트 컨트랙트 기반 검증자 관리가 필요한 경우
- 검증자 수가 많아서(10개 이상) 라운드 체인지 시 성능 저하가 우려되는 경우
IBFT 2.0을 유지해도 되는 경우
- 기존 IBFT 2.0 네트워크가 안정적으로 운영 중인 경우
- 검증자 수가 적고(4~6개) 라운드 체인지 빈도가 낮은 경우
- 마이그레이션 리스크를 감수할 필요가 없는 경우
기존 IBFT 2.0 네트워크에서 QBFT로 전환이 필요하다면, Besu는 transitions 제네시스 설정을 통해 특정 블록 번호부터 합의 알고리즘을 변경할 수 있습니다.
{
"config": {
"istanbul": {
"epoch": 30000,
"policy": 0,
"ceil2Nby3Block": 0
},
"transitions": [{
"block": 120,
"algorithm": "qbft"
}]
}
}
5. Besu에서의 PoA 합의 프로토콜
Hyperledger Besu는 QBFT, IBFT 2.0, Clique 세 가지 PoA 합의 프로토콜을 지원합니다. PoA 프로토콜은 참여자들이 서로를 알고 있고 일정 수준의 신뢰가 존재하는 허가형 컨소시엄 네트워크에 적합합니다. Ethash(PoW) 대비 블록 생성 시간이 빠르고 트랜잭션 처리량이 훨씬 높습니다.
QBFT/IBFT 2.0의 주요 제네시스 설정
{
"config": {
"chainId": 1337,
"qbft": {
"blockperiodseconds": 2,
"epochlength": 30000,
"requesttimeoutseconds": 4
}
}
}
blockperiodseconds: 블록 생성 주기 (초)epochlength: 에포크 길이. 에포크 전환 시 모든 투표가 리셋됨requesttimeoutseconds: 요청 타임아웃. 이 시간 내에 블록이 생성되지 않으면 라운드 체인지 발생
장애 허용 범위
BFT를 보장하기 위해 QBFT와 IBFT 2.0은 최소 4개의 검증자가 필요합니다. 검증자 수에 따른 장애 허용 범위는 다음과 같습니다.
| 검증자 수 | 허용 가능한 장애 노드 수 |
|---|---|
| 4~5 | 1 |
| 6~8 | 2 |
| 9~11 | 3 |
검증자의 1/3 이상이 응답하지 않으면 네트워크는 새로운 블록을 생성하지 못하고 멈추게 됩니다. 그리고 노드가 재시작된 이후에도 복구에 상당한 시간이 소요될 수 있기 때문에, 운영 환경에서는 검증자의 1/3 이상을 잃지 않도록 네트워크를 구성해야 합니다.
Clique와의 비교
참고로 Clique는 QBFT, IBFT 2.0과 비교했을 때 장단점이 명확합니다. 단일 검증자로도 운영이 가능하고 합의 속도가 빠르지만, 즉시 완결성이 보장되지 않아 포크가 발생할 수 있습니다. 다만 Clique는 Besu 25.12.0부터 블록 생성 기능이 deprecated되었기 때문에 신규 네트워크 구축에는 적합하지 않습니다.
6. 마무리
BFT 계열 합의 알고리즘의 흐름을 정리하면 PBFT → IBFT 1.0 → IBFT 2.0 → QBFT 순으로 발전해왔습니다. 각 단계에서 이전 프로토콜의 한계를 보완하며 Safety와 Liveness 사이의 균형을 개선해왔고, 특히 QBFT는 라운드 체인지 시 메시지 복잡도를 O(N³)에서 O(N²)로 줄여 엔터프라이즈 환경에서의 안정성을 높였습니다.
도입부에서 언급했던 장애 테스트로 돌아가면, 검증자 4개 중 2개를 내렸을 때 블록이 멈춘 이유는 정족수를 만족시킬 수 없었기 때문입니다. 그리고 노드를 재시작한 뒤에도 바로 블록이 생성되지 않고 약간의 딜레이가 있었는데, 이는 라운드 체인지가 반복되면서 새로운 제안자가 합의를 재개하는 과정이었습니다. 이론을 알고 나니 로그에서 QbftBesuControllerBuilder가 찍어주는 라운드 번호의 의미도 이해할 수 있었습니다.
Reference
- Hyperledger Besu - Proof of Authority Consensus
- Hyperledger Besu - QBFT
- Hyperledger Besu - IBFT 2.0
- The Istanbul BFT Consensus Algorithm - Henrique Moniz (arxiv)
- Correctness Analysis of IBFT - Roberto Saltini (arxiv)
- EEA - QBFT Blockchain Consensus Protocol Specification v1
- ConsenSys - Why IBFT 2.0
- Web3 Labs - Exploring PBFT, IBFT and QBFT
- Catalyst - Choose a Consensus Protocol
댓글남기기