commit 418c54e9c75d5fa5cbd703a2dfc00958e807f9f8
parent ffcde95e5f53ffc19b58d74e5407527a7999ec02
Author: nolash <dev@holbrook.no>
Date: Tue, 24 Aug 2021 17:55:01 +0200
Add generic wire methods for signer
Diffstat:
8 files changed, 71 insertions(+), 26 deletions(-)
diff --git a/chainlib/eth/cli.py b/chainlib/eth/cli.py
@@ -17,9 +17,17 @@ from crypto_dev_signer.eth.signer import ReferenceSigner as EIP155Signer
# local imports
from chainlib.eth.address import AddressChecksum
from chainlib.eth.connection import EthHTTPConnection
-
+from chainlib.eth.gas import (
+ OverrideGasOracle,
+ RPCGasOracle,
+ )
+from chainlib.eth.nonce import (
+ OverrideNonceOracle,
+ RPCNonceOracle,
+ )
script_dir = os.path.dirname(os.path.realpath(__file__))
+
class Wallet(BaseWallet):
"""Convenience constructor to set Ethereum defaults for chainlib cli Wallet object
@@ -32,10 +40,41 @@ class Wallet(BaseWallet):
class Rpc(BaseRpc):
"""Convenience constructor to set Ethereum defaults for chainlib cli Rpc object
+
+
"""
def __init__(self, wallet=None):
super(Rpc, self).__init__(EthHTTPConnection, wallet=wallet)
+
+ def connect_by_config(self, config):
+ """
+
+ If the standard arguments for nonce and fee price/price have been defined (which generate the configuration keys "_NONCE", "_FEE_PRICE" and "_FEE_LIMIT" respectively) , the corresponding overrides for fee and nonce generators will be defined.
+
+ """
+ super(Rpc, self).connect_by_config(config)
+
+ if self.can_sign():
+ nonce = config.get('_NONCE')
+ if nonce != None:
+ self.nonce_oracle = OverrideNonceOracle(self.get_sender_address(), nonce, id_generator=self.id_generator)
+ else:
+ self.nonce_oracle = RPCNonceOracle(self.get_sender_address(), self.conn, id_generator=self.id_generator)
+
+ fee_price = config.get('_FEE_PRICE')
+ fee_limit = config.get('_FEE_LIMIT')
+ if fee_price != None or fee_limit != None:
+ self.fee_oracle = OverrideGasOracle(price=fee_price, limit=fee_limit, conn=self.conn, id_generator=self.id_generator)
+ else:
+ self.fee_oracle = RPCGasOracle(self.conn, id_generator=self.id_generator)
+
+ return self.conn
+
+
+ def get_gas_oracle(self):
+ return self.get_fee_oracle()
+
class Config(BaseConfig):
"""Convenience constructor to set Ethereum defaults for the chainlib cli config object
diff --git a/chainlib/eth/connection.py b/chainlib/eth/connection.py
@@ -179,13 +179,13 @@ class EthUnixSignerConnection(EthUnixConnection):
"""Connects rpc signer methods to Unix socket connection interface
"""
- def sign_transaction_to_rlp(self, tx):
+ def sign_transaction_to_wire(self, tx):
"""Sign transaction using unix socket rpc.
:param tx: Transaction object
:type tx: dict
- :rtype: See chainlin.eth.connection.sign_transaction_to_rlp
- :returns: See chainlin.eth.connection.sign_transaction_to_rlp
+ :rtype: See chainlib.eth.connection.sign_transaction_to_rlp
+ :returns: Serialized signature
"""
return sign_transaction_to_rlp(self.chain_spec, self.do, tx)
@@ -203,13 +203,13 @@ class EthUnixSignerConnection(EthUnixConnection):
class EthHTTPSignerConnection(EthHTTPConnection):
- def sign_transaction_to_rlp(self, tx):
+ def sign_transaction_to_wire(self, tx):
"""Sign transaction using http json-rpc.
:param tx: Transaction object
:type tx: dict
:rtype: See chainlin.eth.connection.sign_transaction_to_rlp
- :returns: See chainlin.eth.connection.sign_transaction_to_rlp
+ :returns: Serialized signature
"""
return sign_transaction_to_rlp(self.chain_spec, self.do, tx)
diff --git a/chainlib/eth/gas.py b/chainlib/eth/gas.py
@@ -9,6 +9,7 @@ from hexathon import (
from crypto_dev_signer.eth.transaction import EIP155Transaction
# local imports
+from chainlib.fee import FeeOracle
from chainlib.hash import keccak256_hex_to_hex
from chainlib.jsonrpc import JSONRPCRequest
from chainlib.eth.tx import (
@@ -100,7 +101,7 @@ class Gas(TxFactory):
if data != None:
tx['data'] = data
txe = EIP155Transaction(tx, tx['nonce'], tx['chainId'])
- tx_raw = self.signer.sign_transaction_to_rlp(txe)
+ tx_raw = self.signer.sign_transaction_to_wire(txe)
tx_raw_hex = add_0x(tx_raw.hex())
tx_hash_hex = add_0x(keccak256_hex_to_hex(tx_raw_hex))
@@ -114,7 +115,7 @@ class Gas(TxFactory):
-class RPCGasOracle:
+class RPCGasOracle(FeeOracle):
"""JSON-RPC only gas parameter helper.
:param conn: RPC connection
@@ -128,13 +129,13 @@ class RPCGasOracle:
"""
def __init__(self, conn, code_callback=None, min_price=1, id_generator=None):
+ super(RPCGasOracle, self).__init__(code_callback=code_callback)
self.conn = conn
- self.code_callback = code_callback
self.min_price = min_price
self.id_generator = id_generator
- def get_gas(self, code=None, input_data=None):
+ def get_fee(self, code=None, input_data=None):
"""Retrieve gas parameters from node.
If code is given, the set code callback will be used to estimate gas usage.
@@ -162,6 +163,10 @@ class RPCGasOracle:
gas_price = self.min_price
return (gas_price, fee_units)
+
+ def get_gas(self, code=None, input_data=None):
+ return self.get_fee(code=code, input_data=input_data)
+
class RPCPureGasOracle(RPCGasOracle):
"""Convenience constructor for rpc gas oracle without minimum price.
@@ -213,14 +218,12 @@ class OverrideGasOracle(RPCGasOracle):
super(OverrideGasOracle, self).__init__(price_conn, code_callback, id_generator=id_generator)
- def get_gas(self, code=None):
- """See chainlib.eth.gas.RPCGasOracle.
- """
+ def get_fee(self, code=None, input_data=None):
r = None
fee_units = None
fee_price = None
- rpc_results = super(OverrideGasOracle, self).get_gas(code)
+ rpc_results = super(OverrideGasOracle, self).get_fee(code)
if self.limit != None:
fee_units = self.limit
@@ -245,4 +248,8 @@ class OverrideGasOracle(RPCGasOracle):
return (fee_price, fee_units)
+ def get_gas(self, code=None, input_data=None):
+ return self.get_fee(code=code, input_data=input_data)
+
+
DefaultGasOracle = RPCGasOracle
diff --git a/chainlib/eth/nonce.py b/chainlib/eth/nonce.py
@@ -5,6 +5,7 @@ from hexathon import (
)
# local imports
+from chainlib.nonce import NonceOracle as BaseNonceOracle
from chainlib.jsonrpc import JSONRPCRequest
@@ -22,7 +23,6 @@ def nonce(address, confirmed=False, id_generator=None):
o = j.template()
o['method'] = 'eth_getTransactionCount'
o['params'].append(address)
- o['params'].append('pending')
if confirmed:
o['params'].append('latest')
else:
@@ -34,7 +34,7 @@ def nonce_confirmed(address, id_generator=None):
return nonce(address, confirmed=True, id_generator=id_generator)
-class NonceOracle:
+class NonceOracle(BaseNonceOracle):
"""Base class for the nonce parameter helpers.
:param address: Address to retireve nonce for, in hex
@@ -43,9 +43,8 @@ class NonceOracle:
:type id_generator: chainlib.connection.JSONRPCIdGenerator
"""
def __init__(self, address, id_generator=None):
- self.address = address
self.id_generator = id_generator
- self.nonce = self.get_nonce()
+ super(NonceOracle, self).__init__(address)
def get_nonce(self):
diff --git a/chainlib/eth/tx.py b/chainlib/eth/tx.py
@@ -299,7 +299,7 @@ class TxFactory:
:param chain_spec: Chain spec to use for signer.
:type chain_spec: chainlib.chain.ChainSpec
:param signer: Signer middleware.
- :type param: Object implementing interface ofchainlib.eth.connection.sign_transaction_to_rlp.
+ :type param: Object implementing interface ofchainlib.eth.connection.sign_transaction_to_wire
:param gas_oracle: Backend to generate gas parameters
:type gas_oracle: Object implementing chainlib.eth.gas.GasOracle interface
:param nonce_oracle: Backend to generate gas parameters
@@ -328,7 +328,7 @@ class TxFactory:
if tx['to'] == None or tx['to'] == '':
tx['to'] = '0x'
txe = EIP155Transaction(tx, tx['nonce'], tx['chainId'])
- tx_raw = self.signer.sign_transaction_to_rlp(txe)
+ tx_raw = self.signer.sign_transaction_to_wire(txe)
tx_raw_hex = add_0x(tx_raw.hex())
tx_hash_hex = add_0x(keccak256_hex_to_hex(tx_raw_hex))
return (tx_hash_hex, tx_raw_hex)
diff --git a/chainlib/eth/unittest/base.py b/chainlib/eth/unittest/base.py
@@ -176,7 +176,7 @@ class TestRPCConnection(RPCConnection):
tx_dict = p[0]
tx = EIP155Transaction(tx_dict, tx_dict['nonce'], tx_dict['chainId'])
passphrase = p[1]
- r = self.signer.sign_transaction_to_rlp(tx, passphrase)
+ r = self.signer.sign_transaction_to_wire(tx, passphrase)
return r
@@ -192,9 +192,9 @@ class TestRPCConnection(RPCConnection):
return self.signer.sign_transaction(tx, passphrase)
- def sign_transaction_to_rlp(self, tx, passphrase=''):
+ def sign_transaction_to_wire(self, tx, passphrase=''):
self.__verify_signer(tx, passphrase)
- return self.signer.sign_transaction_to_rlp(tx, passphrase)
+ return self.signer.sign_transaction_to_wire(tx, passphrase)
def disconnect(self):
diff --git a/requirements.txt b/requirements.txt
@@ -1,7 +1,7 @@
-crypto-dev-signer>=0.4.14b7,<=0.4.14
+crypto-dev-signer>=0.4.15a1,<=0.4.15
pysha3==1.0.2
hexathon~=0.0.1a8
websocket-client==0.57.0
potaahto~=0.0.1a1
-chainlib==0.0.8a2
+chainlib==0.0.9a2
confini>=0.4.1a1,<0.5.0
diff --git a/setup.cfg b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = chainlib-eth
-version = 0.0.8a2
+version = 0.0.9a2
description = Ethereum implementation of the chainlib interface
author = Louis Holbrook
author_email = dev@holbrook.no