Allow to set the gas strategy at the interface layer

pull/2425/head
David Núñez 2020-10-22 00:06:50 +02:00
parent 3b70b06a8a
commit 50366c2fde
2 changed files with 25 additions and 17 deletions

View File

@ -280,22 +280,27 @@ class BlockchainInterface:
self.log.debug('Injecting POA middleware at layer 0') self.log.debug('Injecting POA middleware at layer 0')
self.client.inject_middleware(geth_poa_middleware, layer=0) self.client.inject_middleware(geth_poa_middleware, layer=0)
# Gas Price Strategy:
# Bundled web3 strategies are too expensive for Infura (it takes ~1 minute to get a price),
# so we use external gas price oracles, instead (see #2139)
if isinstance(self.client, InfuraClient):
gas_strategy = datafeed_fallback_gas_price_strategy
self.gas_strategy = 'fast' # FIXME
else:
gas_strategy = self.get_gas_strategy(self.gas_strategy)
self.client.set_gas_strategy(gas_strategy=gas_strategy)
gwei_gas_price = Web3.fromWei(self.client.gas_price_for_transaction(), 'gwei')
self.log.debug(f"Currently, our gas strategy returns a gas price of {gwei_gas_price} gwei")
self.client.add_middleware(middleware.time_based_cache_middleware) self.client.add_middleware(middleware.time_based_cache_middleware)
# self.client.add_middleware(middleware.latest_block_based_cache_middleware) # self.client.add_middleware(middleware.latest_block_based_cache_middleware)
self.client.add_middleware(middleware.simple_cache_middleware) self.client.add_middleware(middleware.simple_cache_middleware)
self.set_gas_strategy()
def set_gas_strategy(self, gas_strategy: Optional[Callable] = None):
if gas_strategy:
reported_gas_strategy = f"fixed/{gas_strategy.name}"
elif isinstance(self.client, InfuraClient):
gas_strategy = datafeed_fallback_gas_price_strategy
self.gas_strategy = 'fast'
reported_gas_strategy = "datafeed/fast"
else:
reported_gas_strategy = f"web3/{self.gas_strategy}"
gas_strategy = self.get_gas_strategy(self.gas_strategy)
self.client.set_gas_strategy(gas_strategy=gas_strategy)
gwei_gas_price = Web3.fromWei(self.client.gas_price_for_transaction(), 'gwei')
self.log.debug(f"Using gas strategy '{reported_gas_strategy}'. "
f"Currently, it returns a gas price of {gwei_gas_price} gwei")
def connect(self): def connect(self):
# Spawn child process # Spawn child process

View File

@ -15,8 +15,7 @@
along with nucypher. If not, see <https://www.gnu.org/licenses/>. along with nucypher. If not, see <https://www.gnu.org/licenses/>.
""" """
import datetime import datetime
import functools from typing import Callable, Optional
from typing import Callable
from web3 import Web3 from web3 import Web3
from web3.exceptions import ValidationError from web3.exceptions import ValidationError
@ -64,20 +63,24 @@ __RAW_WEB3_GAS_STRATEGIES = {
} }
def wrap_web3_gas_strategy(web3_gas_strategy: Callable): def wrap_web3_gas_strategy(speed: Optional[str] = None):
""" """
Enriches the web3 exceptions thrown by gas strategies Enriches the web3 exceptions thrown by gas strategies
""" """
@functools.wraps(web3_gas_strategy) web3_gas_strategy = __RAW_WEB3_GAS_STRATEGIES[speed]
def _wrapper(*args, **kwargs): def _wrapper(*args, **kwargs):
try: try:
return web3_gas_strategy(*args, **kwargs) return web3_gas_strategy(*args, **kwargs)
except ValidationError as e: except ValidationError as e:
raise GasStrategyError("Calling the web3 gas strategy failed, probably due to an unsynced chain.") from e raise GasStrategyError("Calling the web3 gas strategy failed, probably due to an unsynced chain.") from e
_wrapper.name = speed
return _wrapper return _wrapper
WEB3_GAS_STRATEGIES = {speed: wrap_web3_gas_strategy(strategy) for speed, strategy in __RAW_WEB3_GAS_STRATEGIES.items()} WEB3_GAS_STRATEGIES = {speed: wrap_web3_gas_strategy(speed) for speed in __RAW_WEB3_GAS_STRATEGIES}
EXPECTED_CONFIRMATION_TIME_IN_SECONDS = { EXPECTED_CONFIRMATION_TIME_IN_SECONDS = {
'slow': int(datetime.timedelta(hours=1).total_seconds()), 'slow': int(datetime.timedelta(hours=1).total_seconds()),