def _construct_block_data_middleware(num_blocks): blocks = generate_block_history(num_blocks) _block_info = { 'blocks': blocks, 'head_block_number': blocks[0]['number'] } def _evm_mine(method, params, block_info=_block_info): num_blocks = params[0] head_block_number = block_info['head_block_number'] if head_block_number + num_blocks >= len(block_info['blocks']): raise ValueError("no more blocks to mine") block_info['head_block_number'] += num_blocks def _get_block_by_number(method, params, block_info=_block_info): block_id = params[0] blocks = block_info['blocks'] head_block_number = block_info['head_block_number'] if block_id == 'latest': return blocks[head_block_number] elif block_id == 'pending': if head_block_number + 1 >= len(blocks): raise ValueError("no pending block") return blocks[head_block_number + 1] elif block_id == 'earliest': return blocks[0] elif is_integer(block_id): if block_id <= head_block_number: return blocks[block_id] else: return None else: raise TypeError('Invalid type for block_id') def _get_block_by_hash(method, params, block_info=_block_info): block_hash = params[0] blocks = block_info['blocks'] head_block_number = block_info['head_block_number'] blocks_by_hash = { block['hash']: block for block in blocks } try: block = blocks_by_hash[block_hash] if block['number'] <= head_block_number: return block else: return None except KeyError: return None return construct_result_generator_middleware({ 'eth_getBlockByNumber': _get_block_by_number, 'eth_getBlockByHash': _get_block_by_hash, 'evm_mine': _evm_mine, })
def result_generator_middleware(): return construct_result_generator_middleware({ 'eth_sendRawTransaction': lambda *args: args, 'net_version': lambda *_: 1, })
def test_fee_utils_indirectly( w3, fee_history_rewards, expected_max_prio_calc ) -> None: fail_max_prio_middleware = construct_error_generator_middleware( {RPCEndpoint("eth_maxPriorityFeePerGas"): lambda *_: ''} ) fee_history_result_middleware = construct_result_generator_middleware( {RPCEndpoint('eth_feeHistory'): lambda *_: {'reward': fee_history_rewards}} ) w3.middleware_onion.add(fail_max_prio_middleware, 'fail_max_prio') w3.middleware_onion.inject(fee_history_result_middleware, 'fee_history_result', layer=0) with pytest.warns( UserWarning, match="There was an issue with the method eth_maxPriorityFeePerGas. Calculating using " "eth_feeHistory." ): max_priority_fee = w3.eth.max_priority_fee assert is_integer(max_priority_fee) assert max_priority_fee == expected_max_prio_calc # clean up w3.middleware_onion.remove('fail_max_prio') w3.middleware_onion.remove('fee_history_result')
def test_get_block_formatters_with_null_values(w3): null_values_block = { 'baseFeePerGas': None, 'extraData': None, 'gasLimit': None, 'gasUsed': None, 'size': None, 'timestamp': None, 'hash': None, 'logsBloom': None, 'miner': None, 'mixHash': None, 'nonce': None, 'number': None, 'parentHash': None, 'sha3Uncles': None, 'difficulty': None, 'receiptsRoot': None, 'statesRoot': None, 'totalDifficulty': None, 'transactionsRoot': None, } result_middleware = construct_result_generator_middleware({ RPC.eth_getBlockByNumber: lambda *_: null_values_block, }) w3.middleware_onion.inject(result_middleware, 'result_middleware', layer=0) received_block = w3.eth.get_block('pending') assert received_block == null_values_block
def test_simple_cache_middleware_does_not_cache_none_responses(w3_base): counter = itertools.count() w3 = w3_base def result_cb(method, params): next(counter) return None w3.middleware_onion.add( construct_result_generator_middleware({ 'fake_endpoint': result_cb, })) w3.middleware_onion.add( construct_simple_cache_middleware( cache_class=dict, rpc_whitelist={'fake_endpoint'}, )) with pytest.raises(ValueError): w3.manager.request_blocking('fake_endpoint', []) with pytest.raises(ValueError): w3.manager.request_blocking('fake_endpoint', []) assert next(counter) == 2
def result_generator_middleware(): return construct_result_generator_middleware({ 'fake_endpoint': lambda *_: str(uuid.uuid4()), 'not_whitelisted': lambda *_: str(uuid.uuid4()), })
def result_generator_middleware(iter_block_number): return construct_result_generator_middleware({ 'eth_getLogs': lambda *_: ["middleware"], 'eth_getBlockByNumber': lambda *_: type('block', (object,), {'hash': 'middleware'}), 'net_version': lambda *_: 1, 'eth_blockNumber': lambda *_: next(iter_block_number), })
def _construct_block_data_middleware(num_blocks): blocks = generate_block_history(num_blocks) _block_info = { 'blocks': blocks, 'head_block_number': blocks[0]['number'] } def _evm_mine(method, params, block_info=_block_info): num_blocks = params[0] head_block_number = block_info['head_block_number'] if head_block_number + num_blocks >= len(block_info['blocks']): raise ValueError("no more blocks to mine") block_info['head_block_number'] += num_blocks def _get_block_by_number(method, params, block_info=_block_info): block_id = params[0] blocks = block_info['blocks'] head_block_number = block_info['head_block_number'] if block_id == 'latest': return blocks[head_block_number] elif block_id == 'pending': if head_block_number + 1 >= len(blocks): raise ValueError("no pending block") return blocks[head_block_number + 1] elif block_id == 'earliest': return blocks[0] elif is_integer(block_id): if block_id <= head_block_number: return blocks[block_id] else: return None else: raise TypeError('Invalid type for block_id') def _get_block_by_hash(method, params, block_info=_block_info): block_hash = params[0] blocks = block_info['blocks'] head_block_number = block_info['head_block_number'] blocks_by_hash = { block['hash']: block for block in blocks } try: block = blocks_by_hash[block_hash] if block['number'] <= head_block_number: return block else: return None except KeyError: return None return construct_result_generator_middleware({ 'eth_getBlockByNumber': _get_block_by_number, 'eth_getBlockByHash': _get_block_by_hash, 'evm_mine': _evm_mine, })
def result_generator_middleware(iter_block_number): return construct_result_generator_middleware({ 'eth_getLogs': lambda *_: FILTER_LOG, 'eth_getBlockByNumber': lambda *_: { 'hash': BLOCK_HASH }, 'net_version': lambda *_: 1, 'eth_blockNumber': lambda *_: next(iter_block_number), })
def test_result_middleware(w3, method, expected): def _callback(method, params): return params[0] w3.middleware_stack.add(construct_result_generator_middleware({ 'test_endpoint': _callback, })) if isinstance(expected, type) and issubclass(expected, Exception): with pytest.raises(expected): w3.manager.request_blocking(method, [expected]) else: actual = w3.manager.request_blocking(method, [expected]) assert actual == expected
def test_result_middleware(w3, method, expected): def _callback(method, params): return params[0] w3.middleware_stack.add(construct_result_generator_middleware({ 'test_endpoint': _callback, })) if isinstance(expected, type) and issubclass(expected, Exception): with pytest.raises(expected): w3.manager.request_blocking(method, [expected]) else: actual = w3.manager.request_blocking(method, [expected]) assert actual == expected
def test_time_based_cache_middleware_does_not_cache_bad_responses( w3_base, response, time_cache_middleware): w3 = w3_base counter = itertools.count() def mk_result(method, params): next(counter) return None w3.middleware_stack.add( construct_result_generator_middleware({'fake_endpoint': mk_result})) w3.middleware_stack.add(time_cache_middleware) w3.manager.request_blocking('fake_endpoint', []) w3.manager.request_blocking('fake_endpoint', []) assert next(counter) == 2
def test_time_based_gas_price_strategy(strategy_params, expected): fixture_middleware = construct_result_generator_middleware({ 'eth_getBlockByHash': _get_block_by_something, 'eth_getBlockByNumber': _get_block_by_something, }) w3 = Web3( provider=BaseProvider(), middlewares=[fixture_middleware], ) time_based_gas_price_strategy = construct_time_based_gas_price_strategy( **strategy_params, ) w3.eth.setGasPriceStrategy(time_based_gas_price_strategy) actual = w3.eth.generate_gas_price() assert actual == expected
def test_time_based_gas_price_strategy(strategy_params, expected): fixture_middleware = construct_result_generator_middleware({ 'eth_getBlockByHash': _get_block_by_something, 'eth_getBlockByNumber': _get_block_by_something, }) w3 = Web3( providers=[BaseProvider()], middlewares=[fixture_middleware], ) time_based_gas_price_strategy = construct_time_based_gas_price_strategy( **strategy_params, ) w3.eth.setGasPriceStrategy(time_based_gas_price_strategy) actual = w3.eth.generateGasPrice() assert actual == expected
def test_time_based_cache_middleware_does_not_cache_bad_responses( w3_base, response, time_cache_middleware): w3 = w3_base counter = itertools.count() def mk_result(method, params): next(counter) return None w3.middleware_stack.add(construct_result_generator_middleware({'fake_endpoint': mk_result})) w3.middleware_stack.add(time_cache_middleware) w3.manager.request_blocking('fake_endpoint', []) w3.manager.request_blocking('fake_endpoint', []) assert next(counter) == 2
def test_time_based_gas_price_strategy_zero_sample(strategy_params_zero, expected_exception_message): with pytest.raises(ValidationError) as excinfo: fixture_middleware = construct_result_generator_middleware({ 'eth_getBlockByHash': _get_block_by_something, 'eth_getBlockByNumber': _get_block_by_something, }) w3 = Web3( provider=BaseProvider(), middlewares=[fixture_middleware], ) time_based_gas_price_strategy_zero = construct_time_based_gas_price_strategy( **strategy_params_zero, ) w3.eth.setGasPriceStrategy(time_based_gas_price_strategy_zero) w3.eth.generate_gas_price() assert str(excinfo.value) == expected_exception_message
def test_time_based_gas_price_strategy_zero_sample(strategy_params_zero, expected_exception_message): with pytest.raises(ValidationError) as excinfo: fixture_middleware = construct_result_generator_middleware({ 'eth_getBlockByHash': _get_block_by_something, 'eth_getBlockByNumber': _get_block_by_something, }) w3 = Web3( providers=[BaseProvider()], middlewares=[fixture_middleware], ) time_based_gas_price_strategy_zero = construct_time_based_gas_price_strategy( **strategy_params_zero, ) w3.eth.setGasPriceStrategy(time_based_gas_price_strategy_zero) w3.eth.generateGasPrice() assert str(excinfo.value) == expected_exception_message
def test_simple_cache_middleware_does_not_cache_none_responses(w3_base): counter = itertools.count() w3 = w3_base def result_cb(method, params): next(counter) return None w3.middleware_stack.add(construct_result_generator_middleware({ 'fake_endpoint': result_cb, })) w3.middleware_stack.add(construct_simple_cache_middleware( cache_class=dict, rpc_whitelist={'fake_endpoint'}, )) w3.manager.request_blocking('fake_endpoint', []) w3.manager.request_blocking('fake_endpoint', []) assert next(counter) == 2
def test_latest_block_cache_middleware_does_not_cache_bad_responses( w3_base, block_data_middleware, latest_block_based_cache_middleware): counter = itertools.count() w3 = w3_base def result_cb(method, params): next(counter) return None w3 = w3_base w3.middleware_stack.add(block_data_middleware) w3.middleware_stack.add( construct_result_generator_middleware({ 'fake_endpoint': result_cb, })) w3.middleware_stack.add(latest_block_based_cache_middleware) w3.manager.request_blocking('fake_endpoint', []) w3.manager.request_blocking('fake_endpoint', []) assert next(counter) == 2
def test_latest_block_cache_middleware_does_not_cache_bad_responses( w3_base, block_data_middleware, latest_block_based_cache_middleware): counter = itertools.count() w3 = w3_base def result_cb(method, params): next(counter) return None w3 = w3_base w3.middleware_stack.add(block_data_middleware) w3.middleware_stack.add(construct_result_generator_middleware({ 'fake_endpoint': result_cb, })) w3.middleware_stack.add(latest_block_based_cache_middleware) w3.manager.request_blocking('fake_endpoint', []) w3.manager.request_blocking('fake_endpoint', []) assert next(counter) == 2
def result_generator_middleware(): return construct_result_generator_middleware({ 'eth_sendRawTransaction': lambda *args: args, 'net_version': lambda *_: 1, })
def result_generator_middleware(): return construct_result_generator_middleware({ 'eth_getLogs': lambda _, params: params, })
def result_generator_middleware(): return construct_result_generator_middleware({ 'fake_endpoint': lambda *_: str(uuid.uuid4()), 'not_whitelisted': lambda *_: str(uuid.uuid4()), })