‘Mastering Bitcoin 2nd’ 세미나 11, 8장. The Bitcoin Network (1/2)
이번 장에서는 비트코인 네트워크와 네트워크를 구성하는 노드들에 대해서 다룹니다. 내용 상 어려운 내용은 없지만 집중도를 유지하기 위해 두 번의 세미나로 나누어 진행합니다. 이번 세미나에서는 Bloom Filters 전 까지 다룹니다.
Chapter 8. The Bitcoin Network
Peer-to-Peer Network Architecture
아래에 인용한 본문 내용을 주의를 기울여 여러 번 다시 읽어 봅니다.
Bitcoin is structured as a peer-to-peer network architecture on top of the internet. The term peer-to-peer, or P2P, means that the computers that participate in the network are peers to each other, that they are all equal, that there are no “special” nodes, and that all nodes share the burden of providing network services. The network nodes interconnect in a mesh network with a “flat” topology. There is no server, no centralized service, and no hierarchy within the network. Nodes in a P2P network both provide and consume services at the same time with reciprocity acting as the incentive for participation. P2P networks are inherently resilient, decentralized, and open.
Bitcoin’s P2P network architecture is much more than a topology choice. Bitcoin is a P2P digital cash system by design, and the network architecture is both a reflection and a foundation of that core characteristic. Decentralization of control is a core design principle that can only be achieved and maintained by a flat, decentralized P2P consensus network.
비트코인 시스템의 가장 중요한 목표가 탈중앙화이고, P2P 네트워크는 탈중앙화를 가능하게 하는 네트워크 아키텍처이기 때문에 이 둘의 만남은 필연적입니다. 비트코인 시스템의 대부분 설계 제약들은 네트워크 아키텍처로 P2P 네트워크를 선택함으로 비롯됩니다.
P2P 네트워크는 탈중앙화되어 있기 때문에 제어의 구심점이 없습니다. 구심점이 없다는 것은 쉽게 흩어질 수 있다는 것입니다. 비트코인 시스템은 특정 노드가 구심점 역할을 하도록 하지 않고 인센티브라는 메커니즘으로 노드들의 상호작용으로 부터 구심점이 생기도록 한 것(창발의 한 형태로)입니다.
P2P 네트워크는 그 자체의 특성 상 “차이”가 필연적입니다. 참여자들이 공통의 목표를 가지고 협력하는 시스템 내에는 하나의 진실(truth)만이 존재해야 합니다. 하나의 진실 만이 존재해야 하는 시스템에서 차이가 발생하면 안 되는데 P2P 네트워크는 차이가 필연적입니다. 차이가 발생하는데 하나의 진실 만이 존재해야 한다면 서로 합의를 해야 합니다. 차이가 있는 곳에 합의가 있는 것입니다.
하나의 진실 만이 존재해야 하는 시스템에서 P2P 네트워크를 선택하는 경우 ‘합의’는 필연적이 됩니다. 다시 말해 공통 원장(하나의 진실)을 요구하는 비트코인 시스템이 선택한 P2P 네트워크는 “탈중앙화된 P2P 합의 네트워크”가 될 수 밖에 없다는 것입니다.
Node Types and Roles
비트코인 네트워크에 참여하는 노드는 그림 1의 네 가지 노드 역할을 모두 하는 것이 기본입니다. 하지만 채굴을 원하지 않는 노드도 있을 수 있고, 스마트폰과 같은 자원 제약이 있는 환경에서 실행되어야 하는 노드도 있기 때문에 노드 역할을 좀 더 다양화할 필요가 있습니다. 노드의 역할을 다양하게 한다는 것은 노드의 역할에 따라 기능 설정이 가능해야 한다는 것을 의미합니다.
The Extended Bitcoin Network
비트코인 시스템에 있어 채굴 노드의 역할은 다른 역할에 비해 더 중요합니다.
비트코인 시스템은 채굴에 있어 경쟁 방식을 채택하고 있고, 경쟁에서 이기기 위해서는 고 사양의 컴퓨팅 자원을 요구합니다. 이러한 상황에서 고 사양의 컴퓨팅 자원을 갖춘 소수의 채굴 노드들만이 채굴에 참여하게 됨에 따라 채굴의 중앙화가 일어나게 됩니다. 채굴의 중앙화를 막기 위한 방법 중 하나는 채굴 풀을 지원하는 것이고 이를 위한 프로토콜이 추가됩니다. Stratum 프로토콜은 대표적인 채굴 풀 지원을 위한 프로토콜입니다.
채굴 풀을 지원함에 따라 채굴 풀 지원 프로토콜에 따르는 노드들이 기존 비트코인 네트워크에 추가되어 네트워크를 확장하게 됩니다. 그림 2와 3은 확장된 비트코인 네트워크를 보여줍니다.
Bitcoin Relay Networks
A Bitcoin Relay Network is a network that attempts to minimize the latency in the transmission of blocks between miners.
채굴이 비트코인 시스템에 있어 중요한 만큼 비트코인 시스템은 채굴을 위한 지원을 추가합니다. 비트코인 릴레이 네트워크 또한 이러한 지원의 하나로 블록 전달 지연을 최소화할 수 있도록 비트코인 네트워크에 별도의 네트워크를 추가한 것입니다.
대표적인 비트코인 릴레이 네트워크로는 FIBRE와 Falcon이 있습니다.
The network consisted of several specialized nodes hosted on the Amazon Web Services infrastructure around the world and served to connect the majority of miners and mining pools.
릴레이 네트워크는 세계 전역에 퍼질 수 있도록 지역 별로 설정된 아마존 웹 서비스 상에서 호스팅되고 있습니다. 좀 더 빠른 블록 전달을 원하는 채굴 노드나 채굴 풀 노드는 이 네트워크에 연결하면 됩니다.
릴레이 네트워크의 문제점은 네트워크를 관리하는 주체가 있다는 것입니다. 최근 FIBRE는 탈중앙하기 위한 더 많은 노력을 기울이고 있다고 합니다.
Network Discovery
한 번도 네트워크에 연결된 적이 없는 새로운 노드라면, 이미 네트워크에 연결된 적어도 하나의 노드와 연결되어야 합니다. P2P 특성 상 하나의 노드에 연결되기만 추가적으로 다른 노드들과 연결되는 것은 쉽습니다. 첫 번째 연결된 노드를 시드 노드라 합니다.
어떻게 시드 노드를 찾을 것인가가 문제입니다. 첫 번째 방법은 비트코인 클라이언트에 포함된 DNS seeds를 사용하는 것입니다. 다른 방법으로 직접 시드로 사용할 노드의 IP 주소를 직접 작성하는 것입니다.
To connect to a known peer, nodes establish a TCP connection, usually to port 8333, or an alternative port if one is provided. Upon establishing a connection, the node will start a “handshake” by transmitting a version message.
피어에 연결하려면 먼저 TCP 연결을 만들어야 합니다. 일반적으로 포트는 8333을 사용합니다. 연결이 만들어지고 나면 노드는 그림 4와 같이 기본 식별 정보를 포함한 version 메시지를 전달함으로 “handshake”를 시작합니다.
하나 이상의 연결이 만들어지고 나면 노드는 그림 5와 같이 자신의 IP 주소를 포함한 addr 메시지를 전달하거나 다른 노드들의 주수를 얻기 위해 getaddr 메시지를 전달합니다. getaddr 메시지를 받은 노드는 자신이 알고 있는 노드들의 주소를 addr 메시지로 전달합니다.
P2P 네트워크의 특성 상 노드들은 빈번하게 네트워크에 들어오고 나가기를 반복합니다. 따라서 노드는 연결된 노드들의 목록을 유지할 필요가 있습니다. 모든 노드들과의 연결을 유지하는 것은 낭비이고, 가장 최근에 연결되었던 일부 노드들과의 연결만 유지하면 됩니다. 노드가 다시 부팅되었을 때 연결정보를 사용해 빠르게 연결을 다시 구축할 수 있습니다. 연결에 트래픽이 없는 경우 노드는 정기적으로 연결을 유지하기 위해 메시지를 보냅니다. 만약 연결된 노드가 90분 이상 응답이 없으면 연결이 끊어진 것으로 가정합니다.
bitcoin-cli getpeerinfo 명령은 연결된 노드들의 정보를 제공합니다.
선택적으로 연결할 노드들을 정하고 싶은 때는 클라이언트 실행 옵션으로 connect를 사용할 수 있습니다.
- connect=<하나 이상의 IP 주소들>
Full Nodes
풀노드는 모든 트랜잭션을 가진 전체 블록체인을 유지하는 노드입니다.
풀노드는 로컬에 모든 트랜잭션을 가진 전체 블록체인을 유지하기 때문에 다른 노드에 의존하지 않고 자체적으로 트랜잭션을 검증할 수 있습니다.
Exchanging “Inventory”
풀노드가 피어에 연결된 후에 첫 번째 할 일은 동기화라고 부르는 전체 블록체인을 완전하게 구성하는 것입니다. 동기화는 새로운 노드가 네트워크에 참여하거나 노드가 네트워크에서 나갔다가 다시 들어오는 경우(종료 후 재 기동) 일어나야 합니다. 새로운 노드는 클라이언트 소프트웨어에 내장된 첫 번째 블록(제네시스 블록)만을 포함하고 있습니다.
동기화는 version 메시지를 가지고 시작합니다. version 메시지에는 노드의 현재 블록체인의 높이인 BestHeight를 포함합니다.
노드들은 그림 6과 같이 자신의 로컬 블록체인의 최상위 블록의 해시를 포함한 getblocks 메시지를 피어들과 교환합니다. getblocks 메시지를 받은 피어들 중 더 긴 블록체인을 가진 피어는 해시 값으로 전달된 블록을 기준으로 다음 500개 블록 해시를 inv(inventory) 메시지로 전달합니다. inv 메시지를 받은 노드는 getdata 메시지를 전달하고, block 메시지로 블록 데이터를 받습니다.
블록 데이터를 요청할 때는 특정 피어에 부담이 가중되지 않도록 연결된 피어 별로 “in trainsit”(요청되었지만 아직 받지 못한) 갯수를 추적합니다. “in trainsit”은 MAX_BLOCKS_IN_TRANSIT_PER_PEER를 넘지 않아야 합니다.
Simplified Payment Verification (SPV) Nodes
비트코인 시스템은 스마트폰과 같은 자원 제약이 있는 장치에서도 비트코인 네트워크에 노드로 참여할 수 있도록 SPV 노드를 지원합니다. SPV 노드는 블록 헤더만을 다운로드 합니다. 이것은 풀노드의 전체 블록체인(현재 200GB를 넘었음) 보다 1000배 정도 적습니다.
SPV 노드는 블록 헤더를 얻기 위해 그림 7과 같이 getblocks 메시지 대신 getheaders 메시지를 전송하고, headers 메시지로 블록 헤더를 받습니다. headers 메시지로 한 번에 2,000개의 블록 헤더까지 보낼 수 있습니다.
SPV verifies transactions by reference to their depth in the blockchain instead of their height.
SPV는 풀노드와 같은 방식으로 트랜잭션을 검증할 수 없습니다. 이중지불 여부를 확인하기 위해 풀노드는 트랜잭션 입력이 UTXO인지만 확인하면 되지만, SPV는 블록 헤더 만을 갖고 있기 때문에 그렇게 할 수 없습니다. 블록 헤더를 가지고는 블록의 유효성 만을 검증할 수 있습니다.
SPV는 블록에 트랜잭션이 존재하는지로(존재 증명) 트랜잭션 유효성을 검증합니다. SPV는 관심 트랜잭션이 블록에 포함된 이후 6개의 블록을 더 받아보고(depth로 접근), 6개의 블록에 관심 트랜잭션이 있지 않다면 이중 지불이 아닌 유효한 트랜잭션으로 판단합니다.
SPV는 블록 헤더 만 가지고 있기 때문에 트랜잭션이 블록에 있는지를 알 수 없기 때문에 이를 위해서도 풀 노드에 의존해야 합니다. 지갑은 SPV 노드의 대표적인 예이고, 지갑이 관심 갖는 트랜잭션들이란 대부분 지갑 주소에 관련된 것들입니다. 같은 풀노드에 반복해서 트랜잭션 정보를 요청하다보면, 풀노드는 SPV가 관심 갖는 트랜잭션들이 어떤 것인지를 알 수 있고, 이를 통해 주소와 같은 프라이버시 정보가 노출될 수 있습니다. 만약 작업증명의 노력 보다 큰 비트코인을 얻을 수 있다면 풀노드는 SPV를 속이려고 할 수 있습니다. 따라서 풀노드는 랜덤하게 선택해야 하고, 프라이버시 정보는 숨길 수 있도록 해야 합니다. 풀노드에게 트랜잭션 정보를 요청할 때 프라이버시 정보를 숨길 수 있는 방법으로 불룸 필터를 사용합니다.