Split rpc functions into new file.

2024-05-20_merge
tecnovert 5 years ago
parent 0a2c6dafb7
commit adbb0268ff
No known key found for this signature in database
GPG Key ID: 8ED6D8750C4E3F93
  1. 2
      basicswap/base.py
  2. 127
      basicswap/rpc.py
  3. 107
      basicswap/util.py
  4. 19
      bin/basicswap_prepare.py
  5. 14
      tests/basicswap/test_nmc.py
  6. 2
      tests/basicswap/test_reload.py
  7. 16
      tests/basicswap/test_run.py

@ -18,6 +18,8 @@ from .chainparams import (
) )
from .util import ( from .util import (
pubkeyToAddress, pubkeyToAddress,
)
from .rpc import (
callrpc, callrpc,
) )

@ -0,0 +1,127 @@
# -*- coding: utf-8 -*-
# Copyright (c) 2020 tecnovert
# Distributed under the MIT software license, see the accompanying
# file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php.
import os
import time
import json
import urllib
import logging
import traceback
import subprocess
from xmlrpc.client import (
Transport,
Fault,
)
from .util import jsonDecimal
def waitForRPC(rpc_func, wallet=None):
for i in range(5):
try:
rpc_func('getwalletinfo')
return
except Exception as ex:
logging.warning('Can\'t connect to daemon RPC: %s. Trying again in %d second/s.', str(ex), (1 + i))
time.sleep(1 + i)
raise ValueError('waitForRPC failed')
class Jsonrpc():
# __getattr__ complicates extending ServerProxy
def __init__(self, uri, transport=None, encoding=None, verbose=False,
allow_none=False, use_datetime=False, use_builtin_types=False,
*, context=None):
# establish a "logical" server connection
# get the url
type, uri = urllib.parse.splittype(uri)
if type not in ("http", "https"):
raise OSError("unsupported XML-RPC protocol")
self.__host, self.__handler = urllib.parse.splithost(uri)
if not self.__handler:
self.__handler = "/RPC2"
if transport is None:
handler = Transport
extra_kwargs = {}
transport = handler(use_datetime=use_datetime,
use_builtin_types=use_builtin_types,
**extra_kwargs)
self.__transport = transport
self.__encoding = encoding or 'utf-8'
self.__verbose = verbose
self.__allow_none = allow_none
def close(self):
if self.__transport is not None:
self.__transport.close()
def json_request(self, method, params):
try:
connection = self.__transport.make_connection(self.__host)
headers = self.__transport._extra_headers[:]
request_body = {
'method': method,
'params': params,
'id': 2
}
connection.putrequest("POST", self.__handler)
headers.append(("Content-Type", "application/json"))
headers.append(("User-Agent", 'jsonrpc'))
self.__transport.send_headers(connection, headers)
self.__transport.send_content(connection, json.dumps(request_body, default=jsonDecimal).encode('utf-8'))
resp = connection.getresponse()
return resp.read()
except Fault:
raise
except Exception:
# All unexpected errors leave connection in
# a strange state, so we clear it.
self.__transport.close()
raise
def callrpc(rpc_port, auth, method, params=[], wallet=None):
try:
url = 'http://%s@127.0.0.1:%d/' % (auth, rpc_port)
if wallet:
url += 'wallet/' + wallet
x = Jsonrpc(url)
v = x.json_request(method, params)
x.close()
r = json.loads(v.decode('utf-8'))
except Exception as ex:
traceback.print_exc()
raise ValueError('RPC Server Error')
if 'error' in r and r['error'] is not None:
raise ValueError('RPC error ' + str(r['error']))
return r['result']
def callrpc_cli(bindir, datadir, chain, cmd, cli_bin='particl-cli'):
cli_bin = os.path.join(bindir, cli_bin)
args = cli_bin + ('' if chain == 'mainnet' else ' -' + chain) + ' -datadir=' + datadir + ' ' + cmd
p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
out = p.communicate()
if len(out[1]) > 0:
raise ValueError('RPC error ' + str(out[1]))
r = out[0].decode('utf-8').strip()
try:
r = json.loads(r)
except Exception:
pass
return r

