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-10 18:27:44 +01:00
|
|
|
|
def __init__(self, sender, signer, translator, 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
|
2021-01-10 18:27:44 +01:00
|
|
|
|
self.translator = translator
|
2021-01-09 22:05:24 +01:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
|
2021-01-10 18:27:44 +01:00
|
|
|
|
def noop_fee_helper(self, tx):
|
2021-01-09 22:59:27 +01:00
|
|
|
|
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
|
|
|
|
|
|
|
|
|
|
2021-01-10 18:27:44 +01:00
|
|
|
|
def noop_translator(self, tx):
|
|
|
|
|
return tx
|
|
|
|
|
|
|
|
|
|
|
2021-01-09 22:05:24 +01:00
|
|
|
|
def sign_and_send(self, builder, force_wait=False):
|
2021-01-10 18:27:44 +01:00
|
|
|
|
|
|
|
|
|
fee_price = self.fee_price_helper()
|
2021-01-09 22:05:24 +01:00
|
|
|
|
|
|
|
|
|
tx_tpl = {
|
|
|
|
|
'from': self.sender,
|
|
|
|
|
'chainId': self.chain_id,
|
2021-01-10 18:27:44 +01:00
|
|
|
|
'feeUnits': 0, #fee_units,
|
|
|
|
|
'feePrice': fee_price,
|
2021-01-09 22:05:24 +01:00
|
|
|
|
'nonce': self.nonce,
|
|
|
|
|
}
|
2021-01-09 22:59:27 +01:00
|
|
|
|
|
2021-01-10 18:27:44 +01:00
|
|
|
|
tx = self.translator(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
|
|
|
|
|
2021-01-10 18:27:44 +01:00
|
|
|
|
tx['feeUnits'] = self.fee_helper(tx)
|
|
|
|
|
tx = self.translator(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)
|