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 (
pubkeyToAddress,
)
from .rpc import (
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
# file LICENSE.txt or http://www.opensource.org/licenses/mit-license.php.
import os
import decimal
import subprocess
import json
import traceback
import hashlib
import urllib
from xmlrpc.client import (
Transport,
Fault,
)
from .segwit_addr import bech32_decode, convertbits, bech32_encode
COIN = 100000000
@ -196,102 +188,3 @@ def DeserialiseNum(b, o=0):
if b[o + nb - 1] & 0x80:
return -(v & ~(0x80 << (8 * (nb - 1))))
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 zipfile
import stat
import time
from urllib.request import urlretrieve
import urllib.parse
import logging
@ -29,7 +28,10 @@ import platform
import gnupg
import basicswap.config as cfg
from basicswap.util import callrpc_cli
from basicswap.rpc import (
callrpc_cli,
waitForRPC,
)
from bin.basicswap_run import startDaemon
if platform.system() == 'Darwin':
@ -53,7 +55,7 @@ if not len(logger.handlers):
def make_reporthook():
read = 0 # number of bytes read so far
read = 0 # Number of bytes read so far
last_percent_str = ''
def reporthook(blocknum, blocksize, totalsize):
@ -280,17 +282,6 @@ def make_rpc_func(bin_dir, data_dir, chain):
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):
sys.stderr.write('Error: {}, exiting.\n'.format(error_msg))
sys.exit(1)

@ -34,7 +34,10 @@ from basicswap.basicswap import (
from basicswap.util import (
COIN,
toWIF,
)
from basicswap.rpc import (
callrpc_cli,
waitForRPC,
)
from basicswap.key import (
ECKey,
@ -206,17 +209,6 @@ def run_loop(self):
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):
@classmethod

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

@ -37,9 +37,12 @@ from basicswap.basicswap import (
from basicswap.util import (
COIN,
toWIF,
callrpc_cli,
dumpje,
)
from basicswap.rpc import (
callrpc_cli,
waitForRPC,
)
from basicswap.key import (
ECKey,
)
@ -210,17 +213,6 @@ def run_loop(self):
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):
if 'bip9_softforks' in ro:
assert(ro['bip9_softforks']['csv']['status'] == 'active')

Loading…
Cancel
Save