@ -4,17 +4,9 @@
# Distributed under the MIT software license, see the accompanying # Distributed under the MIT software license, see the accompanying
# file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php. # file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php.
import os
import decimal import decimal
import subprocess
import json import json
import traceback
import hashlib import hashlib
import urllib
from xmlrpc.client import (
Transport,
Fault,
)
from .segwit_addr import bech32_decode, convertbits, bech32_encode from .segwit_addr import bech32_decode, convertbits, bech32_encode
COIN = 100000000 COIN = 100000000
@ -196,102 +188,3 @@ def DeserialiseNum(b, o=0):
if b[o + nb - 1] & 0x80: if b[o + nb - 1] & 0x80:
return -(v & ~(0x80 << (8 * (nb - 1)))) return -(v & ~(0x80 << (8 * (nb - 1))))
return v return v
class Jsonrpc():
# __getattr__ complicates extending ServerProxy
def __init__(self, uri, transport=None, encoding=None, verbose=False,
allow_none=False, use_datetime=False, use_builtin_types=False,
*, context=None):
# establish a "logical" server connection
# get the url
type, uri = urllib.parse.splittype(uri)
if type not in ("http", "https"):
raise OSError("unsupported XML-RPC protocol")
self.__host, self.__handler = urllib.parse.splithost(uri)
if not self.__handler:
self.__handler = "/RPC2"
if transport is None:
handler = Transport
extra_kwargs = {}
transport = handler(use_datetime=use_datetime,
use_builtin_types=use_builtin_types,
**extra_kwargs)
self.__transport = transport
self.__encoding = encoding or 'utf-8'
self.__verbose = verbose
self.__allow_none = allow_none
def close(self):
if self.__transport is not None:
self.__transport.close()
def json_request(self, method, params):
try:
connection = self.__transport.make_connection(self.__host)
headers = self.__transport._extra_headers[:]
request_body = {
'method': method,
'params': params,
'id': 2
}
connection.putrequest("POST", self.__handler)
headers.append(("Content-Type", "application/json"))
headers.append(("User-Agent", 'jsonrpc'))
self.__transport.send_headers(connection, headers)
self.__transport.send_content(connection, json.dumps(request_body, default=jsonDecimal).encode('utf-8'))
resp = connection.getresponse()
return resp.read()
except Fault:
raise
except Exception:
# All unexpected errors leave connection in
# a strange state, so we clear it.
self.__transport.close()
raise
def callrpc(rpc_port, auth, method, params=[], wallet=None):
try:
url = 'http://%s@127.0.0.1:%d/' % (auth, rpc_port)
if wallet:
url += 'wallet/' + wallet
x = Jsonrpc(url)
v = x.json_request(method, params)
x.close()
r = json.loads(v.decode('utf-8'))
except Exception as ex:
traceback.print_exc()
raise ValueError('RPC Server Error')
if 'error' in r and r['error'] is not None:
raise ValueError('RPC error ' + str(r['error']))
return r['result']
def callrpc_cli(bindir, datadir, chain, cmd, cli_bin='particl-cli'):
cli_bin = os.path.join(bindir, cli_bin)
args = cli_bin + ('' if chain == 'mainnet' else ' -' + chain) + ' -datadir=' + datadir + ' ' + cmd
p = subprocess.Popen(args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
out = p.communicate()
if len(out[1]) > 0:
raise ValueError('RPC error ' + str(out[1]))
r = out[0].decode('utf-8').strip()
try:
r = json.loads(r)
except Exception:
pass
return r

@ -20,7 +20,6 @@ import mmap
import tarfile import tarfile
import zipfile import zipfile
import stat import stat
import time
from urllib.request import urlretrieve from urllib.request import urlretrieve
import urllib.parse import urllib.parse
import logging import logging
@ -29,7 +28,10 @@ import platform
import gnupg import gnupg
import basicswap.config as cfg import basicswap.config as cfg
from basicswap.util import callrpc_cli from basicswap.rpc import (
callrpc_cli,
waitForRPC,
)
from bin.basicswap_run import startDaemon from bin.basicswap_run import startDaemon
if platform.system() == 'Darwin': if platform.system() == 'Darwin':
@ -53,7 +55,7 @@ if not len(logger.handlers):
def make_reporthook(): def make_reporthook():
read = 0 # number of bytes read so far read = 0 # Number of bytes read so far
last_percent_str = '' last_percent_str = ''
def reporthook(blocknum, blocksize, totalsize): def reporthook(blocknum, blocksize, totalsize):
@ -280,17 +282,6 @@ def make_rpc_func(bin_dir, data_dir, chain):
return rpc_func return rpc_func
def waitForRPC(rpc_func, wallet=None):
for i in range(10):
try:
rpc_func('getwalletinfo')
return
except Exception as ex:
logging.warning('Can\'t connect to daemon RPC: %s. Trying again in %d second/s.', str(ex), (1 + i))
time.sleep(1 + i)
raise ValueError('waitForRPC failed')
def exitWithError(error_msg): def exitWithError(error_msg):
sys.stderr.write('Error: {}, exiting.\n'.format(error_msg)) sys.stderr.write('Error: {}, exiting.\n'.format(error_msg))
sys.exit(1) sys.exit(1)

@ -34,7 +34,10 @@ from basicswap.basicswap import (
from basicswap.util import ( from basicswap.util import (
COIN, COIN,
toWIF, toWIF,
)
from basicswap.rpc import (
callrpc_cli, callrpc_cli,
waitForRPC,
) )
from basicswap.key import ( from basicswap.key import (
ECKey, ECKey,
@ -206,17 +209,6 @@ def run_loop(self):
btcRpc('generatetoaddress 1 {}'.format(self.btc_addr)) btcRpc('generatetoaddress 1 {}'.format(self.btc_addr))
def waitForRPC(rpc_func, wallet=None):
for i in range(5):
try:
rpc_func('getwalletinfo')
return
except Exception as ex:
logging.warning('Can\'t connect to daemon RPC: %s. Trying again in %d second/s.', str(ex), (1 + i))
time.sleep(1 + i)
raise ValueError('waitForRPC failed')
class Test(unittest.TestCase): class Test(unittest.TestCase):
@classmethod @classmethod

@ -31,7 +31,7 @@ from unittest.mock import patch
from urllib.request import urlopen from urllib.request import urlopen
from urllib import parse from urllib import parse
from basicswap.util import ( from basicswap.rpc import (
callrpc_cli, callrpc_cli,
) )

@ -37,9 +37,12 @@ from basicswap.basicswap import (
from basicswap.util import ( from basicswap.util import (
COIN, COIN,
toWIF, toWIF,
callrpc_cli,
dumpje, dumpje,
) )
from basicswap.rpc import (
callrpc_cli,
waitForRPC,
)
from basicswap.key import ( from basicswap.key import (
ECKey, ECKey,
) )
@ -210,17 +213,6 @@ def run_loop(self):
btcRpc('generatetoaddress 1 {}'.format(self.btc_addr)) btcRpc('generatetoaddress 1 {}'.format(self.btc_addr))
def waitForRPC(rpc_func, wallet=None):
for i in range(5):
try:
rpc_func('getwalletinfo')
return
except Exception as ex:
logging.warning('Can\'t connect to daemon RPC: %s. Trying again in %d second/s.', str(ex), (1 + i))
time.sleep(1 + i)
raise ValueError('waitForRPC failed')
def checkForks(ro): def checkForks(ro):
if 'bip9_softforks' in ro: if 'bip9_softforks' in ro:
assert(ro['bip9_softforks']['csv']['status'] == 'active') assert(ro['bip9_softforks']['csv']['status'] == 'active')

Loading…
Cancel
Save