class DynamicGasPrice(GasPrice): GWEI = 1000000000 def __init__(self, arguments): self.gas_station = None self.fixed_gas = None if arguments.ethgasstation_api_key: self.gas_station = EthGasStation( refresh_interval=60, expiry=600, api_key=arguments.ethgasstation_api_key) elif arguments.etherchain_gas: self.gas_station = EtherchainOrg(refresh_interval=60, expiry=600) elif arguments.poanetwork_gas: self.gas_station = POANetwork(refresh_interval=60, expiry=600, alt_url=arguments.poanetwork_url) elif arguments.fixed_gas_price: self.fixed_gas = int(round(arguments.fixed_gas_price * self.GWEI)) self.initial_multiplier = arguments.gas_initial_multiplier self.reactive_multiplier = arguments.gas_reactive_multiplier self.gas_maximum = int(round(arguments.gas_maximum * self.GWEI)) if self.fixed_gas: assert self.fixed_gas <= self.gas_maximum def get_gas_price(self, time_elapsed: int) -> Optional[int]: # start with fast price from the configured gas API fast_price = self.gas_station.fast_price( ) if self.gas_station else None # if API produces no price, or remote feed not configured, start with a fixed price if fast_price is None: initial_price = self.fixed_gas if self.fixed_gas else 10 * self.GWEI # otherwise, use the API's fast price, adjusted by a coefficient, as our starting point else: initial_price = int(round(fast_price * self.initial_multiplier)) return GeometricGasPrice( initial_price=initial_price, every_secs=30, coefficient=self.reactive_multiplier, max_price=self.gas_maximum).get_gas_price(time_elapsed) def __str__(self): retval = "" if self.gas_station: retval = f"{type(self.gas_station)} fast gas price with initial multiplier {self.initial_multiplier} " elif self.fixed_gas: retval = f"Fixed gas price {round(self.fixed_gas / self.GWEI, 1)} Gwei " else: retval = f"Default gas 10 Gwei " retval += f"and will multiply by {self.reactive_multiplier} every 30s to a maximum of " \ f"{round(self.gas_maximum / self.GWEI, 1)} Gwei" return retval def __repr__(self): return f"DynamicGasPrice({pformat(vars(self))})"
class DynamicGasPrice(GasPrice): GWEI = 1000000000 def __init__(self, arguments): self.gas_station = None if arguments.ethgasstation_api_key: self.gas_station = EthGasStation( refresh_interval=60, expiry=600, api_key=arguments.ethgasstation_api_key) elif arguments.etherchain_gas: self.gas_station = EtherchainOrg(refresh_interval=60, expiry=600) elif arguments.poanetwork_gas: self.gas_station = POANetwork(refresh_interval=60, expiry=600, alt_url=arguments.poanetwork_url) def get_gas_price(self, time_elapsed: int) -> Optional[int]: # start with standard price plus backup in case gas price API is down, then do fast if 0 <= time_elapsed <= 60: standard_price = self.gas_station.standard_price( ) if self.gas_station else None if standard_price is not None: return int(standard_price * 1.1) else: return self.default_gas_pricing(time_elapsed) # move to fast after a minute else: fast_price = self.gas_station.fast_price( ) if self.gas_station else None if fast_price is not None: return int(fast_price * 1.1) else: return self.default_gas_pricing(time_elapsed) # default gas pricing when EthGasStation feed is down def default_gas_pricing(self, time_elapsed: int): return IncreasingGasPrice(initial_price=5 * self.GWEI, increase_by=10 * self.GWEI, every_secs=60, max_price=100 * self.GWEI).get_gas_price(time_elapsed)
def test_poanetwork_integration(): logging.basicConfig(format='%(asctime)-15s %(levelname)-8s %(message)s', level=logging.DEBUG) logging.getLogger('urllib3.connectionpool').setLevel(logging.INFO) logging.getLogger('requests.packages.urllib3.connectionpool').setLevel(logging.INFO) poa = POANetwork(10, 600) while True: safe_low_price = poa.safe_low_price() logging.info(safe_low_price) standard_price = poa.standard_price() logging.info(standard_price) fast_price = poa.fast_price() logging.info(fast_price) if safe_low_price is not None and standard_price is not None and fast_price is not None: break time.sleep(1)