Dork's port

Block Header와 Order(Internal Byte Order, little-endian order) 본문

BlockChain

Block Header와 Order(Internal Byte Order, little-endian order)

Dork94 2019. 3. 19. 14:39

Bitcoin Developer Reference를 보면 Block Header는 다음과 같이 정의되어 있다.


//
//  block.hpp
//  b_to_the_i_to_the_coin
//
//  Created by 장한빈 on 19/03/2019.
//  Copyright © 2019 장한빈. All rights reserved.
//

#ifndef block_hpp
#define block_hpp
#pragma pack(push,1)
#include <cstdint>

// The hashes are in internal byte order the other values are all in little-endian order
class BlockHeader{
    int32_t version;
    char previous_block_header_hash[32];
    char merkle_root_hash[32];
    uint32_t time;
    uint32_t nBits;
    uint32_t nonce;
};

#pragma pack(pop)
#endif /* block_hpp */


위의 각각 변수에 대한 설명은 Bitcoin Developer Reference에 나와있으므로 생략하겠다.


특이한 점은 처음에 Wireshark로 패킷 분석한 결과 Version에 대한 값이 02 00 00 00으로 little-endian 방식을 사용하였다.


기존에 네트워크 패킷에서 network byte order(big-endian)를 사용하지 않고 little-endian을 사용하는 경우를 딱 한번 보았는데 무선랜환경(802.11)에서 radio tap헤더의 처음부분에 little-endian으로 사용하였다. 이때는 드라이버가 신호에 대한 세기나 기타등등을 로컬에서 생성하는 정보여서 Host OS의 order를 따라갔던 것이였는데, Bitcoin은 little-endian을 쓰길래 찾아보았다.


따라서, 찾아본 결과 다음과 같은 글을 발견할 수 있었다.


The hashes are in internal byte order; the other values are all in little-endian order


즉, 해쉬에 대한 값은 internal byte order(Host Byte order)로 전송하며 나머지는 little-endian 방식으로 저장및 송수신 한다는 내용을 볼 수 있었는데, 그 이유에 대해선 차차 공부하며 서술 하도록 하겠다!



이유를 조금 찾아보았는데, 우선 왜 hash의 값은 internal byte order를 사용하는지, 나머지는 왜 little endian을 사용하는지에 대한 명확한 이유를 찾을 수 없었다.


little endian에 관련해서는 Stack overflow에 small design error라고 한다. 출처는 이 말에 대한 출처는 명확하지 않으므로, 그냥 참고만 하자! 


또한, 이에 대한 논의가 진행되고 있다고 한다.


두번째 의문은 왜 internal byte order를 사용해서 통신을 하냐 였는데, 이거에 대한 의문점은 다음과 같다.


CPU에 따라 Big-endian과 Little-endian으로 나뉜다.


2가지 방식이 있으며, 사용자에 따라 방식이 다를 수 있으므로, 값을 입력해서 네트워크로 전송할 때에 자신의 endian에 대한 방식을 알려주는 field가 존재하거나, 값을 이용해서 little인지 big인지 알아야한다.


헤더의 경우 자신의 운영체제 endian에 대한 필드는 찾지 못했으며, bitcoin의 해쉬의 경우 00 00 과 같이 시작하기 때문에 충분히 endian을 추론 가능하다. 그러나 이 말은 어떠한 헤더가 수신될때마다 어떠한 프로세스를 거쳐 endian을 판별해야한다.


의문이 가는점은 차라리 다른 속성값과 같이 고정을 하면 위와 같은 프로세스를 통해 헤더 수신될 때마다 endian을 판별하지 않아도 되는데 왜 이런 문제점을 남겨놨는지는 의문이다.


혹시나 의견이나 답을 아시는 분이있다면 댓글부탁드립니다!




실제로 확인해보니 어떤사람이 보낸 패킷에 prev_header의 값은 little-endian으로 정렬된 것을 볼 수 있다.


주의할 점은 사용자가 받는 Host system의 endian이 아니라 다른 사용자가 전송시에 사용되는 endian이 사용된다!


사용자가 받는 Host의 edian 방식에 따라 endian을 바꿔 전송 시키는 방식은 RPC byte order라고 따로 있는 것 같다 :) 

Comments