KEEP!T Column: [ Opensource Blockchain Engine, IT-CHAIN] 01. P2P 네트워크와 합의 알고리즘
현재 블록체인 기술은 가장 빠르게 확산되고 있는 유망한 기술 중 하나이며, Bitcoin, Ethereum, EOS 등 수많은 외산 블록체인 엔진들이 입지를 굳혀가는 가운데 국내에서도 블록체인 코어 기술을 위한 많은 연구가 진행이 되고 있습니다.
이번 글에서는 수많은 블록체인 엔진들 중에서도 Lightweight Customizable Chain을 목표로 활발하게 개발이 진행중인 국내 오픈소스 블록체인 엔진인 IT-CHAIN에 대해 살펴보고자 합니다.
본 포스트는 연재 형식으로 IT-CHAIN의 핵심적인 component인 p2p, consensus, blockchain, authentication, txpool, iCode 를 다루는 총 4~6편의 포스트로 이루어 질 예정이며, 오늘은 it-chain의 전체적인 구조와 더불어 그 첫번째 component 인 p2p component에 대한 소개를 하고자 합니다.
What is it-chain?
많은 블록체인 엔진들 중에서 it-chain을 소개하게 된 계기는 무엇보다 구조적으로 매우 직관적이고 이해하기 쉽게 설계되어 있기 때문입니다. 가령, ethereum과 hyperledger처럼 당장 상용화를 목적으로 개발이 진행중인 엔진들은 실용적 문제들에 봉착하여 다양한 기법과 최신 기술을 도입하여 코드를 당장 이해하기 어려움이 있기에 블록체인을 처음 접하는 사람들의 경우 전체 코드를 한눈에 이해하는 것은 매우 어려운 일이 아닐 수 없습니다. 하지만, it-chain은 전체 설계 및 핵심적인 컴포넌트들이 비교적 상세하게 문서화가 되어 있고, 블록체인의 핵심이 되는 기본적인 기능만을 구현하였기 때문에, 블록체인 엔진이 움직이는 큰 그림을 보다 직관적이고 쉽게 이해할 수 있는 장점이 있습니다. 만약 블록체인 엔진 개발에 관심이 있는 엔지니어라면 그 시작으로 it-chain 의 구현을 살펴보는 것을 추천합니다. (it-chain의 github 주소, https://github.com/it-chain/engine)
it-chain이 지향하는 바는 블록체인을 개발하는 누구든지 쉽고 가볍게 커스터마이징이 가능한 엔진을 만드는 것 입니다. 만약 누군가가 ethereum의 코드를 가져다가 자신만의 블록체인 엔진을 만든다고 한다면 그것은 매우 어려운 일일 것 입니다. 합의 알고리즘 하나를 변경하더도 관련된 모든 코드에 대한 이해가 필요하며 얼기설기 얽혀있는 수많은 코드들을 재정리 해야 합니다. 하지만, it-chain 은 event-sourcing을 기반으로 모든 동작이 event를 기반으로 이루어 지기에 다른 구성요소들의 동작에 구애받지 않고 원하는 파트만 손쉽게 변형하여 자신만의 engine을 만들 수 있습니다.
it-chain의 전체 구조
it-chain
은 6개의 독립적으로 동작하는 핵심 컴포넌트들로 구현되며, 각각은 AMQP(Asynchronous Message Queue Protocol) 를 통해 커뮤니케이션을 합니다. AMQP는 이벤트 버스로서 각 컴포넌트들에서 일어난 모든 일들은 이벤트 형태로 전파되어 다른 컴포넌트들이 해당 이벤트에 맞는 동작을 수행함으로써 전체 기능이 동작하는 방식입니다.
다음은 it-chain의 각 컴포넌트의 간단한 역할을 보여줍니다.
- TxPool 컴포넌트: 트랜잭션을 임시로 저장하고 관리하는 컴포넌트로, 합의되어 블록에 저장되지 않은 트랜잭션들을 모아둡니다.
- Consensus 컴포넌트: 합의를 담당하는 컴포넌트이며, 현재는 PBFT(Practical Byzantine Fault Tolerance) 알고리즘을 따릅니다.
- BlockChain 컴포넌트: 블록을 생성하고 관리하는 컴포넌트입니다.
- P2P 컴포넌트: 네트워크의 참여하는 Peer들을 찾고, 유지하는 컴포넌트입니다.
- Auth 컴포넌트: 각종 인증을 담당합니다.
- iCode 컴포넌트: it-chain의 스마트 컨트랙트인 iCode 관련 기능을 담당합니다.
It-chain의 Peer to Peer 네트워크
이번 포스트에서는 it-chain에서 여러 노드들 사이의 네트워크 정보를 동기화하고 커넥션을 관리하는 p2p component와 노드 사이의 합의를 이루는 consensus 컴포넌트에 대해 알아보고자 합니다.
먼저, P2p 컴포넌트가 하는 일은 다음과 같습니다.
- 블록체인 네트워크 내의 다른 노드들의 존재를 인지하고 저장합니다.
- 네트워크 내의 노드들 사이의 connection정보와 ip 주소 정보를 Peer 라는 이름으로 저장하고 여러 Peer 들의 집합인 PeerTable 을 형성합니다.
- 모든 노드들이 네트워크 내의 모든 노드들에 대한 정보인 PeerTable 을 공유하고 동기화 합니다.
예를 들어 현재 블록체인 네트워크가 A, B, C 노드로 이루어져있다고 가정해 봅시다.
여기서 D라는 새로운 노드가 A라는 노드에게 접속을 요청을 하게 된다면 D 노드는 A 노드의 정보만을 알고 있게 될 것이며, 마찬가지로 B, C 노드도 D노드에 대한 정보를 알지 못할 것입니다.
하지만 private 블록체인에서는 모든 노드들이 계속해서 서로 통신을 위해 연결되어 있어야 하기 때문에 새롭게 연결된 노드의 정보를 다른 노드들에게 전파해 주어야 하며 각 노드들은 전체 네트워크에 대한 일관된 정보를 공유해야 합니다.
네트워크 정보는 어떻게 저장되나요?
p2p 컴포넌트 내의 연결 정보는 Peer 라는 이름으로 저장이 되며, 그 안에는 특정 노드와의 연결에 대한 고유값인 connectionId와 상대 노드의 ip 주소 를 저장합니다.
가령 A, B, C 노드로 구성된 네트워크가 있다면 A 노드는 B, C 노드와 연결됨에 따른 고유한 connection과 B, C 노드의 ip 주소를 Peer A, Peer B 라는 이름으로 저장하며 모든 노드는 이러한 peer들의 정보를 peer 들의 정보의 집합인 PeerTable 에 저장합니다.
네트워크 정보는 어떻게 공유되나요?
블록체인 네트워크에 새로운 노드가 접속하는 것은 네트워크 내의 특정 노드에게 연결을 요청하는 것에서 시작됩니다.
노드 A, B, C 로 구성된 네트워크에서 D라는 노드가 접속되는 상황을 가정해 봅시다.
노드 D는 A, B, C 노드 중 임의의 노드인 A 노드에게 연결을 요청하고 만약 연결이 이루어 진다면 노드 D의 정보는 노드 A의 PeerTable 에 저장되고, 노드 A 는 새롭게 바뀐 PeerTable 을 노드 D에게 전달해 줍니다.
노드 D는 A에게 받은 PeerTable을 살펴보고 아직 자신이 연결하지 않은 노드인 B와 C 노드에 대해 알게되고 해당 노드의 ip 주소로 연결을 요청하게 됩니다.
B, C 노드가 새로 접근한 노드인 D 노드에게 연결을 요청받고 승인하는 것으로 네트워크 내의 모든 노드는 새로 접근한 노드인 D 노드와 연결이 이루어지게 됩니다.
It-chain의 Consensus 컴포넌트
블록체인에서 핵심은 바로 consensus 입니다.
consensus 컴포넌트는 특정 블록을 생성하기 위해 다른 노드들에게 해당 블록을 생성해도 되는지 검증을 요구하고 네트워크 구성원들의 합의가 이루어지면 새로운 블록을 생성합니다.
It-chain 에서 이러한 합의 알고리즘은 설정을 통해 간편하게 교체할 수 있으며 기본적으로 pbft 알고리즘에 따라 합의가 이루어 지게 됩니다.
pbft 합의 알고리즘
기본적인 PBFT 알고리즘은 다음과 같은 순서로 이루어지게 됩니다.
- 클라이언트가 네트워크 구성원에게 어떤 합의문에 대해 합의할 것을 요청합니다.
- 합의 요청을 받은 노드들 중 리더 노드는 네트워크 내의 모든 구성원에게 특정 합의에 대한 합의를 시작할 것을 알리는 preprepare message 를 전달합니다.
- preprepare message 를 전달받은 모든 노드는 다시 모든 노드에게 prepare message 를 전달합니다.
- 전체 네트워크 구성원들 중 정족수(2/3) 이상의 노드에게 받은 preparemessage 인 commit message 를 모든 노드들에게 전달합니다.
- 위 과정이 끝나면 모든 노드들은 정족수이상이 합의한 결과를 가지게 됩니다.
하지만 It-chain 에서는 오직 리더만이 새롭게 생성될 블록을 제안하고 실제로 생성할 수 있으므로 위 과정에서 클라이언트 및 요청 응답이 존재하지 않습니다.
It-chain에서 pbft 알고리즘의 구현
It-chain에서는 위와 같은 pbft 알고리즘 구현을 위해 다음과 같은 몇가지 개념을 도입합니다.
- Parliament: 의회, 즉, 합의에 참여할 노드들의 집합을 의미합니다.
- Representative: 대표자, 즉 합의에 참여할 실제 노드 구성원을 의미합니다.
- Leader: 의장, 즉 의회 구성원의 대표인 리더를 의미합니다.
pbft의 목적은 어디까지나 합의하고자 하는 블록에 대한 합의이기에 다음과 같은 과정에 따라 pbft 기반의 합의 알고리즘이 동작됩니다.
- 리더 노드의 consensus 컴포넌트가 블록 생성을 담당하는 blockchain 컴포넌트로 부터 합의하고자 하는 블록을 제안받습니다.
- 리더 노드는 해당 블록에 대한 합의를 진행하기 위해 현재 네트워크를 구성하고 있는 정보를 담고 있는 PeerTable 에서 전부 혹은 부분적인 노드를 선출하여 Parliament 를 구성합니다.
- 리더 노드가 Parliament 에 속한 모든 Representative 들에게 preprepare message 를 전달합니다.
- preprepare message 를 받은 모든 representative 들은 받은 정보를 통해 각자의 Parliament 를 구축하고 다른 Representative 들에게 prepare message 를 전달합니다.
- 각 Representative 들은 정족수 이상의 prepare 메세지를 받기 까지 받은 모든 prepare message 를 prepare message pool 에 저장하고 정족수 이상이 넘으면 commit message 를 전파합니다.
- 전체 의회 구성원의 1/3 이상에게 commit message를 받은 각 Representative 들은 Commit message 내의 Proposed Block 에 대한 승인을 하는 이벤트를 발생시키고 블록체인 컴포넌트는 해당 블록에 대한 검증을 시작합니다.
Proposed Block 이 confirm 되기 까지 Commit message 들은 Commit message pool 에 저장됩니다.
It-chain에서 리더의 선출
it-chain 에서의 리더 선출은 RAFT 라는 알고리즘을 통해 진행되며 consensus 컴포넌트에 구현되어 있습니다.
다음은 RAFT 알고리즘의 간단한 프로세스입니다.
- 리더가 사라지면 노드는 의회를 구성합니다.
- 150ms ~ 300ms 사이의 랜덤 값으로 모든 노드가 타이머를 동작시킵니다.
- 노드의 타이머가 다 되면 그 노드는 자신의 상태를 Candidate 으로 바꾸고
RequestVoteProtocol
을 통해 의회 내의 다른 노드에게 투표 요청 message 를 전달합니다. RequestVoteProtocol
로 메세지를 받은 노드는 아직 타이머가 다 되지 않은 경우 타이머를 리셋하고, 송신한 노드에게VoteLeaderProtocol
을 통해 메세지를 전달하여 리더로 투표합니다.- 만약 상태가 CANDIDATE 인 노드가
VoteLeaderProtocol
를 통해 다른 모든 노드에게 투표 메세지를 받는다면 그 노드는 스스로 리더가 되고 다른 모든 노드들에게 리더가 됨을 선포합니다.
위와 같은 과정을 통해 물리적으로 떨어져 있는 여러 개의 노드들이 서로 합의를 이루고 리더를 선출 할 수 있게 됩니다.
이번 포스트에서는 국내 블록체인 엔진인 it-chain 의 p2p network 와 consensus 알고리즘, 그리고 리더 선출에 대해 알아보았습니다.
다음 포스트에서는 it-chain에서 블록을 합의하는 컴포넌트인 Blockchain 컴포넌트에 대해 알아보겠습니다.
LNH
[참조] it-chain 공식 git repository
이 저작물은 크리에이티브 커먼즈 저작자표시-비영리-변경금지 4.0 국제 라이선스에 따라 이용할 수 있습니다.
Coins mentioned in post: