Ejemplo n.º 1
0
 def _unpack_proof(raw: bytes) -> TxProof:
     io = BytesIO(raw)
     pack_version = bitcoinx.read_varint(io.read)
     if pack_version == 1:
         position = bitcoinx.read_varint(io.read)
         branch_count = bitcoinx.read_varint(io.read)
         merkle_branch = [
             bitcoinx.read_varbytes(io.read) for i in range(branch_count)
         ]
         return TxProof(position, merkle_branch)
     raise DataPackingError(f"Unhandled packing format {pack_version}")
Ejemplo n.º 2
0
    def deserialize_headers(cls, f):
        """deserialize block headers into a list of dicts"""
        lst_headers = []
        global headers_stream
        global hashes_stream
        # Store headers temporarily to memory as binary stream
        headers_stream.seek(0)
        headers_stream.write(f.read())

        # make a list of block hashes for validating
        headers_stream.seek(0)
        count = bitcoinx.read_varint(headers_stream.read)  # count of headers
        for i in range(count):
            header = headers_stream.read(80)  # minus final txn count (1 byte)
            headers_stream.read(1)  # discard txn count
            _hash = simple_spv.tools.get_block_hash(header)  # calculates hash as part of validation
            hashes_stream.write(_hash + '\n')

        f.seek(0)

        number_headers = bitcoinx.read_varint(f.read)
        for i in range(number_headers):
            # TODO make into single function call for readability and reuse
            version = bitcoinx.read_le_int32(f.read)
            prev_block = bitcoinx.hash_to_hex_str(f.read(32))
            merkle_root = bitcoinx.hash_to_hex_str(f.read(32))
            timestamp = bitcoinx.read_le_uint32(f.read)
            bits = ut.int_to_hex(bitcoinx.read_le_uint32(f.read))
            nonce = bitcoinx.read_le_uint32(f.read)
            txn_count = bitcoinx.read_varint(f.read)

            block_header = {'version': version,
                            'prev_block_hash': prev_block,
                            'merkle_root': merkle_root,
                            'timestamp': timestamp,
                            'bits': bits,
                            'nonce': nonce,
                            'txn_count': txn_count}

            lst_headers.append(block_header)

        return lst_headers
Ejemplo n.º 3
0
 def deserialize_inv(cls, f):
     message = []
     count = bitcoinx.read_varint(f.read)
     for i in range(count):
         inv_type = bitcoinx.read_le_uint32(f.read)
         inv_hash = bitcoinx.hash_to_hex_str(f.read(32))
         inv_vector = {'count': count,
                       'inv_type': inv_type,
                       'inv_hash': inv_hash}
     message.append(inv_vector)
     return message
Ejemplo n.º 4
0
    def deserialize_getheaders(cls, f):
        """for checking my own getheaders request"""
        version = bitcoinx.read_le_uint32(f.read)
        hash_count = bitcoinx.read_varint(f.read)
        block_locator_hashes = []
        for i in range(hash_count):
            block_locator_hashes.append(bitcoinx.hash_to_hex_str(f.read(32)))
        hash_stop = bitcoinx.hash_to_hex_str(f.read(32))

        message = {'version': version,
                   'hash_count': hash_count,
                   'block_locator_hashes': block_locator_hashes,
                   'hash_stop': hash_stop}
        return message
Ejemplo n.º 5
0
 def deserialize_addr(cls, f):
     count = bitcoinx.read_varint(f.read)
     addresses = []
     for i in range(count):
         timestamp = time.ctime(bitcoinx.read_le_uint32(f.read))
         services = bitcoinx.read_le_uint64(f.read)
         reserved = f.read(12)  # IPv6
         IPv4 = socket.inet_ntoa(f.read(4))
         port = bitcoinx.read_le_uint16(f.read)
         addresses.append({'timestamp': timestamp,
                           'services': services,
                           'IPv4': IPv4,
                           'port': port})
     return addresses  # count not returned by choice
Ejemplo n.º 6
0
    def validate_headers_batch(cls, f):
        """Takes in "headers" response as byte stream (up to max 2000 headers) and validates"""
        valid_headers = []  # list of [True, True, True...]
        global db_height
        f.seek(0)

        count = bitcoinx.read_varint(f.read)  # count of headers
        for i in range(count):
            header = f.read(80)  # minus final txn count (1 byte)
            f.read(1)  # discard txn count
            valid_headers.append(
                cls.validate_block_header(header))
            db_height += 1

        # check if all true
        if all(i is True for i in valid_headers):
            print("all valid")
        else:
            raise ValueError("Invalid header. Validation result for first 5 headers in batch: ", valid_headers[0:5])

        return True