chaind-eth/chaind_eth/cli/retry.py

82 lines
2.5 KiB
Python

# standard imports
import logging
# external imports
from chainlib.eth.gas import price
from chainlib.eth.tx import unpack
from chaind.error import TxSourceError
from crypto_dev_signer.eth.transaction import EIP155Transaction
from chainlib.eth.gas import Gas
from hexathon import (
add_0x,
strip_0x,
)
# local imports
from chaind_eth.cli.tx import TxProcessor
logg = logging.getLogger(__name__)
DEFAULT_GAS_FACTOR = 1.1
class Retrier:
def __init__(self, sender, signer, source, chain_spec, gas_oracle, gas_factor=DEFAULT_GAS_FACTOR):
self.sender = sender
self.signer = signer
self.source = source
self.raw_content = []
self.content = []
self.cursor = 0
self.gas_oracle = gas_oracle
self.gas_factor = gas_factor
self.chain_spec = chain_spec
self.chain_id = chain_spec.chain_id()
self.processor = [TxProcessor()]
def load(self, process=True):
for processor in self.processor:
self.raw_content = processor.load(self.source)
if self.raw_content != None:
if process:
#try:
self.process()
#except Exception as e:
# raise TxSourceError('invalid source contents: {}'.format(str(e)))
return self.content
raise TxSourceError('unparseable source')
def process(self):
gas_data = self.gas_oracle.get_gas()
gas_price = gas_data[0]
for tx in self.raw_content:
tx_bytes = bytes.fromhex(strip_0x(tx))
tx = unpack(tx_bytes, self.chain_spec)
tx_gas_price_old = int(tx['gasPrice'])
if tx_gas_price_old < gas_price:
tx['gasPrice'] = gas_price
else:
tx['gasPrice'] = int(tx_gas_price_old * self.gas_factor)
if tx_gas_price_old == tx['gasPrice']:
tx['gasPrice'] += 1
tx_obj = EIP155Transaction(tx, tx['nonce'], self.chain_id)
new_tx_bytes = self.signer.sign_transaction_to_wire(tx_obj)
logg.debug('add tx {} with gas price changed from {} to {}: {}'.format(tx['hash'], tx_gas_price_old, tx['gasPrice'], new_tx_bytes.hex()))
self.content.append(new_tx_bytes)
def __iter__(self):
self.cursor = 0
return self
def __next__(self):
if self.cursor == len(self.content):
raise StopIteration()
tx = self.content[self.cursor]
self.cursor += 1
return tx