예제 #1
0
def apply_formatters(method, params, make_request, request_formatters,
                     result_formatters, error_formatters):
    if method in request_formatters:
        formatter = request_formatters[method]
        formatted_params = formatter(params)
        response = make_request(method, formatted_params)
    else:
        response = make_request(method, params)

    if 'result' in response and method in result_formatters:
        formatter = result_formatters[method]
        formatted_response = assoc(
            response,
            'result',
            formatter(response['result']),
        )
        return formatted_response
    elif 'error' in response and method in error_formatters:
        formatter = error_formatters[method]
        formatted_response = assoc(
            response,
            'error',
            formatter(response['error']),
        )
        return formatted_response
    else:
        return response
예제 #2
0
def prepare_replacement_transaction(web3, current_transaction,
                                    new_transaction):
    if current_transaction['blockHash'] is not None:
        raise ValueError(
            'Supplied transaction with hash {} has already been mined'.format(
                current_transaction['hash']))
    if 'nonce' in new_transaction and new_transaction[
            'nonce'] != current_transaction['nonce']:
        raise ValueError(
            'Supplied nonce in new_transaction must match the pending transaction'
        )

    if 'nonce' not in new_transaction:
        new_transaction = assoc(new_transaction, 'nonce',
                                current_transaction['nonce'])

    if 'gasPrice' in new_transaction:
        if new_transaction['gasPrice'] <= current_transaction['gasPrice']:
            raise ValueError(
                'Supplied gas price must exceed existing transaction gas price'
            )
    else:
        generated_gas_price = web3.vns.generateGasPrice(new_transaction)
        minimum_gas_price = int(
            math.ceil(current_transaction['gasPrice'] * 1.1))
        if generated_gas_price and generated_gas_price > minimum_gas_price:
            new_transaction = assoc(new_transaction, 'gasPrice',
                                    generated_gas_price)
        else:
            new_transaction = assoc(new_transaction, 'gasPrice',
                                    minimum_gas_price)

    return new_transaction
예제 #3
0
def extract_valid_transaction_params(transaction_params):
    extracted_params = {
        key: transaction_params[key]
        for key in VALID_TRANSACTION_PARAMS if key in transaction_params
    }

    if extracted_params.get('data') is not None:
        if transaction_params.get('input') is not None:
            if extracted_params['data'] != transaction_params['input']:
                msg = 'failure to handle this transaction due to both "input: {}" and'
                msg += ' "data: {}" are populated. You need to resolve this conflict.'
                err_vals = (transaction_params['input'],
                            extracted_params['data'])
                raise AttributeError(msg.format(*err_vals))
            else:
                return extracted_params
        else:
            return extracted_params
    elif extracted_params.get('data') is None:
        if transaction_params.get('input') is not None:
            return assoc(extracted_params, 'data', transaction_params['input'])
        else:
            return extracted_params
    else:
        raise Exception(
            "Unreachable path: transaction's 'data' is either set or not set")
예제 #4
0
    def sendTransaction(self, transaction):
        # TODO: move to middleware
        if 'from' not in transaction and is_checksum_address(self.defaultAccount):
            transaction = assoc(transaction, 'from', self.defaultAccount)

        # TODO: move gas estimation in middleware
        if 'gas' not in transaction:
            transaction = assoc(
                transaction,
                'gas',
                get_buffered_gas_estimate(self.web3, transaction),
            )

        return self.web3.manager.request_blocking(
            "eth_sendTransaction",
            [transaction],
        )
예제 #5
0
def fill_nonce(web3, transaction):
    if 'from' in transaction and 'nonce' not in transaction:
        return assoc(
            transaction, 'nonce',
            web3.vns.getTransactionCount(transaction['from'],
                                         block_identifier='pending'))
    else:
        return transaction
예제 #6
0
    def estimateGas(self, transaction):
        # TODO: move to middleware
        if 'from' not in transaction and is_checksum_address(self.defaultAccount):
            transaction = assoc(transaction, 'from', self.defaultAccount)

        return self.web3.manager.request_blocking(
            "eth_estimateGas",
            [transaction],
        )
예제 #7
0
 def middleware(method, params):
     if method == 'eth_sendTransaction':
         transaction = params[0]
         if 'gasPrice' not in transaction:
             generated_gas_price = web3.vns.generateGasPrice(transaction)
             if generated_gas_price is not None:
                 transaction = assoc(transaction, 'gasPrice', generated_gas_price)
                 return make_request(method, [transaction])
     return make_request(method, params)
예제 #8
0
    def call(self, transaction, block_identifier=None):
        # TODO: move to middleware
        if 'from' not in transaction and is_checksum_address(self.defaultAccount):
            transaction = assoc(transaction, 'from', self.defaultAccount)

        # TODO: move to middleware
        if block_identifier is None:
            block_identifier = self.defaultBlock
        return self.web3.manager.request_blocking(
            "eth_call",
            [transaction, block_identifier],
        )
예제 #9
0
    def middleware(method, params):
        response = make_request(method, params)

        if 'result' in response:
            result = response['result']
            if is_dict(result) and not isinstance(result, AttributeDict):
                return assoc(response, 'result',
                             AttributeDict.recursive(result))
            else:
                return response
        else:
            return response
예제 #10
0
    def middleware(method, params):
        result = make_request(method, params)

        # As of v1.8, Geth returns errors when you request a
        # receipt for a transaction that is not in the chain.
        # It used to return a result of None, so we simulate the old behavior.

        if method == 'eth_getTransactionReceipt' and 'error' in result:
            is_geth = web3.version.node.startswith('Geth')
            if is_geth and result['error']['code'] == -32000:
                return assoc(
                    dissoc(result, 'error'),
                    'result',
                    None,
                )
            else:
                return result
        else:
            return result
예제 #11
0
def fill_default(field, guess_func, web3, transaction):
    if field in transaction and transaction[field] is not None:
        return transaction
    else:
        guess_val = guess_func(web3, transaction)
        return assoc(transaction, field, guess_val)