3939except ImportError :
4040 import httplib
4141import base64
42- import json
4342import decimal
43+ import json
44+ import logging
4445try :
4546 import urllib .parse as urlparse
4647except ImportError :
5051
5152HTTP_TIMEOUT = 30
5253
54+ log = logging .getLogger ("BitcoinRPC" )
5355
5456class JSONRPCException (Exception ):
5557 def __init__ (self , rpc_error ):
@@ -84,9 +86,9 @@ def __init__(self, service_url, service_name=None, timeout=HTTP_TIMEOUT, connect
8486 pass
8587 authpair = user + b':' + passwd
8688 self .__auth_header = b'Basic ' + base64 .b64encode (authpair )
87-
88- if connection :
89- # Callables re-use the connection of the original proxy
89+
90+ if connection :
91+ # Callables re-use the connection of the original proxy
9092 self .__conn = connection
9193 elif self .__url .scheme == 'https' :
9294 self .__conn = httplib .HTTPSConnection (self .__url .hostname , port ,
@@ -107,6 +109,8 @@ def __getattr__(self, name):
107109 def __call__ (self , * args ):
108110 AuthServiceProxy .__id_count += 1
109111
112+ log .debug ("-%s-> %s %s" % (AuthServiceProxy .__id_count , self .__service_name ,
113+ json .dumps (args , default = EncodeDecimal )))
110114 postdata = json .dumps ({'version' : '1.1' ,
111115 'method' : self .__service_name ,
112116 'params' : args ,
@@ -126,21 +130,46 @@ def __call__(self, *args):
126130 else :
127131 return response ['result' ]
128132
129- def _batch (self , rpc_call_list ):
130- postdata = json .dumps (list (rpc_call_list ), default = EncodeDecimal )
133+ def batch_ (self , rpc_calls ):
134+ """Batch RPC call.
135+ Pass array of arrays: [ [ "method", params... ], ... ]
136+ Returns array of results.
137+ """
138+ batch_data = []
139+ for rpc_call in rpc_calls :
140+ AuthServiceProxy .__id_count += 1
141+ m = rpc_call .pop (0 )
142+ batch_data .append ({"jsonrpc" :"2.0" , "method" :m , "params" :rpc_call , "id" :AuthServiceProxy .__id_count })
143+
144+ postdata = json .dumps (batch_data , default = EncodeDecimal )
145+ log .debug ("--> " + postdata )
131146 self .__conn .request ('POST' , self .__url .path , postdata ,
132147 {'Host' : self .__url .hostname ,
133148 'User-Agent' : USER_AGENT ,
134149 'Authorization' : self .__auth_header ,
135150 'Content-type' : 'application/json' })
136-
137- return self ._get_response ()
151+ results = []
152+ responses = self ._get_response ()
153+ for response in responses :
154+ if response ['error' ] is not None :
155+ raise JSONRPCException (response ['error' ])
156+ elif 'result' not in response :
157+ raise JSONRPCException ({
158+ 'code' : - 343 , 'message' : 'missing JSON-RPC result' })
159+ else :
160+ results .append (response ['result' ])
161+ return results
138162
139163 def _get_response (self ):
140164 http_response = self .__conn .getresponse ()
141165 if http_response is None :
142166 raise JSONRPCException ({
143167 'code' : - 342 , 'message' : 'missing HTTP response from server' })
144168
145- return json .loads (http_response .read ().decode ('utf8' ),
146- parse_float = decimal .Decimal )
169+ responsedata = http_response .read ().decode ('utf8' )
170+ response = json .loads (responsedata , parse_float = decimal .Decimal )
171+ if "error" in response and response ["error" ] is None :
172+ log .debug ("<-%s- %s" % (response ["id" ], json .dumps (response ["result" ], default = EncodeDecimal )))
173+ else :
174+ log .debug ("<-- " + responsedata )
175+ return response
0 commit comments