플라네타리움 엔지니어링 스낵

Libplanet 0.6 릴리스

(한국어English)

안녕하세요. 저희 팀은 Libplanet의 여섯 번째 마이너 버전인 0.6 버전을 릴리스했습니다.

Libplanet은 분산 P2P로 돌아가는 온라인 멀티플레이어 게임을 만들 때, 그러한 게임들이 매번 구현해야 하는 P2P 통신이나 데이터 동기화 등의 문제를 푸는 공용 라이브러리입니다.

0.6 버전에서는 Libplanet의 네트워크 구성과 관련한 큰 변화가 있었고, 잘 관측되지 않았던 버그들을 다수 수정했습니다. 이 글에서는 0.6 버전의 주요 변경 사항들에 대해 다루겠습니다.

Kademlia 분산 해시 테이블 적용

기존의 Libplanet에서는 각 피어가 네트워크상의 모든 피어들을 전부 관리했습니다. 생성한 데이터를 전파하는 블록체인의 특성상 이와 같은 방법은 네트워크에 적은 수의 피어들이 접속해 있다면 그럭저럭 작동하지만, 피어의 수가 많을 때는 네트워크 통신 문제가 생기게 됩니다.

위 문제를 해결하여 더욱 많은 피어들을 관리하기 위해 분산 해시 테이블 기법의 하나인 Kademlia 프로토콜이 적용되었습니다. Kademlia 분산 해시 테이블의 작동 원리가 궁금하시다면 Kademlia 분산 해시 테이블 적용기를 참고해 주세요.

트랜잭션 전파 방식 변경

어떤 클라이언트가 트랜잭션을 생성했을 때 해당 클라이언트는 자신의 라우팅 테이블이 가진 있는 피어들에 해당 데이터를 전파하고, 이를 통해 블록체인 네트워크상의 모든 피어가 동기화됩니다.

기존 Libplanet은 트랜잭션을 일정 주기마다 전파하는 방식으로 작동했었고, 각 피어가 네트워크 위에 존재하는 모든 피어들의 정보를 갖고 있었기 때문에 한 번의 전파로 모든 피어가 동기화되었습니다. 그러나 Kademlia 분산 해시 테이블이 적용되면서 한 번의 전파만으로는 모든 피어가 동기화되었음을 보장할 수 없게 되었습니다. 각 피어는 전파받은 데이터를 다시 전파하는 방식으로 네트워크에 퍼트리는데, 트랜잭션 전파가 일정 주기마다 실행되었기에 운이 나쁘다면 네트워크가 동기화되는 데 많은 시간이 소요되었습니다.

따라서 이 패치에서는 트랜잭션을 전파받았을 때 즉시 전파하게 로직을 수정하여 네트워크 동기화 과정이 오래 지연되는 것을 방지하였습니다.

한 블록 내 트랜잭션들의 실행 순서 보장

한 블록 안에 여러 개의 트랜잭션이 포함될 때, 모든 클라이언트에서 같은 순서로 액션이 실행하는 것을 보장해 주어야 합니다. 그러면서도 블록을 마이닝 하기 전까지는 그 실행 순서를 예측할 수 없어야 합니다.

이번 업데이트에서는 위의 조건을 만족하기 위해 블록의 트랜잭션을 담을 때, 블록의 Hash 값과 트랜잭션의 Id를 이용해 순서를 정렬하여 모든 클라이언트에서 액션이 같은 순서로 실행되는 것이 보장될 수 있게 하였습니다.

비동기 블록 마이닝

Libplanet은 작업 증명 시스템을 기반으로 블록을 합의하기 때문에, 블록을 생성하는 마이닝 과정에서 다량의 CPU 자원을 소모합니다. 기존에는 블록의 Nonce를 찾는 Hashcash.Answer() 함수가 동기 함수였기 때문에 실행 중인 스레드가 차단되었고, 작업을 도중에 중단하는 것이 어려웠습니다.

이번 패치를 통해 BlockChain<T>.Mine()이 비동기 함수가 되어 사용자가 CancellationToken을 주어 원하는 시점에 중단시킬 수 있게 되었습니다. 또한 마이닝 도중 블록체인의 팁이 변경되었을 때 외부에서 구독 가능한 BlockChain<T>.TipChanged 이벤트가 불리고, 해당 이벤트가 발생할 시 진행하던 마이닝이 중단되게 됩니다.

그 외

그 외의 여러 가지 변경 사항은 전체 변경 내용에서 확인하실 수 있습니다.

이번 변경 사항이나 Libplanet에 대해 궁금한 점이 있으시다면 언제든 저희 팀이 상주해 있는 디스코드 대화방에 방문해 주세요!

플라네타리움은 게임에 특화된 오픈 소스 P2P 라이브러리 Libplanet과, 그 위에서 중앙 서버 없는 온라인 게임 〈나인 크로니클〉을 만들고 있습니다. 저희와 흥미로운 기술적 도전을 함께 하실 분들을 모시고 있습니다. 지금 인재 영입 페이지를 확인해주세요!