Tendermint

Tendermint 합의 알고리즘

텐더민트 합의 알고리즘은 코스모스 블록체인의 엔진이자, 많은 시스템에서 안전하고 일관되게 애플리케이션을 복제하기 위한 소프트웨어이다.

안전하고: 시스템의 최대 1/3이 임의의 방식으로 실패하더라도 텐더민트가 작동한다

일관되게: 실패하지 않은 모든 시스템은 동일한 트랜잭션 로그를 보고 동일한 상태를 계산한다

안전하고 일관된 복제는 분산 시스템의 근본적인 문제이다.

악의적인 것을 포함하여 임의의 방식으로 실패하는 시스템을 허용하는 능력을 BFT(비잔틴 실패 허용)라고 한다.

텐더민트는 블록체인 합의 엔진과 일반 애플리케이션 인터페이스의 두 가지 주요한 기술 컴포넌트들로 구성된다.

텐더민트 코어라는 합의 엔진은 동일한 트랜잭션이 동일한 순서로 모든 시스템에 기록된다는 것을 보증한다.

애플리케이션 블록체인 인터페이스(ABCI, Application BlockChain Interface)라는 애플리케이션 인터페이스를 사용하면 모든 프로그래밍 언어로 트랜잭션들을 처리할 수 있다.

고급 키-값 저장소 혹은 기발한 스크립팅 언어처럼 상태 머신이 내장되어 미리 패키징되어 제공되는 다른 블록체인이나 합의 솔루션과 달리, 개발자들은 자신에게 적합한 프로그래밍 언어나 개발 환경으로 작성된 애플리케이션의 BFT 상태 머신 복제에 텐더민트를 사용할 수 있다.

텐더민트는 특징은 다음과 같다.

  • 텐더민트는 비잔틴 장애 허용이다. 즉, 최대 1/3 실패만 허용하지만, 이러한 장애에는 해킹이나 악의적인 공격을 비롯한 임의의 동작들이 포함될 수 있다.

  • 고급 키-값 저장소와 같은 특정 응용 프로그램을 지정하지 않는다. 대신 임의의 상태 머신 복제에 중점을 둠으로 개발자는 키-값 저장소에서 암호화폐, 전자 투표 플랫폼 등에 이르기까지 자신에게 적합한 애플리케이션 로직을 구축할 수 있다.

ABCI Overview

애플리케이션 블록체인 인터페이스(ABCI, Application BlockChain Interface)는 모든 프로그램 언어로 작성된 애플리케이션의 비잔틴 장애 허용(BFT) 복제를 허용한다.

**Motivation 지금까지, 비트코인과 같은 모든 블록체인 “스택"들은 모놀리식 설계를 가졌었다. 즉, 각 블록체인 스택은 분산 원장의 모든 문제를 처리하는 단일 프로그램이다. 여기에는 P2P 연결, 트랜잭션의 "mempool" 브로드캐스팅, 가장 최근 블록에 대한 합의, 계정 잔액, 튜링-완전 계약, 사용자 수준 권한 등이 포함된다. **

컴퓨터 과학에서 모놀리식 아키텍처를 사용하는 것은 일반적으로 좋지 않은 관행이다. 코드의 컴포넌트를 재사용하기 어렵게 만들고 그렇게 하려고 시도하면 코드베이스의 분기(fork)에 대한 복잡한 유지 관리 절차가 발생한다. 코드베이스가 모듈식으로 설계되지 않고 "스파게티 코드"로 인해 문제가 있는 경우 특히 그렇다.

모놀리식 설계의 또 다른 문제는 블록체인 스택의 언어로 제한된다는 것이다. 또는 그 반대도 마찬가지이다. 완전 튜링 바이트 코드 가상 머신을 지원하는 이더리움의 경우, 해당 바이트 코드로 컴파일되는 언어로 제한한다. 오늘날, 그것들은 Serpent와 Solidity이다.

대조적으로, 우리의 접근 방식은 특정 블록체인 응용 프로그램의 응용 프로그램 상태 세부 정보에서 합의 엔진과 P2P 계층을 분리하는 것이다. 소켓 프로토콜로 구현되는 인터페이스에 대한 애플리케이션의 세부 정보를 추상화하여 이를 수행한다.

Intro to ABCI

Tendermint Core("합의 엔진")는 ABCI를 만족하는 소켓 프로토콜을 통해 애플리케이션과 통신한다.

비트코인은 각 노드가 완전히 감사된 UTXO(Unspent Transaction Output) 데이터베이스를 유지 관리하는 암호화폐 블록체인이다. ABCI 위에 비트코인과 같은 시스템을 만들고 싶다면 Tendermint Core는 다음과 같은 것들을 담당한다.

  • 노드 간 블록 및 트랜잭션 공유

  • 거래의 표준/불변 순서 설정(블록체인)

응용 프로그램은 다음을 담당한다.

  • UTXO 데이터베이스 유지 관리

  • 트랜잭션의 암호화 서명 검증

  • 트랜잭션이 존재하지 않는 트랜잭션을 사용하는 것을 방지

  • 클라이언트가 UTXO 데이터베이스를 쿼리할 수 있도록 한다.

텐더민트는 애플리케이션 프로세스와 합의 프로세스 사이에 매우 간단한 API(예: ABCI)를 제공하여 블록체인 설계를 분리할 수 있다.

ABCI는 코어에서 애플리케이션으로 전달되는 3가지 기본 메시지 유형으로 구성된다. 애플리케이션은 해당 응답 메시지로 응답한다.

3가지 기본 메시지 유형은 다음과 같다.(참고: ABCI Message Types)

DeliverTx Message

