Пример #1
0
    def newFilter(self, filter_dict):
        if not isinstance(filter_dict, dict):
            raise BadRequestError('Filter must be an object')
        required_keys = set(['fromBlock', 'toBlock'])
        if not required_keys.issubset(set(filter_dict.keys())):
            raise BadRequestError('Invalid filter object')

        b0 = self.json_rpc_server.get_block(block_id_decoder(filter_dict['fromBlock']))
        b1 = self.json_rpc_server.get_block(block_id_decoder(filter_dict['toBlock']))
        if b1.number < b0.number:
            raise BadRequestError('fromBlock must be prior or equal to toBlock')
        address = filter_dict.get('address', None)
        if is_string(address):
            addresses = [address_decoder(address)]
        elif isinstance(address, Iterable):
            addresses = [address_decoder(addr) for addr in address]
        elif address is None:
            addresses = None
        else:
            raise JSONRPCInvalidParamsError('Parameter must be address or list of addresses')
        topics = [data_decoder(topic) for topic in filter_dict.get('topics', [])]

        blocks = [b1]
        while blocks[-1] != b1:
            blocks.append(blocks[-1].get_parent())
        filter_ = Filter(self.chain.chain, reversed(blocks), addresses, topics)
        self.filters[self.next_id] = filter_
        self.next_id += 1
        return self.next_id - 1
Пример #2
0
def data_decoder(data):
    """Decode `data` representing unformatted data."""
    if not data.startswith('0x'):
        data = '0x' + data
    if len(data) % 2 != 0:
        raise BadRequestError('Invalid data encoding, must be even length')
    try:
        return decode_hex(data[2:])
    except TypeError:
        raise BadRequestError('Invalid data hex encoding', data[2:])
Пример #3
0
 def play_index(self, index):
     """Start playback of the specified song."""
     self.logger.info('[RPC] wotabag.play_index {}'.format(index))
     if index >= len(self.playlist) or index < 0:
         raise BadRequestError('Invalid song index')
     self.current_track = index
     self._play()
Пример #4
0
    def set_color(self, color):
        """Set all LEDs to the specified color or color sequence."""
        self.logger.info('[RPC] wotabag.set_color {}'.format(color))
        if color == 'Aqours Rainbow':
            colors = aqours_rainbow
        elif color in aqours_units:
            colors = aqours_units[color]
        elif color == 'Saint Snow':
            colors = saint_snow
        elif color in muse_units:
            colors = muse_units[color]
        elif color.upper() in BladeColor.__members__:
            colors = (BladeColor[color.upper()],)
        else:
            raise BadRequestError('Unknown color')

        strip = self.strip
        if len(colors) == 1:
            for i in range(strip.numPixels()):
                strip.setPixelColor(i, colors[0].value)
            strip.show()
        elif len(colors) <= 3:
            if len(colors) == 2:
                colors = colors + (colors[0],)
            for x, color in (enumerate(colors)):
                for y in range(9):
                    strip.setPixelColor(pixel_index(x, y), color.value)
            strip.show()
        elif len(colors) == 9:
            for x in range(3):
                for y, color in enumerate(colors):
                    strip.setPixelColor(pixel_index(x, y), color.value)
            strip.show()
Пример #5
0
def address_decoder(data):
    """Decode an address from hex with 0x prefix to 20 bytes."""
    if not data.startswith('0x'):
        data = '0x' + data
    addr = data_decoder(data)
    if len(addr) not in (20, 0):
        raise BadRequestError('Addresses must be 20 or 0 bytes long')
    return addr
Пример #6
0
 def getFilterLogs(self, id_):
     if id_ not in self.filters:
         raise BadRequestError('Unknown filter')
     filter_ = self.filters[id_]
     if filter_.pending or filter_.latest:
         return [None] * len(filter_.logs)
     else:
         return self.filters[id_].logs
Пример #7
0
    def call(self, data, block_id=None):
        block = self.json_rpc_server.get_block(block_id)
        state_root_before = block.state_root

        # rebuild block state before finalization
        if block.has_parent():
            parent = block.get_parent()
            test_block = block.init_from_parent(parent, block.coinbase,
                                                timestamp=block.timestamp)
            for tx in block.get_transactions():
                success, output = processblock.apply_transaction(test_block, tx)
                assert success
        else:
            original = block.snapshot()
            original['journal'] = deepcopy(original['journal'])  # do not alter original journal
            test_block = ethereum.blocks.genesis(block.db)
            test_block.revert(original)

        # validate transaction
        if not isinstance(data, dict):
            raise BadRequestError('Transaction must be an object')
        to = address_decoder(data['to'])
        try:
            startgas = quantity_decoder(data['gas'])
        except KeyError:
            startgas = block.gas_limit - block.gas_used
        try:
            gasprice = quantity_decoder(data['gasPrice'])
        except KeyError:
            gasprice = 0
        try:
            value = quantity_decoder(data['value'])
        except KeyError:
            value = 0
        try:
            data_ = data_decoder(data['data'])
        except KeyError:
            data_ = b''
        try:
            sender = address_decoder(data['from'])
        except KeyError:
            sender = '\x00' * 20
        # apply transaction
        nonce = test_block.get_nonce(sender)
        tx = Transaction(nonce, gasprice, startgas, to, value, data_)
        tx.sender = sender
        try:
            success, output = processblock.apply_transaction(test_block, tx)
        except processblock.InvalidTransaction:
            success = False
        assert block.state_root == state_root_before
        if success:
            return output
        else:
            return False
