mirror of
https://github.com/basicswap/basicswap.git
synced 2025-01-06 10:49:27 +00:00
Split rpc functions into new file.
This commit is contained in:
parent
0a2c6dafb7
commit
adbb0268ff
7 changed files with 142 additions and 145 deletions
|
@ -18,6 +18,8 @@ from .chainparams import (
|
||||||
)
|
)
|
||||||
from .util import (
|
from .util import (
|
||||||
pubkeyToAddress,
|
pubkeyToAddress,
|
||||||
|
)
|
||||||
|
from .rpc import (
|
||||||
callrpc,
|
callrpc,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
127
basicswap/rpc.py
Normal file
127
basicswap/rpc.py
Normal file
|
@ -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…
Reference in a new issue