Beispiel #1
0
    def gas_price_strategy_eth_gas_station_or_with_margin(
            web3: Web3, transaction_params):
        # FIXME: This is a temporary fix to speed up gas price generation
        # by fetching from eth_gas_station if possible.
        # Once we have a reliable gas price calculation this can be removed
        if int(web3.net.version) == 1:
            try:
                response = requests.get(ETH_GAS_STATION_API)
                if response and response.status_code == 200:
                    data = response.json()
                    log.debug(
                        f"fetched gas price: {Wei(int(data['fast'] * 10e7 * 1.1))} Wei"
                    )
                    return Wei(int(data["fast"] * 10e7 * 1.1))
            except (TimeoutError, ConnectionError, KeyError):
                log.debug(
                    "Could not fetch from ethgasstation. Falling back to web3 gas estimation."
                )

        gas_price_strategy = construct_time_based_gas_price_strategy(
            max_wait_seconds=15, sample_size=25)
        gas_price = Wei(
            int(
                gas_price_strategy(web3, transaction_params) *
                GAS_PRICE_MARGIN))
        return gas_price
Beispiel #2
0
def setup_gas_strategy(w3, transaction_wait):
    w3.eth.setGasPriceStrategy(
        construct_time_based_gas_price_strategy(transaction_wait))

    w3.middleware_onion.add(middleware.time_based_cache_middleware)
    w3.middleware_onion.add(middleware.latest_block_based_cache_middleware)
    w3.middleware_onion.add(middleware.simple_cache_middleware)
Beispiel #3
0
def get_web3_client(
    http_endpoint: str = "",
    ws_endpoint: str = "",
    ws_endpoint_timeout: int = 60,
    apply_gas_price_strategy: bool = False,
    max_tx_wait_seconds: int = 120,
    inject_retry_request: bool = False,
    inject_poa: bool = False,
    inject_local_filter: bool = False,
    inject_stale_check: bool = False,
    stale_check_allowable_delay: Union[int, None] = None,
) -> Web3:
    """Returns instance of the Web3 client."""
    # Either http or ws endpoint must be provided (prefer ws over http)
    if ws_endpoint:
        w3 = Web3(
            Web3.WebsocketProvider(ws_endpoint,
                                   websocket_timeout=ws_endpoint_timeout))
        logger.info(f"Using Web3 websocket endpoint {ws_endpoint}")

        if inject_retry_request:
            w3.middleware_onion.add(ws_retry_request_middleware)
            logger.info("Injected request retry middleware")
    else:
        w3 = Web3(Web3.HTTPProvider(http_endpoint))
        logger.info(f"Using Web3 HTTP endpoint {http_endpoint}")

        if inject_retry_request:
            w3.middleware_onion.add(http_retry_request_middleware)
            logger.info("Injected request retry middleware")

    if inject_poa:
        w3.middleware_onion.inject(geth_poa_middleware, layer=0)
        logger.info("Injected POA middleware")

    if inject_stale_check and stale_check_allowable_delay is not None:
        stale_check_middleware = make_stalecheck_middleware(
            stale_check_allowable_delay)
        w3.middleware_onion.add(stale_check_middleware)
        logger.info("Injected stale check middleware")

    if inject_local_filter:
        w3.middleware_onion.add(local_filter_middleware)
        logger.info("Injected local filter middleware")

    if apply_gas_price_strategy:
        w3.eth.setGasPriceStrategy(
            construct_time_based_gas_price_strategy(
                max_wait_seconds=max_tx_wait_seconds,
                weighted=True,
                sample_size=120,
            ))
        w3.middleware_onion.add(_time_based_cache_middleware)
        w3.middleware_onion.add(_latest_block_based_cache_middleware)
        w3.middleware_onion.add(_simple_cache_middleware)
        logger.info(
            f"Set gas price strategy with {max_tx_wait_seconds} wait seconds")

    return w3
Beispiel #4
0
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
Beispiel #6
0
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
Beispiel #8
0
    def __init__(self, node_uri, use_ipc=False, use_poa=False):
        """ Create instance to interact with the contract deployer.

        Args:
            node_uri (str): Either the http address of an ethereum node or the
                      path to the IPC file if 'use_ipc=True'.
            use_ipc (bool): If True then 'node_uri' will be treated as a file
                     path to the 'geth.ipc' file of the node to connect to.
            use_poa (bool): If True then it will inject 'geth_poa_middleware'
                     to the web3 instance. When 'node_uri' refers to a Rinkeby
                     node then this needs to be set to True.
        """
        if use_ipc:
            provider = IPCProvider(node_uri)
        else:
            provider = HTTPProvider(node_uri)

        self.w3 = Web3(provider)
        self.default_account = None
        self.contract_data = None

        if use_poa:
            # Needed only with PoA (Rinkeby)
            self.w3.middleware_stack.inject(middleware.geth_poa_middleware,
                                            layer=0)

        block_sample = 40
        prob = 95  # Probability to be included
        express_strategy = construct_time_based_gas_price_strategy(
            30, block_sample, prob)

        self.w3.eth.setGasPriceStrategy(express_strategy)
        # Tries to make transactions faster (and more expensive?)
        # self.w3.eth.setGasPriceStrategy(fast_gas_price_strategy)
        self.w3.middleware_stack.add(middleware.time_based_cache_middleware)
        self.w3.middleware_stack.add(
            middleware.latest_block_based_cache_middleware)
        self.w3.middleware_stack.add(middleware.simple_cache_middleware)
Beispiel #9
0
import functools

from cachetools import LRUCache
from web3.gas_strategies.time_based import construct_time_based_gas_price_strategy
from web3.middleware.cache import construct_simple_cache_middleware
from web3.types import RPCEndpoint

BLOCK_HASH_CACHE_RPC_WHITELIST = {RPCEndpoint("eth_getBlockByHash")}


block_hash_cache_middleware = construct_simple_cache_middleware(
    # default sample size of gas price strategies is 120
    cache_class=functools.partial(LRUCache, 150),  # type: ignore
    rpc_whitelist=BLOCK_HASH_CACHE_RPC_WHITELIST,
)

faster_gas_price_strategy = construct_time_based_gas_price_strategy(
    max_wait_seconds=15, sample_size=120, probability=99
)