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.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.latest_block_based_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):
# Spawn child process

View File

@ -15,8 +15,7 @@
along with nucypher. If not, see <https://www.gnu.org/licenses/>.
"""
import datetime
import functools
from typing import Callable
from typing import Callable, Optional
from web3 import Web3
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
"""
@functools.wraps(web3_gas_strategy)
web3_gas_strategy = __RAW_WEB3_GAS_STRATEGIES[speed]
def _wrapper(*args, **kwargs):
try:
return web3_gas_strategy(*args, **kwargs)
except ValidationError as e:
raise GasStrategyError("Calling the web3 gas strategy failed, probably due to an unsynced chain.") from e
_wrapper.name = speed
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 = {
'slow': int(datetime.timedelta(hours=1).total_seconds()),