씨레벨 — 수천 건의 스마트 컨트랙트 병렬 처리

솔라나를 세계 최고 성능의 블록체인으로 만들어준 8가지 핵심 기술 중 하나인 씨레벨에 대해 소개 드립니다

GM Chung
솔라나 한국
7 min readMay 22, 2020

--

솔라나는 세계 최고의 성능을 자랑하는 무허가형 블록체인입니다. 현재 진행 중인 솔라나의 테스트넷은 200개의 독립된 GPU 노드들로 구성되었으며, GPU를 통해 초당 50,000건의 트랜잭션을 처리하고 있습니다. 높은 성능을 달성하기 위해 여러 최적화 및 새로운 기술이 필요로 했으며, 그 결과 블록체인 개발 분야에 있어 기존에는 찾아보지 못할 수준의 네트워크 수용력을 이뤄냈습니다.

솔라나 네트워크를 가능하게 해준 8가지 주요 혁신들은 다음과 같습니다:

이번 시간엔 솔라나의 병렬 스마트 컨트랙트 런타임인 씨레벨(Sealevel)에 대해 알아보겠습니다. 시작하기에 앞서 알아야 될 사항으로는, 이더리움 가상머신(EVM)과 이오스(EOS)의 WASM 기반 런타임은 모두 단일 스레드(Thread)를 갖추고 있다는 점입니다. 즉, 한 번에 한 컨트랙트 씩 블록체인 상태 변환이 일어남을 의미합니다. 솔라나는 밸리데이터가 가용할 수 있는 코어(Core)들을 활용해 수천, 수만 개의 컨트랙트들을 병렬 처리할 수 있는 런타임을 적용하였습니다.

솔라나가 트랜잭션들을 병렬 처리할 수 있는 이유는 솔라나에서는 트랜잭션이 읽고 쓸 상태들을 실행하는 와중에도 모두 표현(describe)하고 있기 때문입니다. 이를 통해 서로 겹치지 않는 트랜잭션들을 동시에 처리할 수 있게 될 뿐만 아니라, 동일한 상태를 읽기만 하는 모든 트랜잭션들 또한 동시에 처리할 수 있게 됩니다.

프로그램과 계정

솔라나의 계정 데이터베이스, 클라우드브레이크(Cloudbreak)는 공개키를 계정에 맵핑(Mapping)한 것입니다. 계정은 바이트 벡터인 데이터와 잔액에 대한 정보를 담고 있습니다. 계정은 “소유자(Owner)”라는 란이 존재하며, 계정의 상태 변환을 관리하는 프로그램의 공개키를 의미합니다. 프로그램은 코드만 가질 뿐, 상태는 없습니다. 프로그램의 상태 변환은 자신에게 할당된 계정의 데이터 벡터에 의해 일어나게 됩니다.

  1. 프로그램은 자신이 소유한 계정 정보만 변경할 수 있습니다.
  2. 프로그램은 자신이 소유한 계정에서만 인출할 수 있습니다.
  3. 모든 프로그램은 모든 계정에 크레딧(Credit)을 부여할 수 있습니다.
  4. 모든 프로그램은 모든 계정을 읽을 수 있습니다.

기본적으로, 모든 계정들은 시스템 프로그램(System Program)의 소유인 상태로 시작됩니다.

  1. 오직 시스템 프로그램만 계정 소유권을 부여할 수 있습니다.
  2. 오직 시스템 프로그램만 초기화되지 않은(zero-initialized) 데이터를 할당할 수 있습니다.
  3. 계정의 소유권은 계정당 단 한 번만 할당할 수 있습니다.

로더 프로그램(Loader Program)은 사용자 정의 프로그램(User-defined Program)을 불러올 수 있습니다. 로더 프로그램은 계정이 가지고 있는 데이터를 실행할 수 있도록 마크할 수 있습니다. 사용자는 커스텀 프로그램을 불러오기 위해 다음의 트랜잭션들을 수행합니다:

  1. 새로운 공개키 생성.
  2. 생성된 키에 코인 송금.
  3. 시스템 프로그램에게 메모리 할당 지시.
  4. 시스템 프로그램에게 계정을 로더(Loader)에게 지정할 것을 지시.
  5. 조각난 메모리에 바이트코드 업로드.
  6. 로더 프로그램에게 메모리를 실행 가능하도록 마크할 것을 지시.

