Ejemplo n.º 1
0
def get_next_segwit_tx_size(buf, off, tail=-1):
    """
    Returns the size of the next transaction in the.
    Returns -1 if there's a parsing error or the end goes beyond the tail.
    """
    end = off + btc_constants.TX_VERSION_LEN + btc_constants.TX_SEGWIT_FLAG_LEN

    io_size, txin_c, _ = btc_common_utils.get_tx_io_count_and_size(
        buf, end, tail)

    if io_size < 0:
        return -1

    end += io_size

    for _ in range(txin_c):
        witness_count, size = btc_common_utils.btc_varint_to_int(buf, end)
        end += size

        for _ in range(witness_count):
            witness_len, size = btc_common_utils.btc_varint_to_int(buf, end)
            end += size + witness_len

    end += btc_constants.TX_LOCK_TIME_LEN

    if end > tail > 0:
        return -1

    return end - off
    def indices(self) -> List[int]:
        if self._indices is None:
            off = BTC_HDR_COMMON_OFF + 32
            num_indices, size = btc_varint_to_int(self.buf, off)
            off += size
            self._indices = []

            index = -1
            for _ in range(num_indices):
                diff_index, size = btc_varint_to_int(self.buf, off)
                index += diff_index + 1
                self._indices.append(index)
                off += size

        return self._indices
def parse_bx_block_header(
        bx_block: memoryview,
        block_pieces: Deque[Union[bytearray, memoryview]]) -> BlockHeaderInfo:
    block_offsets = compact_block_short_ids_serializer.get_bx_block_offsets(
        bx_block)
    short_ids, short_ids_len = compact_block_short_ids_serializer.deserialize_short_ids_from_buffer(
        bx_block, block_offsets.short_id_offset)

    # Compute block header hash
    block_header_size = \
        block_offsets.block_begin_offset + \
        btc_constants.BTC_HDR_COMMON_OFF + \
        btc_constants.BTC_BLOCK_HDR_SIZE
    block_hash = BtcObjectHash(buf=crypto.bitcoin_hash(
        bx_block[block_offsets.block_begin_offset +
                 btc_constants.BTC_HDR_COMMON_OFF:block_header_size]),
                               length=btc_constants.BTC_SHA_HASH_LEN)
    offset = block_header_size

    # Add header piece
    txn_count, txn_count_size = btc_common_utils.btc_varint_to_int(
        bx_block, block_header_size)
    offset += txn_count_size
    block_pieces.append(bx_block[block_offsets.block_begin_offset:offset])
    return BlockHeaderInfo(block_offsets, short_ids, short_ids_len, block_hash,
                           offset, txn_count)
Ejemplo n.º 4
0
 def __iter__(self):
     off = BTC_HDR_COMMON_OFF
     self._header_count, size = btc_varint_to_int(self.buf, off)
     off += size
     for _ in range(self._header_count):
         yield self._memoryview[off:off + 81]
         off += 81
Ejemplo n.º 5
0
    def __iter__(self):
        off = BTC_HDR_COMMON_OFF + 4  # For the version field.
        b_count, size = btc_varint_to_int(self.buf, off)
        off += size

        for i in range(b_count):
            yield BtcObjectHash(buf=self.buf,
                                offset=off,
                                length=BTC_SHA_HASH_LEN)
            off += 32
Ejemplo n.º 6
0
    def tx_in(self):
        if self._tx_in is None:
            off = BTC_HDR_COMMON_OFF + 4
            self._tx_in_count, size = btc_common_utils.btc_varint_to_int(
                self.buf, off)
            off += size
            self._tx_in = []

            start = off
            end = off

            for _ in range(self._tx_in_count):
                end += 36
                script_len, size = btc_common_utils.btc_varint_to_int(
                    self.buf, end)
                end += size + script_len + 4
                self._tx_in.append(self.rawbytes()[start:end])
                start = end

            off = end
            self._tx_out_count, size = btc_common_utils.btc_varint_to_int(
                self.buf, off)
            self._tx_out = []
            off += size

            start = off
            end = off
            for _ in range(self._tx_out_count):
                end += 8
                script_len, size = btc_common_utils.btc_varint_to_int(
                    self.buf, end)
                end += size + script_len
                self._tx_out.append(self.rawbytes()[start:end])

            off = end

            self._lock_time, = struct.unpack_from('<I', self.buf, off)

        return self._tx_in
