About
BIP152(2016)로 현재 비트코인에서 사용
Compact Blocks
BIP: 152 Layer: Peer Services Title: Compact Block Relay
*RFC 2119
1. MUST 이 단어와 "REQUIRED" 그리고 "SHALL" 은 꼭 필요한 요구사항을 정의할 때 사용.
2. MUST NOT 이 구문과 "SHALL NOT"은 절대 금지 사항을 나타낼 때 사용.
3. SHOULD 이 단어와 "RECOMMENDED"는 없어도 되지만 그래도 권장할 때 사용.
4. SHOULD NOT 이 구문과 "NOT RECOMMENDED"는 3번과 반대의 의미.
5. MAY 이 단어와 "OPTIONAL" 완전 선택적이라는 뜻을 나타낼 때 사용.
출처:
BIP130 (inv or headers)
previous work
와이어 샤크로 분석 가능
*IBD : 초기 데이터 동기화 과정(Initial Block Download or Initial Sync)
Block first 방식
- 단순함(ibd node가 genesis 블록만 가지고 있을때, sync node로부터 전체 블록을 다운로드 받는다.)
- sync 노드에 의존하므로,
- Sync노드의 전송속도가 늦으면 다운로드 속도가 늦음
- sync노드가 블록체인 데이터 전체를 갖고있지 않거나, 다운로드중 연결이 끊어지면 IBD노드는 다른 sync노드를 찾아서 재 요청해야하는 단점이 있다
- sync노드가 부적절한 블록 데이터 전송시 이를 곧바로 전송하기 어려움
Header first 방식
Block first방식의 단점을 보완하기위해 Bitcoin core 0.10.0부터 사용
이전에는 빠른 동기화를위해 bootstrap.dat 파일을 torrent로 다운받아 사용했다.
- Sync 노드로부터 header정보만 먼저 받고, 헤더 정보를 이용하여 다른 여러 sync노드들로부터 동시에 블록 데이터를 받음.(특정 노드에 의존하지 않음)
- sync노드는 한번에 최대 2000개 블록헤더까지 보낼수 있다.
- 헤더 수집 후에는, getdata 메시지를 통해, 각 헤더에 해당하는 실제 블록데이터를 요청
- 여러 full 노드들에게 동시에 요청하며, spv노드는 getheaders-headers메시지만 교환함
- getdata 메시지를 받은 sync노드는 해당 헤더의 실제 블록데이터를 ibd노드에게 전송
Compact Block Relay (BIP152)
- Bitcoin Core 0.13.0부터 적용
- IBD가 완료된 후, Miner에 의해 지속적으로 발생하는 블록 데이터는 Compact block relay 방식으로 전달
- 풀노드가 mempool의 대부분을 공유할때, 전파하는데 사용되는 대역폭의 양을 줄인다.
- compact block sketches를 피어에게 전달한다.
- sketch는 다음과 같은 정보를 포함한다.
- 블록의 80byte 헤더
- 짧은 트랜잭션ID들(DoS 공격을 예방하도록 설계됨)
- 수신 피어가 갖고있지 않을것이라 예상하는 완전한 트랜잭션들
- 송신 피어로부터 sketch를 전달받으면, 수신 피어는 받은 정보와 mempool에 이미 갖고 있는 트랜잭션을 이용하여 블록을 재구성한다.
- 장점 : 트랜잭션이 한번만 전송되므로(중복해서 전송하지 않음) 전체 대역폭이 크게 감소한다.?
- High Bandwidth Relaying 모드 제공
- 수신 노드가 몇개의 피어들이 허가를 먼저 요청하지 않고 새로운 블록을 바로 전송할수 있게하는 고대역폭 모드
- 이는 두 피어가 동시에 같은 블록을 전송하려는 경우 대역폭을 증가시킬수 있지만, 고대역폭 연결에서는 블록이 도착하는 시간 지연을 더 줄일 수 있다.
- 아래의 다이어그램은 현재 노드가 블록을 전달하는 방법과 비교해 compact block relay의 두가지 모드를 나타낸다.
- 노드 A의 타임라인에 있는 회색 박스는 유효성 검사 수행기간을 나타낸다.
- Legacy Relaying(기존방법) :
- High Bandwidth Relaying :
- Low Bandwidth Relaying :
- 노드 B는 A에게 sendcmpt(1) (send compact) 메시지를 보내서 block 메시지는 발생 즉시 받고 싶다고 통보함. (inv, getdata 등의 메시지 교환없이 그냥 블록 데이터를 보내달 라고 요청함)
- 노드 A가 새로운 블록 데이터를 받으면 기본적인 검증만 완 료하고 cmpctblock 메시지를 통해 즉시 노드 B에게 블록 데이터를 보냄. 블록 데이터를 받자마자 보내므로 일부 TX 데이터는 아직 없을 수도 있음.
- 노드 B가 cmpctblock 메시지를 받으면 블록 데이터를 재구 성하고 (reconstruction) 부족한 TX 데이터가 있으면 노드 A에게 getblocktxn 메시지를 보내서 빠진 TX 데이터를 추 가로 요청함.
- 노드 A가 getblocktxn 메시지를 받으면 추가로 보낼 TX 데 이터가 있으면 blocktxn 메시지를 통해 노드 B에게 TX 데이 터를 마저 보냄.
- relay network 보다는 느리다. p2p 네트워크에서의 블록 전파시간을 줄이기 위해 더 개선해야 할것.
- compact block의 추가 개선
- TCP전송을 UDP전송으로 변경
- UDP 전송을 사용하면 간헐적인 패킷손실에 대한 걱정없이 데이터를 받을 수 있고,
- 손실된 패킷을 처리하고 누락된 트랜잭션데이터를 FEC(Forward Error Correction) 코드를 사용하여 미리 전송한다.
- 손실된 패킷을 처리하고 non-redundant block data를 여러 서버로부터 받기위해 사용한다. FEC코드는 원본 데이터를 redundant code로 변환하는방법으로, 패킷의 특정 비율이 대상에 도착하는 한 무손실 전송을 허용한다. 필요한 데이터는 원래 데이터 크기보다 약간 크다.
- 이렇게하면, 노드가 블록을 받는 즉시 블록 전송을 시작할수 있고, 여러 피어로부터 동시에 스트리밍되는 블록을 재구성할 수 있다.
- Pieter Wuille (sipa)에 의해 BIP37 블룸필터를 이용하여 필터링하는 방법이 제안되었었으나, 오버헤드가 전송 속도를 늦춘다는게 발견되었다.
- 얼마나 개선되었나?
- 없는 트랜잭션을 즉시 어떻게 선택할까?
- 노드 A가 블록을 받았을때, 어떤 트랜잭션이 블록에 있는지 확인하지만 mempool은 확인하지않았다. 즉, 수신하는 노드가 가지고 있지 않다고 예측한 트랜잭션이었다. 자신이 몰랐던 트랜잭션이면 자신의 피어들도 모르는 거래일 것이라고 추론한것. 이런 기본적인 휴리스틱으로도 큰 개선이 되었다.