rpc: add CallSigs classes, indirect RPC call (icall) method

This commit is contained in:
The MMGen Project 2021-03-02 17:34:50 +00:00
commit 4ed86de639
Signed by: mmgen
GPG key ID: 3F8B1861E32B7DA2
2 changed files with 63 additions and 0 deletions

View file

@ -297,6 +297,7 @@ class CoinDaemon(Daemon):
network_ids = ('btc','btc_tn','btc_rt','bch','bch_tn','bch_rt','ltc','ltc_tn','ltc_rt','xmr','eth','etc')
cd = namedtuple('daemon_data', [
'id',
'coin',
'cls_pfx',
'coind_name',
@ -311,6 +312,7 @@ class CoinDaemon(Daemon):
daemon_ids = {
'btc': cd(
'bitcoin_core',
'Bitcoin',
'Bitcoin',
'Bitcoin Core', 210000, '0.21.0',
@ -320,6 +322,7 @@ class CoinDaemon(Daemon):
'testnet3',
8332, 18332, 18444),
'bch': cd(
'bitcoin_cash_node',
'BitcoinCashNode',
'Bitcoin',
'Bitcoin Cash Node', 22020000, '22.2.0',
@ -329,6 +332,7 @@ class CoinDaemon(Daemon):
'testnet3',
8442, 18442, 18553), # for BCH we use non-standard RPC ports
'ltc': cd(
'litecoin_core',
'Litecoin',
'Bitcoin',
'Litecoin Core', 180100, '0.18.1',
@ -338,6 +342,7 @@ class CoinDaemon(Daemon):
'testnet4',
9332, 19332, 19444),
'xmr': cd(
'monerod',
'Monero',
'Monero',
'Monero', 'N/A', 'N/A',
@ -347,6 +352,7 @@ class CoinDaemon(Daemon):
None,
18081, None, None),
'eth': cd(
'openethereum',
'Ethereum',
'Ethereum',
'OpenEthereum', 3000001, '3.0.1',
@ -356,6 +362,7 @@ class CoinDaemon(Daemon):
None,
8545, 8545, 8545),
'etc': cd(
'openethereum',
'Ethereum Classic',
'Ethereum',
'OpenEthereum', 3000001, '3.0.1',

View file

@ -193,6 +193,47 @@ class RPCBackends:
from collections import namedtuple
auth_data = namedtuple('rpc_auth_data',['user','passwd'])
class CallSigs:
class Bitcoin:
class bitcoin_core:
@classmethod
def createwallet(cls,wallet_name,no_keys=True,passphrase='',load_on_startup=True):
"""
Quirk: when --datadir is specified (even if standard), wallet is created directly in
datadir, otherwise in datadir/wallets
"""
return (
'createwallet',
wallet_name, # 1. wallet_name
no_keys, # 2. disable_private_keys
no_keys, # 3. blank (no keys or seed)
passphrase, # 4. passphrase (empty string for non-encrypted)
False, # 5. avoid_reuse (track address reuse)
False, # 6. descriptors (native descriptor wallet)
load_on_startup # 7. load_on_startup
)
class litecoin_core(bitcoin_core):
@classmethod
def createwallet(cls,wallet_name,no_keys=True,passphrase='',load_on_startup=True):
return (
'createwallet',
wallet_name, # 1. wallet_name
no_keys, # 2. disable_private_keys
no_keys, # 3. blank (no keys or seed)
)
class bitcoin_cash_node(litecoin_core): pass
class Ethereum:
class openethereum: pass
class RPCClient(MMGenObject):
auth_type = None
@ -307,6 +348,19 @@ class RPCClient(MMGenObject):
return ret
# Icall family of methods - indirect RPC call using CallSigs mechanism:
# - 'timeout' and 'wallet' kwargs are passed to corresponding Call method
# - remaining kwargs are passed to CallSigs method
# - CallSigs method returns method and positional params for Call method
def icall(self,method,**kwargs):
timeout = kwargs.pop('timeout',None)
wallet = kwargs.pop('wallet',None)
return self.call(
*getattr(self.call_sigs,method)(**kwargs),
timeout = timeout,
wallet = wallet )
async def process_http_resp(self,coro,batch=False):
text,status = await coro
if status == 200:
@ -341,6 +395,7 @@ class BitcoinRPCClient(RPCClient,metaclass=aInitMeta):
self.proto = proto
self.daemon = daemon
self.call_sigs = getattr(getattr(CallSigs,proto.base_proto),daemon.id)
super().__init__(
host = 'localhost' if g.test_suite else (g.rpc_host or 'localhost'),
@ -530,6 +585,7 @@ class EthereumRPCClient(RPCClient,metaclass=aInitMeta):
async def __ainit__(self,proto,daemon,backend,caller):
self.proto = proto
self.daemon = daemon
self.call_sigs = getattr(getattr(CallSigs,proto.base_proto),daemon.id)
super().__init__(
host = 'localhost' if g.test_suite else (g.rpc_host or 'localhost'),