Bitcoin 노드의 boostrap 프로세스와 Bitcoin 프로토콜 소개
목차
Introduction #
KAIST NetS&P 연구실에서 학부 인턴으로 일하는 동안, 분산 네트워크에 비트코인 노드가 처음 join할 때 어떻게 통신하는지 알아내야 했습니다. 구체적으로, 이 초기 연결 중에 노드와 known 호스트 또는 seed 노드 간에 어떤 정보가 교환되는지 이해하고 싶었습니다. 이를 조사하기 위해 Wireshark를 사용하여 패킷을 캡처하고 통신 프로세스를 분석했었습니다. 저는 비트코인 노드에 필요한 handshake에는 위에서 자세히 설명한 대로 비트코인 commands 혹은 messages들이 포함된다는 것을 알게 되었습니다.
이 과정에서 교환되는 명령과 프로토콜은 신뢰할 수 있는 연결과 데이터 공유를 구축하는 데 중요합니다. 밑 내용은 Bitcoin Protocol 및 BEP 공식 문서를 주로 참조했습니다.
Bitcoin protocol #
Messages #
비트코인 노드는 _비트코인 프로토콜_을 사용하여 통신하며, 이는 TCP 위에 구축된 프로토콜 문서를 따릅니다. 비트코인 프로토콜의 Messages들은 아래 표와 같이 공통 구조를 가지고 있습니다.
+) 거의 모든 정수는 Little endian 형식으로 인코딩됩니다. 오직 IP나 포트 번호는 Big endian으로 인코딩됩니다. 모든 필드 크기는 byte의 개수를 나타냅니다.
필드 크기 | 설명 | 데이터 타입 | 비고 |
---|---|---|---|
4 | magic | uint32_t | REGTEST의 경우: 0xDAB5BFFA |
12 | command | char[12] | NULL 패딩 |
4 | length | uint32_t | payload bytes 길이 |
4 | checksum | uint32_t | sha256(sha256(payload)) 의 첫 4byte |
? | payload | uchar[] | 실제 데이터 |
version #
자신의 버전을 알립니다.
wtxiderelay #
verack
이전에 전송됩니다.- 프로토콜 버전은 70016 이상이어야 합니다.
Payload #
이 명령어에 대한 빈 페이로드
sendaddrv2 #
BIP155
addrv2
를 addr
보다 선호하여 수신합니다.
version
에 대한 응답으로 반드시 전송해야 합니다.- 그리고
verack
이전에 전송해야 합니다.
verack #
version
에 대한 응답으로 전송됩니다.
getaddr #
활성화된 peers에 대한 정보를 요청합니다.
sendcmpct #
- payload 길이는 9입니다.
- 프로토콜 버전은 70014 이상이어야 합니다.
Payload (9bytes) = 1byte (boolean) + 8bytes
예시 Payload: 0 2 0 0 0 0 0 0
- 첫 번째 및 두 번째 byte가 다음과 같은 경우:
1 과 1
→cmpctblock
으로 인한 새로운 블럭 (BIP130)0 과 *
→inv
과headers
으로 인한 새로운 블럭 (BIP130)* 과 1이 아닌 것
→ 메시지를 수신하지 않음
ping #
TCP 연결이 유효함을 확인하기 위해 랜덤 nonce를 보냅니다.
pong #
ping에서 nonce를 사용하여 ping에 대한 응답을 보냅니다.
getheaders #
peer에게 headers
메시지를 요청합니다.
예시 Payload.
- version:
70016
- hash_count:
1
- block_locator_hashes(=~ starting hash):
[GENESIS_BLOCK_HASH]
- hash_stop(=~ stop_hash):
0
0으로 설정되면 가능한 한 많은 블록을 요청합니다 (최대 2000개)
따라서 getheaders
메시지는 대칭 노드에게 block_locator_hashes
부터 hash_stop
까지 블록 해시를 전송하도록 요청합니다.
Payload #
필드 크기 | 설명 | 데이터 타입 | 비고 |
---|---|---|---|
4 | version | uint32_t | 프로토콜 버전 |
1+ | hash count | var_int | block locator hash 개수 |
32+ | block locator hashes | char[32] | block locator 객체 |
32 | hash_stop | char[32] | 원하는 마지막 block header hash |
feefilter #
제한된 memepool로 인하여, 특정 값 이하의 수수료를 가진 트랜잭션에 대한 inv
를 피어에게 전송하지 않도록 지시합니다.
- 프로토콜 버전은 70013 이상이어야 합니다.
headers #
getheaders
메시지에 대한 블록 헤더 응답을 반환합니다.
sendheaders #
inv
보다 headers
메시지를 선호하여 수신합니다.
- 프로토콜 버전은 70012 이상이어야 합니다.