コード例 #1
0
def test_unpackers():
    b = bytes(range(256))
    assert util.unpack_le_int32_from(b, 0) == (50462976, )
    assert util.unpack_le_int32_from(b, 42) == (757869354, )
    assert util.unpack_le_int64_from(b, 0) == (506097522914230528, )
    assert util.unpack_le_int64_from(b, 42) == (3544384782113450794, )

    assert util.unpack_le_uint16_from(b, 0) == (256, )
    assert util.unpack_le_uint16_from(b, 42) == (11050, )
    assert util.unpack_le_uint32_from(b, 0) == (50462976, )
    assert util.unpack_le_uint32_from(b, 42) == (757869354, )
    assert util.unpack_le_uint64_from(b, 0) == (506097522914230528, )
    assert util.unpack_le_uint64_from(b, 42) == (3544384782113450794, )
コード例 #2
0
ファイル: script.py プロジェクト: nanWarez/electrumx
    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') from None

        return ops
コード例 #3
0
    def get_ops(cls, script):
        '''
        Returns a tuple list of (op_code, index of next op in script, pushed bytes if any)

        If at any point the script fails do decode, a tuple of (-1, len(script), remaining script) is appended
        '''
        ops = []

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

                ops.append(op_v)
        except (IndexError, struct.error):
            # n - 1 because we read a byte first
            ops.append((-1, len(script), script[n - 1:]))

        return ops
コード例 #4
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
コード例 #5
0
 def _read_le_uint16(self):
     result, = unpack_le_uint16_from(self.binary, self.cursor)
     self.cursor += 2
     return result
コード例 #6
0
def read_le_uint16(buf, cursor):
    result, = unpack_le_uint16_from(buf, cursor)
    return result, cursor + 2