funga/crypto_dev_signer/helper/tx.py

90 lines
2.6 KiB
Python
Raw Normal View History

2021-01-09 22:05:24 +01:00
# standard imports
import logging
2021-01-09 22:59:27 +01:00
import time
2021-01-09 22:05:24 +01:00
# third-party imports
from crypto_dev_signer.eth.transaction import EIP155Transaction
# local imports
from crypto_dev_signer.error import TransactionRevertError
logg = logging.getLogger()
class TxExecutor:
2021-01-09 22:59:27 +01:00
def __init__(self, sender, signer, dispatcher, reporter, nonce, chain_id, fee_helper=None, fee_price_helper=None, verifier=None, block=False):
2021-01-09 22:05:24 +01:00
self.sender = sender
self.nonce = nonce
self.signer = signer
self.dispatcher = dispatcher
self.reporter = reporter
self.block = bool(block)
self.chain_id = chain_id
self.tx_hashes = []
2021-01-09 22:59:27 +01:00
if fee_helper == None:
fee_helper = self.noop_fee_helper
2021-01-09 22:05:24 +01:00
self.fee_helper = fee_helper
2021-01-09 22:59:27 +01:00
if fee_price_helper == None:
fee_price_helper = self.noop_fee_price_helper
self.fee_price_helper = fee_price_helper
if verifier == None:
verifier = self.noop_verifier
self.verifier = verifier
def noop_fee_helper(self, sender, code, inputs):
return 1
def noop_fee_price_helper(self):
return 1
def noop_verifier(self, rcpt):
return rcpt
2021-01-09 22:05:24 +01:00
def sign_and_send(self, builder, force_wait=False):
fee_units = self.fee_helper(self.sender, None, None)
tx_tpl = {
'from': self.sender,
'chainId': self.chain_id,
2021-01-09 22:59:27 +01:00
'feeUnits': fee_units,
2021-01-09 22:05:24 +01:00
'feePrice': self.fee_price_helper(),
'nonce': self.nonce,
}
2021-01-09 22:59:27 +01:00
tx = tx_tpl
2021-01-09 22:05:24 +01:00
for b in builder:
2021-01-09 22:59:27 +01:00
tx = b(tx)
2021-01-09 22:05:24 +01:00
logg.debug('from {} nonce {} tx {}'.format(self.sender, self.nonce, tx))
chain_tx = EIP155Transaction(tx, self.nonce, self.chain_id)
signature = self.signer.signTransaction(chain_tx)
chain_tx_serialized = chain_tx.rlp_serialize()
tx_hash = self.dispatcher('0x' + chain_tx_serialized.hex())
self.tx_hashes.append(tx_hash)
self.nonce += 1
rcpt = None
if self.block or force_wait:
rcpt = self.wait_for(tx_hash)
return (tx_hash.hex(), rcpt)
def wait_for(self, tx_hash=None):
if tx_hash == None:
tx_hash = self.tx_hashes[len(self.tx_hashes)-1]
i = 1
while True:
try:
#return self.w3.eth.getTransactionReceipt(tx_hash)
return self.reporter(tx_hash)
2021-01-09 22:59:27 +01:00
except Exception:
2021-01-09 22:05:24 +01:00
logg.debug('poll #{} for {}'.format(i, tx_hash.hex()))
i += 1
time.sleep(1)
2021-01-09 22:59:27 +01:00
return self.verifier(rcpt)