예제 #1
0
def test_datafeed_median_gas_price_strategy():

    mock_etherchain_gas_price = 1000
    mock_upvest_gas_price = 2000
    mock_zoltu_gas_price = 4000
    mock_rpc_gas_price = 42

    def construct_mock_gas_strategy(gas_price) -> Callable:
        def _mock_gas_strategy(web3, tx=None):
            return gas_price
        return _mock_gas_strategy

    # In normal circumstances, all datafeeds in the strategy work, and the median is returned
    with patch('nucypher.utilities.datafeeds.UpvestGasPriceDatafeed.construct_gas_strategy',
               return_value=construct_mock_gas_strategy(mock_upvest_gas_price)):
        with patch('nucypher.utilities.datafeeds.EtherchainGasPriceDatafeed.construct_gas_strategy',
                   return_value=construct_mock_gas_strategy(mock_etherchain_gas_price)):
            with patch('nucypher.utilities.datafeeds.ZoltuGasPriceDatafeed.construct_gas_strategy',
                       return_value=construct_mock_gas_strategy(mock_zoltu_gas_price)):
                datafeed_median_gas_price_strategy = construct_datafeed_median_strategy()
                assert datafeed_median_gas_price_strategy("web3", "tx") == median([mock_etherchain_gas_price,
                                                                                   mock_upvest_gas_price,
                                                                                   mock_zoltu_gas_price])

    # If, for example, Upvest fails, the median is computed using the other two feeds
    with patch('nucypher.utilities.datafeeds.UpvestGasPriceDatafeed._probe_feed',
               side_effect=Datafeed.DatafeedError):
        with patch('nucypher.utilities.datafeeds.EtherchainGasPriceDatafeed.construct_gas_strategy',
                   return_value=construct_mock_gas_strategy(mock_etherchain_gas_price)):
            with patch('nucypher.utilities.datafeeds.ZoltuGasPriceDatafeed.construct_gas_strategy',
                       return_value=construct_mock_gas_strategy(mock_zoltu_gas_price)):
                datafeed_median_gas_price_strategy = construct_datafeed_median_strategy()
                assert datafeed_median_gas_price_strategy("web3", "tx") == median([mock_etherchain_gas_price,
                                                                                   mock_zoltu_gas_price])

    # If only one feed works, then the return value corresponds to this feed
    with patch('nucypher.utilities.datafeeds.UpvestGasPriceDatafeed._probe_feed',
               side_effect=Datafeed.DatafeedError):
        with patch('nucypher.utilities.datafeeds.EtherchainGasPriceDatafeed._probe_feed',
                   side_effect=Datafeed.DatafeedError):
            with patch('nucypher.utilities.datafeeds.ZoltuGasPriceDatafeed.construct_gas_strategy',
                       return_value=construct_mock_gas_strategy(mock_zoltu_gas_price)):
                datafeed_median_gas_price_strategy = construct_datafeed_median_strategy()
                assert datafeed_median_gas_price_strategy("web3", "tx") == mock_zoltu_gas_price

    # If all feeds fail, we fallback to the rpc_gas_price_strategy
    with patch('nucypher.utilities.datafeeds.EtherchainGasPriceDatafeed._probe_feed',
               side_effect=Datafeed.DatafeedError):
        with patch('nucypher.utilities.datafeeds.UpvestGasPriceDatafeed._probe_feed',
                   side_effect=Datafeed.DatafeedError):
            with patch('nucypher.utilities.datafeeds.ZoltuGasPriceDatafeed._probe_feed',
                   side_effect=Datafeed.DatafeedError):
                with patch('nucypher.utilities.gas_strategies.rpc_gas_price_strategy',
                           side_effect=construct_mock_gas_strategy(mock_rpc_gas_price)):
                    datafeed_median_gas_price_strategy = construct_datafeed_median_strategy()
                    assert datafeed_median_gas_price_strategy("web3", "tx") == mock_rpc_gas_price
예제 #2
0
    def configure_gas_strategy(self,
                               gas_strategy: Optional[Callable] = None
                               ) -> None:

        if gas_strategy:
            reported_gas_strategy = f"fixed/{gas_strategy.name}"

        elif isinstance(self.client, InfuraClient):
            gas_strategy = construct_datafeed_median_strategy(
                speed=self.gas_strategy)
            reported_gas_strategy = f"datafeed/{self.gas_strategy}"

        else:
            reported_gas_strategy = f"web3/{self.gas_strategy}"
            gas_strategy = self.get_gas_strategy(self.gas_strategy)

        configuration_message = f"Using gas strategy '{reported_gas_strategy}'"

        if self.max_gas_price:
            __price = Web3.toWei(self.max_gas_price,
                                 'gwei')  # from gwei to wei
            gas_strategy = max_price_gas_strategy_wrapper(
                gas_strategy=gas_strategy, max_gas_price_wei=__price)
            configuration_message += f", with a max price of {self.max_gas_price} gwei."

        self.client.set_gas_strategy(gas_strategy=gas_strategy)
        gwei_gas_price = Web3.fromWei(self.client.gas_price_for_transaction(),
                                      'gwei')

        self.log.info(configuration_message)
        self.log.debug(
            f"Gas strategy currently reports a gas price of {gwei_gas_price} gwei."
        )
예제 #3
0
    def configure_gas_strategy(self,
                               gas_strategy: Optional[Callable] = None
                               ) -> None:

        if gas_strategy:
            reported_gas_strategy = f"fixed/{gas_strategy.name}"

        elif isinstance(self.client, InfuraClient):
            gas_strategy = construct_datafeed_median_strategy(
                speed=self.gas_strategy)
            reported_gas_strategy = f"datafeed/{self.gas_strategy}"

        else:
            reported_gas_strategy = f"web3/{self.gas_strategy}"
            gas_strategy = self.get_gas_strategy(self.gas_strategy)

        configuration_message = f"Using gas strategy '{reported_gas_strategy}'"

        if self.max_gas_price:
            __price = Web3.toWei(self.max_gas_price,
                                 'gwei')  # from gwei to wei
            gas_strategy = max_price_gas_strategy_wrapper(
                gas_strategy=gas_strategy, max_gas_price_wei=__price)
            configuration_message += f", with a max price of {self.max_gas_price} gwei."

        self.client.set_gas_strategy(gas_strategy=gas_strategy)

        # TODO: This line must not be called prior to establishing a connection
        #        Move it down to a lower layer, near the client.
        # gwei_gas_price = Web3.fromWei(self.client.gas_price_for_transaction(), 'gwei')

        self.log.info(configuration_message)