Пример #8
0
def data_decoder(data):
    """Decode `data` representing unformatted data."""
    if not data.startswith('0x'):
        data = '0x' + data
    if len(data) % 2 != 0:
        success = False  # must be even length
    else:
        try:
            return decode_hex(data[2:])
        except TypeError:
            success = False
    assert not success
    raise BadRequestError('Invalid data encoding')
Пример #9
0
    def newFilter(self, filter_dict):
        if not isinstance(filter_dict, dict):
            raise BadRequestError('Filter must be an object')
        b0 = self.json_rpc_server.get_block(
            block_id_decoder(filter_dict.get('fromBlock', 'latest')))
        b1 = self.json_rpc_server.get_block(
            block_id_decoder(filter_dict.get('toBlock', 'latest')))
        if b1.number < b0.number:
            raise BadRequestError(
                'fromBlock must be prior or equal to toBlock')
        address = filter_dict.get('address', None)
        if is_string(address):
            addresses = [address_decoder(address)]
        elif isinstance(address, Iterable):
            addresses = [address_decoder(addr) for addr in address]
        elif address is None:
            addresses = None
        else:
            raise JSONRPCInvalidParamsError(
                'Parameter must be address or list of addresses')
        if 'topics' in filter_dict:
            topics = []
            for topic in filter_dict['topics']:
                if topic is not None:
                    topics.append(big_endian_to_int(data_decoder(topic)))
                else:
                    topics.append(None)
        else:
            topics = None

        blocks = [b1]
        while blocks[-1] != b0:
            blocks.append(blocks[-1].get_parent())
        filter_ = Filter(self.chain.chain, reversed(blocks), addresses, topics)
        self.filters[self.next_id] = filter_
        self.next_id += 1
        return self.next_id - 1
Пример #10
0
 def getFilterChanges(self, id_):
     if id_ not in self.filters:
         raise BadRequestError('Unknown filter')
     filter_ = self.filters[id_]
     logger.debug('filter found', filter=filter_)
     if isinstance(filter_, NewBlockFilter):
         # For filters created with eth_newBlockFilter the return are block hashes
         # (DATA, 32 Bytes), e.g. ["0x3454645634534..."].
         r = filter_.check()
         if r:
             logger.debug('returning newblock', ts=time.time())
             return [data_encoder(r.hash)]
         else:
             return []
     else:
         return loglist_encoder(filter_.new_logs)
Пример #11
0
    def sendTransaction(self, data):
        """
        extend spec to support v,r,s signed transactions
        """
        if not isinstance(data, dict):
            raise BadRequestError('Transaction must be an object')

        def get_data_default(key, decoder, default=None):
            if key in data:
                return decoder(data[key])
            return default

        to = get_data_default('to', address_decoder, b'')
        startgas = get_data_default('gas', quantity_decoder, default_startgas)
        gasprice = get_data_default('gasPrice', quantity_decoder,
                                    default_gasprice)
        value = get_data_default('value', quantity_decoder, 0)
        data_ = get_data_default('data', data_decoder, b'')
        v = signed = get_data_default('v', quantity_decoder, 0)
        r = get_data_default('r', quantity_decoder, 0)
        s = get_data_default('s', quantity_decoder, 0)
        nonce = get_data_default('nonce', quantity_decoder, None)
        sender = get_data_default('from', address_decoder,
                                  self.app.services.accounts.coinbase)

        # create transaction
        if signed:
            assert nonce is not None, 'signed but no nonce provided'
            assert v and r and s
        else:
            nonce = self.app.services.chain.chain.head_candidate.get_nonce(
                sender)

        tx = Transaction(nonce, gasprice, startgas, to, value, data_, v, r, s)
        if not signed:
            assert sender in self.app.services.accounts, 'no account for sender'
            self.app.services.accounts.sign_tx(sender, tx)
        self.app.services.chain.add_transaction(tx, origin=None)

        log.debug('decoded tx', tx=tx.to_dict())

        if to == b'':  # create
            return address_encoder(
                processblock.mk_contract_address(tx.sender, nonce))
        else:
            return data_encoder(tx.hash)
Пример #12
0
def quantity_decoder(data):
    """Decode `data` representing a quantity."""
    if not is_string(data):
        success = False
    elif not data.startswith('0x'):
        success = False  # must start with 0x prefix
    elif len(data) > 3 and data[2] == '0':
        success = False  # must not have leading zeros (except `0x0`)
    else:
        data = data[2:]
        # ensure even length
        if len(data) % 2 == 1:
            data = '0' + data
        try:
            return int(data, 16)
        except ValueError:
            success = False
    assert not success
    raise BadRequestError('Invalid quantity encoding')
Пример #13
0
def bool_decoder(data):
    if not isinstance(data, bool):
        raise BadRequestError('Parameter must be boolean')
    return data
Пример #14
0
def tx_hash_decoder(data):
    """Decode a transaction hash."""
    decoded = data_decoder(data)
    if len(decoded) != 32:
        raise BadRequestError('Transaction hashes must be 32 bytes long')
    return decoded
Пример #15
0
def block_hash_decoder(data):
    """Decode a block hash."""
    decoded = data_decoder(data)
    if len(decoded) != 32:
        raise BadRequestError('Block hashes must be 32 bytes long')
    return decoded