BlockChain/[paper] Consensus
[논문 리뷰] PBFT: Practical Byzantine Fault Tolerance
동현 유
2023. 2. 18. 16:30
Authors : Miguel Castro, Barbara Liskov
Source : OSDI 1999
[Background]
- 네트워크 환경 구분 3가지
: 메세지 송수신 간의 딜레이를 기준으로 (1) Synchronous, (2) Partially synchronous, (3) Asynchronous 로 구분함. - Byzantine Fault Problem 을 해결하기 위해서는 Safety 와 Liveness 를 만족시켜야함.
: Safety - replicated state machines 들이 linearizability를 만족하는 것. 동일한 인풋이 주어지면 모든 노드들이 같은 결과에 도달하는 것. 마치 하나의 머신이 요청을 atomic 하게 처리하는 것과 같은 효과를 내야함.
: Liveness - 최종적으로 아웃풋을 내야함. - FLP impossibility
: Asynchronous 한 네트워크 환경에서 Safety, Liveness 를 동시에 만족하는 deterministic 한 알고리즘은 존재하지 않는다는 사실이 증명됨 (Fischer, Michael J., Nancy A. Lynch, and Michael S. Paterson. "Impossibility of distributed consensus with one faulty process." Journal of the ACM (JACM) 32.2 (1985): 374-382.) - Quorum For Asynchronous Consensus
: malicious 한 노드 개수를 f 개라고 했을 때, 정상적인 노드가 2f + 1 개 이상 있어야 합의에 도달할 수 있음. (fail-stop node가 f개라고 하면 f+1개 이상 있어야 합의 도달 가능) (Bracha, Gabriel, and Sam Toueg. "Asynchronous consensus and broadcast protocols." Journal of the ACM (JACM) 32.4 (1985): 824-840.)
[Purpose]
- 이전의 연구에서는 synchrony 를 가정하거나, asynchonous 하더라도 실제 사용하기에 속도가 너무 느렸음.따라서 asynchronous 한 네트워크 환경에서 적용 가능한 방안을 제시.
- Safety는 asynchrony 상황을 가정, Liveness는 weak synchronous assumption (partial synchrony) 가정함. (둘다 asynchronous 라고 가정하면 FLP impossibility 에 의해 해결이 불가능하기 때문.)
[Algorithm]
(필요조건)
- 각 노드들은 deterministic 해야함. (같은 인풋 -> 동일한 결과)
- 각 노드들의 start state 가 동일해야 함.
(알고리즘 간단버전)
- 클라이언트가 primary 노드에게 요청 \(m\) 을 보냄.
- primary 노드가 나머지 backup 노드들에게 request를 전파함 (pre-prepare)
- 각 노드들은 요청을 실행하고, 클라이언트들에게 응답
- 클라이어트는 f+1 개 이상의 동일한 응답을 받으면, 정상적인 응답이라고 판단.
(정상상황)
- primary 노드가 \(<<PRE-PREPARE, n, v, H(m)>_{\sigma_p}, m>\) 을 만들어서 전파. (v 는 view no, n은 sequence no, \(\sigma\)는 서명, \(H\)는 해시함수)
- pre-prepare 메세지를 받은 backup 노드들은 해당 메세지의 서명이 올바른지, 같은 view 인지, sequence 번호가 올바른지 등을 검증한 후 문제가 없으면 \(<PREPARE, n, v, H(m), i)>_{\sigma_i}\) 를 전파.
- 2f+1 개의 prepare 메세지를 받으면, pre-prepare 메세지와 검증 후에 log로 기록한다. 이 후 \(<COMMIT, n, v, H(m), i>_{\sigma_i}\) 메세지를 전파한다.
- 2f+1 개의 commit 메세지를 받으면, 요청을 실행시키고 클라이언트에게 최종적으로 응답한다. (단, 하나의 요청에 한 번만 응답하는 것을 보장하기 위해, 현재 실행시키려는 요청이 가장 최근 응답보다 과거에 발생한 경우에는 경우에는 실행시키지 않고 버린다.)
(비정상상황)
- primary 노드가 제대로 동작하지 않는 경우를 대비.
- 노드마다 순서대로 번호가 정해져 있는데, primary 노드 역할은 view 가 변하면서 순서대로 돌아감.
- 각 노드마다 timeout 이 발생하면 멈추고 합의를 진행하지 않음(pre-prepare, prepare, commit 메세지를 받지 않음.) View-change 단계에 진입하여, \(<VIEW-CHANGE, v+1, n, C, P, i>_{\sigma_i}\) 메세지를 전파. (n은 lastest stable checkpoint s에 해당하는 seq 번호, C는 s에 대한 2f+1개의 valid messages, P는 s 이후의 사용자 요청에 대한 valid한 pre-prepare 메세지들(2f+1개의 prepare 응답을 받은 것만 해당)), timeout이 발생하지 않더라도 f+1개의 view-change 메세지를 받으면 view-change 단계에 진입함.
- 새로운 primary 노드가 2f+1 개의 view-change 메세지를 받으면, \(<NEW-VIEW, v+1, V, O>_{\sigma_p}\) 메세지를 전파함. (V는 다른 노드들로부터 받은 view-change 메세지, O는 P들을 다 종합해서 가장 낮은 stable checkpoint 번호와 가장 높은 번호 사이에 있는 pre-prepare 메세지들. 다른 노드들과 sync를 맞추기 위함.)
- new-view 메세지를 받으면 v+1 번째 view로 진입
- new-view 메세지를 받은 노드들은 pre-prepare 메세지를 확인하고 prepare 메세지를 전파함. 사용자 요청을 중복 실행하는 것을 방지하기 위해, log를 확인하여 실행 결과를 가져오거나, 다른 노드들에게 요청함.
(리뷰)
- 1/3 이상의 노드를 비정상적으로 조작하지 않는한, safety와 liveness 가 깨지지 않는다는 것을 증명한 논문.
- 요청 처리 시간이 길어지면, exactly-once semantics 전략 때문에 추가 요청들을 실행시키지 않고 계속 버려야한다. 즉 순차처리를 강요하고 있는데, 앞선 요청이 끝나지 않은 상태에서는 메세지 합의가 더 빨리 진행되더라도 실행시키지 않는다. (linearizability) DoS 에 취약함! 이 부분을 optimistic하게 더 개선할 수 있지 않을까? 언제 도착할 지 모르기 때문에 힘들듯..
- primary 노드가 악의적으로 사용자 요청을 조작하여 전파하는 경우 -> 클라이언트가 자신의 요청에 대한 서명이나 MAC 등을 사용해야함.
- 새로운 노드가 참가하면, view-change 를 위해 모든 노드에게 그 사실을 전파해야함. Dynamic 하게 노드들이 참가하고 빠지는 환경에서는 추가적인 작업이 필요함.