비트코인/비트코인 구조

[비트코인 구조] 네트워크 요청과 응답

라이튼 2023. 1. 3. 17:15

미리 알아야 할 내용들


 

[비트코인 구조] P2P 네트워크 연결

P2P 네트워크 연결 비트코인 노드들이 서로 데이터를 주고받기 위해서는 노드들간의 P2P 네트워크 형성이 필요합니다. 이를 위해서 각 노드들은 각자 몇 개의 노드와의 연결을 형성해야 합니다.

kwjdnjs.tistory.com


네트워크 요청과 응답

 

 이번 글에서는 P2P로 연결된 다른 노드에게 각종 요청을 전송하고 응답을 받는 방법에 대해 알아보겠습니다.

 

addr, getaddr 메시지

 addr 메시지는 자신의 IP 정보를 연결된 노드에게 전달할 때 사용하는 메시지입니다. 만약 연결된 노드에게서 다른 노드들에 대한 IP 정보를 얻고 싶다면 getaddr 메시지를 보내면 됩니다.

 

 

Blocks-First

 새로운 풀노드는 최초로 생성된 0번 블록인 제네시스 블록 이외의 블록을 가지고 있지 않습니다. 따라서 블록 전체를 다운로드하기 위해 IBD(Initial Block Download, 최초 블록 다운로드)를 해야 합니다. 이를 위한 가장 첫 단계로 getblocks 메시지를 연결된 노드에게 보냅니다. 지금부터는 블록 다운로드를 시도하는 노드를 IBD 노드, 연결된 노드를 Sync 노드라고 부르겠습니다.

 

 IBD 노드가 보내는 getblocks 메시지에는 IBD 노드가 가진 블록 중 가장 나중에 생성된 블록의 해시값을 담고 있습니다. 따라서 최초로 보내는 getblocks 메시지에는 제네시스 블록의 해시값을 담습니다.

 

 getblocks 메시지를 받은 Sync 노드는 최대 500개의 인벤토리를 담고 있는 inv 메시지를 IBD 노드에게 전송하게 됩니다. 여기에서 인벤토리란 어떤 정보에 대한 id값으로, 여기에서는 블록들의 해시값이 이에 해당합니다. 결론적으로 Sync 노드는 inv 메시지를 통해 IBD 노드에게 최대 500개의 이어지는 블록의 해시값을 전송합니다.

 

 IBD 노드는 전달받은 해시값을 담은 getdata 메시지를 다시 Sync 노드에 전송합니다. Sync 노드는 전송받은 각 블록의 해시값에 해당하는 블록을 각각 block 메시지로 전송하게 됩니다.

 

 

 이렇게 IBD 노드는 getblocks, inv, getdata, block 메시지를 반복하여 전체 블록을 받게 됩니다. 이러한 방식을 Blocks-First라고합니다.

 

Headers-First

 현재 비트코인 코어에서 사용되는 IBD 방식은 Headers-First 방식입니다. 해당 방식은 과거에 사용하던 Blocks-First 방식이 가진 몇 가지 문제점을 개선한 방식입니다.

 

 기존의 Blocks-First 방식과는 달리 Headers-First 방식에서는 getblocks가 아닌 getheaders 메시지를 가장 먼저 보내게 됩니다.

 

 Sync 노드는 getheaders 메시지에 대한 응답으로 블록의 해시값이 아닌 블록 헤더를 전송하게 됩니다. 이때 사용하는 메시지는 headers 메시지이며, 최대 2000개의 블록 헤더를 포함하여 전송합니다. IBD 노드가 전달받은 데이터가 블록의 해시값이 아닌 블록 헤더이기 때문에, 전달받은 즉시 해당 값이 올바른지 검증할 수 있습니다.

 

 이후 이어지는 과정은 Block-First 방식과 같습니다. IBD 노드가 getdata 메시지를 Sync 노드에게 보내면, Sync 노드는 IBD 노드에게 block 메시지로 블록을 하니씩 전송합니다. 그리고 이 과정을 반복합니다.

 

 

새로운 블록 전송

 노드가 작업증명에 성공했다면, 해당 블록을 다른 노드들에게 전송해야 합니다. 이때 블록을 전송하는 방법에는 크게 'Standard Block Relay'와 'Direct Headers Announcement'가 있습니다.

 

Standard Block Relay

 Standard Block Relay 방식은 블록이 발견되었을 경우 먼저 주변 노드들에게 새로운 블록에 대한 inv 메시지를 전달하고 이후 들어오는 요청에 따라 블록 전체를 제공하는 방식입니다. 해당 방식은 노드가 Block-First인지 Headers-First인지에 따라 다르게 동작합니다.

 

  • Block-First인 경우: block을 얻기 위해 getdata 메시지를 보냅니다.
  • Headers-First 인 경우: getheaders 메시지를 보내 확인 후 getdata 메시지를 보냅니다.

 

 블록을 발견한 노드는 위 요청에 따라 block과 headers 메시지를 보냅니다.

 

Direct Headers Announcement

 Direct Headers Announcement 방식은 현재 일반적으로 쓰이는 방식입니다. Standard Block Relay 방식과는 다르게 inv 메시지를 전달하는 과정을 생략하고 바로 sendheaders 메시지를 보냅니다. 해당 메시지는 새롭게 발견된 블록의 헤더를 전송하는 메시지입니다. Headers-First 노드는 이를 확인하고 getdata 메시지를 보내 전체 블록을 받아옵니다.

 

새로운 트랜잭션 전송

 새로운 트랜잭션을 전송하는 과정은 새로운 블록을 전송하는 과정과 유사합니다. 먼저 새로운 트랜잭션을 받은 노드가 inv 메시지를 다른 노드에게 전송하여 알린 뒤, 다른 노드가 getdata로 트랜잭션을 요청하면, tx 메시지를 통해 트랜잭션을 전송합니다.

 

 

 지금까지 비트코인 P2P 네트워크에서의 요청과 응답에 대해 알아봤습니다. 감사합니다.

 

 

이어지는 글들


 

[비트코인 구조] 메시지 헤더와 주요 메시지

미리 알아야 할 내용들 [비트코인 구조] P2P 네트워크 연결 P2P 네트워크 연결 비트코인 노드들이 서로 데이터를 주고받기 위해서는 노드들간의 P2P 네트워크 형성이 필요합니다. 이를 위해서 각

kwjdnjs.tistory.com