Add eth adapter to tx helper
This commit is contained in:
parent
347e117eb9
commit
f0e00152b7
@ -1,7 +1,7 @@
|
|||||||
* 0.4.13-unreleased
|
* 0.4.13-unreleased
|
||||||
- Implement DictKeystore
|
- Implement DictKeystore
|
||||||
- Remove unused insert_key method in keystore interface
|
- Remove unused insert_key method in keystore interface
|
||||||
- Add transaction executor helper
|
- Add transaction executor helper, with adapter helper for eth
|
||||||
* 0.4.12
|
* 0.4.12
|
||||||
- Enforce hex strings in signer backend for sign message
|
- Enforce hex strings in signer backend for sign message
|
||||||
* 0.4.11
|
* 0.4.11
|
||||||
|
1
crypto_dev_signer/eth/helper/__init__.py
Normal file
1
crypto_dev_signer/eth/helper/__init__.py
Normal file
@ -0,0 +1 @@
|
|||||||
|
from .tx import EthTxExecutor
|
49
crypto_dev_signer/eth/helper/tx.py
Normal file
49
crypto_dev_signer/eth/helper/tx.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
# standard imports
|
||||||
|
import logging
|
||||||
|
|
||||||
|
# local imports
|
||||||
|
from crypto_dev_signer.helper import TxExecutor
|
||||||
|
|
||||||
|
logg = logging.getLogger()
|
||||||
|
logging.getLogger('web3').setLevel(logging.CRITICAL)
|
||||||
|
logging.getLogger('urllib3').setLevel(logging.CRITICAL)
|
||||||
|
|
||||||
|
|
||||||
|
class EthTxExecutor(TxExecutor):
|
||||||
|
|
||||||
|
def __init__(self, w3, sender, signer, chain_id, verifier=None, block=False):
|
||||||
|
self.w3 = w3
|
||||||
|
nonce = self.w3.eth.getTransactionCount(sender, 'pending')
|
||||||
|
super(EthTxExecutor, self).__init__(sender, signer, self.translator, self.dispatcher, self.reporter, nonce, chain_id, self.fee_helper, self.fee_price_helper, verifier, block)
|
||||||
|
|
||||||
|
|
||||||
|
def fee_helper(self, tx):
|
||||||
|
estimate = self.w3.eth.estimateGas(tx)
|
||||||
|
if estimate < 21000:
|
||||||
|
estimate = 21000
|
||||||
|
logg.debug('estimate {} {}'.format(tx, estimate))
|
||||||
|
return estimate
|
||||||
|
|
||||||
|
|
||||||
|
def fee_price_helper(self):
|
||||||
|
return self.w3.eth.gasPrice
|
||||||
|
|
||||||
|
|
||||||
|
def dispatcher(self, tx):
|
||||||
|
return self.w3.eth.sendRawTransaction(tx)
|
||||||
|
|
||||||
|
|
||||||
|
def reporter(self, tx):
|
||||||
|
return self.w3.eth.getTransactionReceipt(tx)
|
||||||
|
|
||||||
|
|
||||||
|
def translator(self, tx):
|
||||||
|
if tx.get('feePrice') != None:
|
||||||
|
tx['gasPrice'] = tx['feePrice']
|
||||||
|
del tx['feePrice']
|
||||||
|
|
||||||
|
if tx.get('feeUnits') != None:
|
||||||
|
tx['gas'] = tx['feeUnits']
|
||||||
|
del tx['feeUnits']
|
||||||
|
|
||||||
|
return tx
|
@ -13,8 +13,9 @@ logg = logging.getLogger()
|
|||||||
|
|
||||||
class TxExecutor:
|
class TxExecutor:
|
||||||
|
|
||||||
def __init__(self, sender, signer, dispatcher, reporter, nonce, chain_id, fee_helper=None, fee_price_helper=None, verifier=None, block=False):
|
def __init__(self, sender, signer, translator, dispatcher, reporter, nonce, chain_id, fee_helper=None, fee_price_helper=None, verifier=None, block=False):
|
||||||
self.sender = sender
|
self.sender = sender
|
||||||
|
self.translator = translator
|
||||||
self.nonce = nonce
|
self.nonce = nonce
|
||||||
self.signer = signer
|
self.signer = signer
|
||||||
self.dispatcher = dispatcher
|
self.dispatcher = dispatcher
|
||||||
@ -33,7 +34,7 @@ class TxExecutor:
|
|||||||
self.verifier = verifier
|
self.verifier = verifier
|
||||||
|
|
||||||
|
|
||||||
def noop_fee_helper(self, sender, code, inputs):
|
def noop_fee_helper(self, tx):
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
|
|
||||||
@ -45,21 +46,29 @@ class TxExecutor:
|
|||||||
return rcpt
|
return rcpt
|
||||||
|
|
||||||
|
|
||||||
|
def noop_translator(self, tx):
|
||||||
|
return tx
|
||||||
|
|
||||||
|
|
||||||
def sign_and_send(self, builder, force_wait=False):
|
def sign_and_send(self, builder, force_wait=False):
|
||||||
fee_units = self.fee_helper(self.sender, None, None)
|
|
||||||
|
fee_price = self.fee_price_helper()
|
||||||
|
|
||||||
tx_tpl = {
|
tx_tpl = {
|
||||||
'from': self.sender,
|
'from': self.sender,
|
||||||
'chainId': self.chain_id,
|
'chainId': self.chain_id,
|
||||||
'feeUnits': fee_units,
|
'feeUnits': 0, #fee_units,
|
||||||
'feePrice': self.fee_price_helper(),
|
'feePrice': fee_price,
|
||||||
'nonce': self.nonce,
|
'nonce': self.nonce,
|
||||||
}
|
}
|
||||||
|
|
||||||
tx = tx_tpl
|
tx = self.translator(tx_tpl)
|
||||||
for b in builder:
|
for b in builder:
|
||||||
tx = b(tx)
|
tx = b(tx)
|
||||||
|
|
||||||
|
tx['feeUnits'] = self.fee_helper(tx)
|
||||||
|
tx = self.translator(tx)
|
||||||
|
|
||||||
logg.debug('from {} nonce {} tx {}'.format(self.sender, self.nonce, tx))
|
logg.debug('from {} nonce {} tx {}'.format(self.sender, self.nonce, tx))
|
||||||
|
|
||||||
chain_tx = EIP155Transaction(tx, self.nonce, self.chain_id)
|
chain_tx = EIP155Transaction(tx, self.nonce, self.chain_id)
|
||||||
|
3
setup.py
3
setup.py
@ -24,13 +24,14 @@ f.close()
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name="crypto-dev-signer",
|
name="crypto-dev-signer",
|
||||||
version="0.4.13b1",
|
version="0.4.13b2",
|
||||||
description="A signer and keystore daemon and library for cryptocurrency software development",
|
description="A signer and keystore daemon and library for cryptocurrency software development",
|
||||||
author="Louis Holbrook",
|
author="Louis Holbrook",
|
||||||
author_email="dev@holbrook.no",
|
author_email="dev@holbrook.no",
|
||||||
packages=[
|
packages=[
|
||||||
'crypto_dev_signer.eth.signer',
|
'crypto_dev_signer.eth.signer',
|
||||||
'crypto_dev_signer.eth.web3ext',
|
'crypto_dev_signer.eth.web3ext',
|
||||||
|
'crypto_dev_signer.eth.helper',
|
||||||
'crypto_dev_signer.eth',
|
'crypto_dev_signer.eth',
|
||||||
'crypto_dev_signer.keystore',
|
'crypto_dev_signer.keystore',
|
||||||
'crypto_dev_signer.runnable',
|
'crypto_dev_signer.runnable',
|
||||||
|
@ -3,10 +3,14 @@ import unittest
|
|||||||
import logging
|
import logging
|
||||||
import os
|
import os
|
||||||
|
|
||||||
|
# third-party imports
|
||||||
|
import web3
|
||||||
|
|
||||||
# local imports
|
# local imports
|
||||||
from crypto_dev_signer.keystore import DictKeystore
|
from crypto_dev_signer.keystore import DictKeystore
|
||||||
from crypto_dev_signer.eth.signer import ReferenceSigner
|
from crypto_dev_signer.eth.signer import ReferenceSigner
|
||||||
from crypto_dev_signer.helper import TxExecutor
|
from crypto_dev_signer.helper import TxExecutor
|
||||||
|
from crypto_dev_signer.eth.helper import EthTxExecutor
|
||||||
|
|
||||||
logging.basicConfig(level=logging.DEBUG)
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
logg = logging.getLogger()
|
logg = logging.getLogger()
|
||||||
@ -29,21 +33,23 @@ class MockEthTxBackend:
|
|||||||
def fee_price_helper(self):
|
def fee_price_helper(self):
|
||||||
return 21
|
return 21
|
||||||
|
|
||||||
def fee_helper(self, sender, code, inputs):
|
def fee_helper(self, tx):
|
||||||
logg.debug('fee helper code {} inputs {}'.format(code, inputs))
|
logg.debug('fee helper tx {}'.format(tx))
|
||||||
return 2
|
return 2
|
||||||
|
|
||||||
def builder(self, tx):
|
def builder(self, tx):
|
||||||
return {
|
return tx
|
||||||
'from': tx['from'],
|
|
||||||
'to': '0x' + os.urandom(20).hex(),
|
|
||||||
'data': '',
|
|
||||||
'gasPrice': tx['feePrice'],
|
|
||||||
'gas': tx['feeUnits'],
|
|
||||||
}
|
|
||||||
|
|
||||||
def builder_two(self, tx):
|
def builder_two(self, tx):
|
||||||
tx['value'] = 1024
|
tx['value'] = 10243
|
||||||
|
tx['to'] = web3.Web3.toChecksumAddress('0x' + os.urandom(20).hex())
|
||||||
|
tx['data'] = ''
|
||||||
|
if tx.get('feePrice') != None:
|
||||||
|
tx['gasPrice'] = tx['feePrice']
|
||||||
|
del tx['feePrice']
|
||||||
|
if tx.get('feeUnits') != None:
|
||||||
|
tx['gas'] = tx['feeUnits']
|
||||||
|
del tx['feeUnits']
|
||||||
return tx
|
return tx
|
||||||
|
|
||||||
|
|
||||||
@ -66,10 +72,21 @@ class TestHelper(unittest.TestCase):
|
|||||||
|
|
||||||
def test_helper(self):
|
def test_helper(self):
|
||||||
backend = MockEthTxBackend()
|
backend = MockEthTxBackend()
|
||||||
executor = TxExecutor(self.address_hex, self.signer, backend.dispatcher, backend.reporter, 666, 13, backend.fee_helper, backend.fee_price_helper, backend.verifier)
|
executor = TxExecutor(self.address_hex, self.signer, backend.builder, backend.dispatcher, backend.reporter, 666, 13, backend.fee_helper, backend.fee_price_helper, backend.verifier)
|
||||||
|
|
||||||
tx_ish = {'from': self.address_hex}
|
tx_ish = {'from': self.address_hex}
|
||||||
executor.sign_and_send([backend.builder, backend.builder_two])
|
executor.sign_and_send([backend.builder_two])
|
||||||
|
|
||||||
|
|
||||||
|
def test_eth_helper(self):
|
||||||
|
backend = MockEthTxBackend()
|
||||||
|
w3 = web3.Web3(web3.Web3.HTTPProvider('http://localhost:8545'))
|
||||||
|
executor = EthTxExecutor(w3, self.address_hex, self.signer, 8996)
|
||||||
|
|
||||||
|
tx_ish = {'from': self.address_hex}
|
||||||
|
#executor.sign_and_send([backend.builder, backend.builder_two])
|
||||||
|
with self.assertRaises(ValueError):
|
||||||
|
executor.sign_and_send([backend.builder_two])
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
Loading…
Reference in New Issue
Block a user