Ejemplo n.º 1
0
    def get_ops(cls, script):
        ops = []

        # The unpacks or script[n] below throw on truncated scripts
        try:
            n = 0
            while n < len(script):
                op = script[n]
                n += 1

                if op <= OpCodes.OP_PUSHDATA4:
                    # Raw bytes follow
                    if op < OpCodes.OP_PUSHDATA1:
                        dlen = op
                    elif op == OpCodes.OP_PUSHDATA1:
                        dlen = script[n]
                        n += 1
                    elif op == OpCodes.OP_PUSHDATA2:
                        dlen, = unpack_le_uint16_from(script[n: n + 2])
                        n += 2
                    else:
                        dlen, = unpack_le_uint32_from(script[n: n + 4])
                        n += 4
                    if n + dlen > len(script):
                        raise IndexError
                    op = (op, script[n:n + dlen])
                    n += dlen

                ops.append(op)
        except Exception:
            # Truncated script; e.g. tx_hash
            # ebc9fa1196a59e192352d76c0f6e73167046b9d37b8302b6bb6968dfd279b767
            raise ScriptError('truncated script')

        return ops
Ejemplo n.º 2
0
    async def raw_blocks(self, hex_hashes):
        '''Return the raw binary blocks with the given hex hashes.'''

        params_iterable = ((h, False) for h in hex_hashes)
        blocks = await self._send_vector('getblock', params_iterable)

        raw_blocks = []
        valid_tx_tree = {}
        for block in blocks:
            # Convert to bytes from hex
            raw_block = hex_to_bytes(block)
            raw_blocks.append(raw_block)
            # Check if previous block is valid
            prev = self.prev_hex_hash(raw_block)
            votebits = unpack_le_uint16_from(raw_block[100:102])[0]
            valid_tx_tree[prev] = self.is_valid_tx_tree(votebits)

        processed_raw_blocks = []
        for hash, raw_block in zip(hex_hashes, raw_blocks):
            if hash in valid_tx_tree:
                is_valid = valid_tx_tree[hash]
            else:
                # Do something complicated to figure out if this block is valid
                header = await self._send_single('getblockheader', (hash, ))
                if 'nextblockhash' not in header:
                    raise DaemonError(f'Could not find next block for {hash}')
                next_hash = header['nextblockhash']
                next_header = await self._send_single('getblockheader',
                                                      (next_hash, ))
                is_valid = self.is_valid_tx_tree(next_header['votebits'])

            if is_valid:
                processed_raw_blocks.append(raw_block)
            else:
                # If this block is invalid remove the normal transactions
                self.logger.info(f'block {hash} is invalidated')
                processed_raw_blocks.append(self.strip_tx_tree(raw_block))

        return processed_raw_blocks
Ejemplo n.º 3
0
Archivo: tx.py Proyecto: shyba/torba
 def _read_le_uint16(self):
     result, = unpack_le_uint16_from(self.binary, self.cursor)
     self.cursor += 2
     return result