DeliverTx 메시지는 애플리케이션의 일꾼이다.

블록체인에서 각 트랜잭션은 메시지를 함께 전송한다.

애플리케이션은 현재 상태, 애플리케이션 프로토콜 그리고 트랜잭션의 암호화 증명에 대해 DeliverTx와 함께 받은 각 트랜잭션에 대한 검증이 필요하다.

그리고 검증된 트랜잭션은 (예를 들어) 키-값 저장소에 바인딩되거나 혹은 UTXO 데이터베이스의 업데이트에 의한 애플리케이션 상태를 업데이트할 필요가 있다.

CheckTx Message

CheckTx 메시지는 DeliverTx와 유사하지만, 그것은 단지 트랜잭션의 검증만을 위한 것이다.

텐더민트 코어의 멤풀(mempool)은 CheckTx와 함께 트랜잭션의 타당성을 먼저 체크하고, 단지 유효한 트랜잭션을 피어들에게 전달하기만 한다.

예를 들어, 애플리케이션은 트랜잭션안에 있는 증가 시퀀스 번호를 체크해야하고 그 증가 시퀀스 번호가 예전 것이라면 CheckTx에 에러를 리턴한다.

또는 모든 트랜잭션과 함께 갱신해야 하는 기능 기반 시스템을 사용할 수 있다.

Commit Message

Commit 메시지는 다음 블록의 헤더안에 위치시켜야 할 현재 애플리케이션 상태에 암호화 커밋을 계산하는데 사용된다.

이것은 몇 가지 편리한 속성을 가지고 있다.

해당 상태 업데이트의 불일치는 이제 전체 클래스의 프로그래밍 오류를 포착하는 블록체인 포크로 나타난다.

이것은 또한 블록 해시를 확인하여 Merkle-hash 증명을 확인할 수 있고 블록 해시가 쿼럼에 의해 서명된다는 점에서 안전한 경량 클라이언트의 개발을 단순화한다.

애플리케이션에 대한 여러 ABCI 소켓 연결이 있을 수 있다.

텐더민트 코어는 애플리케이션에 3개의 ABCI연결을 형성한다.

하나는 멤풀에 브로드캐스팅할 때 트랜잭션의 검증을 위해, 두 번째는 블록 제안을 실행할 합의 엔진을 위해, 그리고 세 번째는 애플리케이션 상태의 질의를 위해 형성된다.

그것은 아마도 애플리케이션 설계자들이 뭔가 유용한 것을 하는 블록체인을 만들기 위해 그들의 메시지 핸들러를 매우 조심해서 설계해야 한다는 증거이지만 이 아키텍처는 시작할 장소를 제공한다는 것은 분명하다.

아래 다이어그램은 ABCI를 통한메시지의 흐름을 표현한다.

Consensus Overview

텐더민트는 이해하기 쉽고, 대부분 비동기식이고, BFT 합의 프로토콜이다. 프로토콜은 아래 처럼보이는 단순 상태 머신을 따른다.

프로토콜 참여자들은 검증자(Validator)라 불린다.

그들은 교대로 트랜잭션 블록을 제안하고 투표를 한다.

블록들은 각 높이(height)에 하나의 블록으로 한 체인에 커밋된다.한 블록은 커밋에 실패할 수 있다.

이 경우 프로토콜은 다음 라운드로 이동하고, 새로운 검증자가 해당 높이에 대한 블록을 제안 한다.

블록을 성공적으로 커밋하려면 두 단계의 투표가 필요하다.

우리는 그것들을 사전 투표와 사전 커밋이라고 부른다.

동일한 라운드에서 2/3 이상의 검증인이 동일한 블록에 대해 사전 커밋하면 블록이 커밋된다.

검증자는 폴카 댄스처럼 뭔가를 하기때문에 폴카를 하는 커플의 그림이 있다.

동일한 블록에 사전 투표한 검증자가 2/3보다 많을 때, 우리는 그것을 폴카라 부른다.

모든 사전 커밋은 동일한 라운드에서 한 폴카로 정당화 되어야 한다.

검증자는 현재 제안자가 오프라인이거나 네트워크가 드려지는 등 많은 이유로 블록을 커밋하는 데 실패할 수 있다.

텐더민트는 검증자를 스킵할 것을 설정할 수 있게 한다.

검증자는 다음 라운드로 넘어가기 위해 투표전에 제안자로 부터 완성된 제안 블록을 받기위해 잠시 기다린다.

타임아웃에 대한 이러한 의존성은 텐더민트를 비동기식 프로토콜이 아닌 약한 동기식 프로토콜로 만드는 이유이다.

그러나 프로토콜의 나머지는 비동기이고, 검증자는 단지 검증자 세트의 2/3보다 많은 검증자로 부터 들은 후 진행된다.

텐더민트를 단순하게 만드는 요소는 다음 라운드로 스킵할때와 동일한 메커니즘으로 블록을 커밋한다는 것이다.

검증자의 1/3미만이 비잔틴이라고 가정할 때 텐더민트는 안전이 결코 침해되지 안는다는 것을 보증한다.

그것은 검증자가 동일한 높이에서 충돌하는 블록을 절대 커밋하지 않는다는 것이다.

이를 위해 흐름도에서 따를 수 있는 경로를 조절하는 몇 가지 잠금 규칙을 도입한다.

검증자가 하나의 블록을 사전 커밋 할 때, 그것은 그 블록에서 잠긴다. 그리고,

  1. 잠겨 있는 블록에 대해 사전 투표를 해야한다.

  2. 이후 라운드에서 해당 블록에 대한 폴카가 있는 경우에만 잠금을 해제하고 새 블록에 대해 사전 커밋할 수 있다.

Last updated