commit b9581e83e7af82be129870e01631685bea1987f3
parent 9356ef53b22cacc6bac26675f270c8202a901ad4
Author: nolash <dev@holbrook.no>
Date: Sat, 24 Apr 2021 07:36:45 +0200
Use tag instead of chain spec for rpc connection constructor registration
Diffstat:
3 files changed, 71 insertions(+), 40 deletions(-)
diff --git a/chainlib/connection.py b/chainlib/connection.py
@@ -22,7 +22,7 @@ from .jsonrpc import (
)
from .http import PreemptiveBasicAuthHandler
-logg = logging.getLogger(__name__)
+logg = logging.getLogger().getChild(__name__)
error_parser = DefaultErrorParser()
@@ -65,19 +65,14 @@ def str_to_connspec(s):
raise ValueError('unknown connection type {}'.format(s))
-def from_conntype(t):
- if t in [ConnType.HTTP, ConnType.HTTP_SSL]:
- return JSONRPCHTTPConnection
- elif t in [ConnType.UNIX]:
- return JSONRPCUnixConnection
- raise NotImplementedError(t)
-
-
-
class RPCConnection():
__locations = {}
- __constructors = {}
+ __constructors = {
+ 'default': {
+ },
+ }
+ __constructors_for_chains = {}
def __init__(self, url=None, chain_spec=None):
self.chain_spec = chain_spec
@@ -104,34 +99,40 @@ class RPCConnection():
logg.debug('parsed url {} to location {}'.format(url, self.location))
+ @staticmethod
+ def from_conntype(t, tag='default'):
+ return RPCConnection.__constructors[tag][t]
+
+
+ @staticmethod
+ def register_constructor(t, c, tag='default'):
+ if RPCConnection.__constructors.get(tag) == None:
+ RPCConnection.__constructors[tag] = {}
+ RPCConnection.__constructors[tag][t] = c
+ logg.info('registered RPC connection constructor {} for type {} tag {}'.format(c, t, tag))
+
+
# TODO: constructor needs to be constructor-factory, that itself can select on url type
@staticmethod
- def register_location(location, chain_spec, tag='default', constructor=None, exist_ok=False):
+ def register_location(location, chain_spec, tag='default', exist_ok=False):
chain_str = str(chain_spec)
if RPCConnection.__locations.get(chain_str) == None:
RPCConnection.__locations[chain_str] = {}
- RPCConnection.__constructors[chain_str] = {}
elif not exist_ok:
v = RPCConnection.__locations[chain_str].get(tag)
if v != None:
raise ValueError('duplicate registration of tag {}:{}, requested {} already had {}'.format(chain_str, tag, location, v))
conntype = str_to_connspec(location)
RPCConnection.__locations[chain_str][tag] = (conntype, location)
- if constructor != None:
- RPCConnection.__constructors[chain_str][tag] = constructor
- logg.info('registered rpc connection {} ({}:{}) as {} with custom constructor {}'.format(location, chain_str, tag, conntype, constructor))
- else:
- logg.info('registered rpc connection {} ({}:{}) as {}'.format(location, chain_str, tag, conntype))
+ logg.info('registered rpc connection {} ({}/{}) as {}'.format(location, chain_str, tag, conntype))
@staticmethod
def connect(chain_spec, tag='default'):
chain_str = str(chain_spec)
c = RPCConnection.__locations[chain_str][tag]
- constructor = RPCConnection.__constructors[chain_str].get(tag)
- if constructor == None:
- constructor = from_conntype(c[0])
- logg.debug('cons {} {}'.format(constructor, c))
+ constructor = RPCConnection.from_conntype(c[0], tag=tag)
+ logg.debug('rpc connect {} {} {}'.format(constructor, c, tag))
return constructor(url=c[1], chain_spec=chain_spec)
@@ -215,3 +216,7 @@ class JSONRPCUnixConnection(UnixConnection):
return jsonrpc_result(result, error_parser)
+
+RPCConnection.register_constructor(ConnType.HTTP, JSONRPCHTTPConnection, tag='default')
+RPCConnection.register_constructor(ConnType.HTTP_SSL, JSONRPCHTTPConnection, tag='default')
+RPCConnection.register_constructor(ConnType.UNIX, JSONRPCUnixConnection, tag='default')
diff --git a/chainlib/eth/connection.py b/chainlib/eth/connection.py
@@ -25,6 +25,8 @@ from .sign import (
sign_transaction,
)
from chainlib.connection import (
+ ConnType,
+ RPCConnection,
JSONRPCHTTPConnection,
JSONRPCUnixConnection,
error_parser,
@@ -82,23 +84,47 @@ class EthUnixConnection(JSONRPCUnixConnection):
raise NotImplementedError('Not yet implemented for unix socket')
+def sign_transaction_to_rlp(chain_spec, doer, tx):
+ txs = tx.serialize()
+ logg.debug('serializing {}'.format(txs))
+ # TODO: because some rpc servers may fail when chainId is included, we are forced to spend cpu here on this
+ chain_id = txs.get('chainId') or 1
+ if chain_spec != None:
+ chain_id = chain_spec.chain_id()
+ txs['chainId'] = add_0x(chain_id.to_bytes(2, 'big').hex())
+ txs['from'] = add_0x(tx.sender)
+ o = sign_transaction(txs)
+ r = doer(o)
+ logg.debug('sig got {}'.format(r))
+ return bytes.fromhex(strip_0x(r))
+
+
+def sign_message(doer, msg):
+ o = sign_message(msg)
+ return doer(o)
+
+
class EthUnixSignerConnection(EthUnixConnection):
def sign_transaction_to_rlp(self, tx):
- txs = tx.serialize()
- logg.debug('serializing {}'.format(txs))
- # TODO: because some rpc servers may fail when chainId is included, we are forced to spend cpu here on this
- chain_id = txs.get('chainId') or 1
- if self.chain_spec != None:
- chain_id = self.chain_spec.chain_id()
- txs['chainId'] = add_0x(chain_id.to_bytes(2, 'big').hex())
- txs['from'] = add_0x(tx.sender)
- o = sign_transaction(txs)
- r = self.do(o)
- logg.debug('sig got {}'.format(r))
- return bytes.fromhex(strip_0x(r))
-
-
- def sign_message(self, msg):
- o = sign_message(msg)
- return self.do(o)
+ return sign_transaction_to_rlp(self.chain_spec, self.do, tx)
+
+
+ def sign_message(self, tx):
+ return sign_message(self.do, tx)
+
+
+class EthHTTPSignerConnection(EthHTTPConnection):
+
+ def sign_transaction_to_rlp(self, tx):
+ return sign_transaction_to_rlp(self.chain_spec, self.do, tx)
+
+
+ def sign_message(self, tx):
+ return sign_message(self.do, tx)
+
+
+
+RPCConnection.register_constructor(ConnType.HTTP, EthHTTPConnection, tag='eth_default')
+RPCConnection.register_constructor(ConnType.HTTP_SSL, EthHTTPConnection, tag='eth_default')
+RPCConnection.register_constructor(ConnType.UNIX, EthUnixConnection, tag='eth_default')
diff --git a/setup.cfg b/setup.cfg
@@ -1,6 +1,6 @@
[metadata]
name = chainlib
-version = 0.0.2a16
+version = 0.0.2a17
description = Generic blockchain access library and tooling
author = Louis Holbrook
author_email = dev@holbrook.no