82 lines
2.5 KiB
Python
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
|