이 단계에서, 로더(loader)는 바이트코드를 검증하고, 바이트코드를 불러온 계정을 실행 가능 프로그램으로 사용할 수 있게 됩니다. 그리고 새로운 계정들은 사용자 정의 프로그램이 소유한 것으로 마크될 수 있습니다.

이때 알아야 할 중요한 점은 프로그램이 코드라는 것이며, 키값에는 오직 해당 프로그램에만 쓰기 권한이 있는 부분적인 키들이 존재한다는 것입니다.

트랜잭션

트랜잭션은 지시사항 벡터(instruction vector)를 지정합니다. 각 지시사항에는 프로그램, 프로그램 지시사항, 그리고 트랜잭션에서 읽고 쓰고자 하는 계정 리스트가 담겨있습니다. 이러한 인터페이스는 낮은 수준의 운영체제 인터페이스를 사용하는 기기로부터 영감을 받아 디자인되었습니다:

size_t

readv(int d, const struct iovec *iov, int iovcnt);

struct iovec {

char *iov_base; /* Base address. */

size_t iov_len; /* Length. */

};

readv나 writev 같은 인터페이스들은 커널에게 사용자가 읽고 쓰기에 필요한 모든 메모리를 앞서 미리 알려줍니다. 만일 기기가 사용 가능할 만큼의 여유가 있다면, 운영체제는 기기를 미리 확보(prefetch)하고, 준비한 뒤 작업을 동시에 실행할 수 있게 됩니다.

솔라나에서 각 지시사항은 가상머신에 어떤한 계정들을 읽고 쓸 것인지 미리 알려줍니다. 바로 이것이 솔라나 가상머신 최적화에 있어 가장 근본적인 부분입니다.

  1. 수백만에 달하는 대기 중인 트랜잭션들의 구분.
  2. 중복되지 않는 모든 트랜잭션들의 병렬 스케쥴링.

여기에 더해 솔라나는 CPU와 GPU 하드웨어 디자인을 활용할 수 있습니다.

SIMD 지시사항은 단일 코드가 다수의 데이터 스트림 상에서 실행될 수 있게 합니다. 즉, 솔라나만의 특유한 디자인 상에서 씨레벨을 통해 추가적인 최적화가 가능하다는 것을 의미합니다:

  1. 프로그램 ID에 따라 모든 지시사항 분류.
  2. 모든 계정에서 같은 프로그램을 동시에 실행.

이 내용이 얼마나 엄청난 최적화인지 확인하고 싶다면, CUDA 개발자 가이드를 참고해보시길 바랍니다:

“CUDA 아키텍쳐는 확장 가능한 멀티 스레드 스트리밍 멀티프로세서(Streaming Processors, SMs) 어레이를 기반으로 개발되었습니다. CUDA 프로그램이 호스트 CPU 상에서 커널 그리드를 호출하면, 그리드 블록들이 열거되어 사용 가능한 실행 용량을 갖추고 있는 멀티프로세서에게 분배됩니다.”

현재의 엔비디아(Nvidia) GPU는 4000개의 CUDA 코어가 있지만, 약 50개의 멀티프로세서를 갖고 있습니다. 멀티프로세서는 한 번에 하나의 프로그램 지시사항만을 실행할 수 있지만, 같은 지시사항을 80개의 다른 입력값으로 병렬 실행이 가능합니다. 때문에 씨레벨에서 로드한 모든 트랜잭션들이 같은 프로그램 지시사항을 호출할 시 (예시: 크립토키티의 BreedCats), 솔라나는 사용할 수 있는 모든 CUDA 코어에 걸쳐 모든 트랜잭션들을 동시다발적으로 처리할 수 있습니다.

좋은 성능에는 공짜란 없습니다. 때문에 SIMD 최적화를 하기 위해, 실행된 지시사항들은 소수의 브랜치를 내포해야 하며, 모두 같은 브랜치를 갖추고 있어야 합니다. 멀티프로세서는 실행문이 배치(Batch) 내에 주어지는 가장 느린 경로에 종속됩니다. 이러한 전제에도 불구하고, 씨레벨을 통한 병렬 처리 방식은 단일 스레드 런타임과 비교했을 때, 블록체인 네트워크 작동 방식의 근본적인 면을 변화시켰으며 이를 통해 매우 우수한 처리량과 사용성을 이뤄냈습니다.

솔라나 공식 커뮤니티에 참여하세요

공식 홈페이지 | 텔레그램 | 디스코드 | 트위터

--

--