Ejemplo n.º 7
0
 def version(self):
     if self._version is None:
         off = 0
         self._version = struct.unpack_from('<I', self.buf, off)[0]
         off += 4
         self._prev_block = BtcObjectHash(self.buf, off, 32)
         off += 32
         self._merkle_root = self._memoryview[off:off + 32]
         off += 32
         self._timestamp, self._bits, self._nonce = struct.unpack_from(
             '<III', self.buf, off)
         self._txn_count, size = btc_varint_to_int(self.buf, off)
     return self._version
Ejemplo n.º 8
0
    def pre_filled_transactions(self) -> Dict[int, memoryview]:
        if self._pre_filled_transactions is None:
            off = BTC_HDR_COMMON_OFF + BTC_BLOCK_HDR_SIZE + BTC_SHORT_NONCE_SIZE
            self._short_id_c, size = btc_varint_to_int(self.buf, off)
            off += size + BTC_COMPACT_BLOCK_SHORT_ID_LEN * self._short_id_c
            self._pre_filled_tx_count, size = btc_varint_to_int(self.buf, off)
            off += size

            self._pre_filled_transactions = {}

            index = -1
            # pyre-fixme[6]: Expected `int` for 1st param but got `None`.
            for _ in range(self._pre_filled_tx_count):
                diff, size = btc_varint_to_int(self.buf, off)
                off += size
                size = get_next_tx_size(self.buf, off)
                buf = self._memoryview[off:off + size]
                off += size

                index += diff + 1
                self._pre_filled_transactions[index] = buf

        return self._pre_filled_transactions
Ejemplo n.º 9
0
    def short_ids(self) -> Dict[bytes, int]:
        if self._short_ids is None:
            off = BTC_HDR_COMMON_OFF + BTC_BLOCK_HDR_SIZE + BTC_SHORT_NONCE_SIZE
            self._short_id_c, size = btc_varint_to_int(self.buf, off)
            off += size
            self._short_ids = {}

            for idx in range(self._short_id_c):
                self._short_ids[bytes(
                    self._memoryview[off:off +
                                     BTC_COMPACT_BLOCK_SHORT_ID_LEN])] = idx
                off += BTC_COMPACT_BLOCK_SHORT_ID_LEN

        return self._short_ids
    def transactions(self) -> List[memoryview]:
        if self._transactions is None:
            self._transactions = []
            off = BTC_HDR_COMMON_OFF + BTC_SHA_HASH_LEN

            tx_len, size = btc_varint_to_int(self.buf, off)
            off += size

            for _ in range(tx_len):
                size = get_next_tx_size(self.buf, off)
                tx = self._memoryview[off:off + size]
                off += size
                self._transactions.append(tx)

        return self._transactions  # pyre-ignore
Ejemplo n.º 11
0
    def __iter__(self) -> Iterator[Tuple[int, BtcObjectHash]]:
        off = btc_constants.BTC_HDR_COMMON_OFF
        num_items, size = btc_common_utils.btc_varint_to_int(self.buf, off)
        off += size
        # pyre-fixme[16]: `InventoryBtcMessage` has no attribute `_num_items`.
        self._num_items = num_items

        # pyre-fixme[16]: `InventoryBtcMessage` has no attribute `_items`.
        self._items = list()
        for _ in range(num_items):
            inv_type, = struct.unpack_from("<L", self.buf, off)
            off += 4
            yield (inv_type,
                   BtcObjectHash(buf=self.buf,
                                 offset=off,
                                 length=btc_constants.BTC_SHA_HASH_LEN))
            off += 32
Ejemplo n.º 12
0
    def version(self):
        if self._version is None:
            off = BTC_HDR_COMMON_OFF
            self._version = struct.unpack_from('<I', self.buf, off)[0]
            off += 4
            self._prev_block = BtcObjectHash(self.buf, off, 32)
            off += 32
            self._merkle_root = BtcObjectHash(self.buf, off, 32)
            off += 32
            self._timestamp, self._bits, self._nonce = struct.unpack_from(
                '<III', self.buf, off)
            off += 12
            self._txn_count, size = btc_varint_to_int(self.buf, off)
            off += size
            self._tx_offset = off

            self._header = self._memoryview[0:self._tx_offset]

        return self._version
Ejemplo n.º 13
0
def ont_varint_to_int(buf: Union[memoryview, bytearray],
                      off: int) -> Tuple[int, int]:
    return btc_varint_to_int(buf, off)
Ejemplo n.º 14
0
    def hash_count(self):
        if self._header_count is None:
            off = BTC_HDR_COMMON_OFF
            self._header_count, size = btc_varint_to_int(self.buf, off)

        return self._header_count
Ejemplo n.º 15
0
 def count(self):
     off = btc_constants.BTC_HDR_COMMON_OFF
     num_items, size = btc_common_utils.btc_varint_to_int(self.buf, off)
     return num_items