middleware.py (3996B)
1 # standard imports 2 import logging 3 import re 4 import socket 5 import uuid 6 import json 7 8 logg = logging.getLogger(__file__) 9 10 11 def jsonrpc_request(method, params): 12 uu = uuid.uuid4() 13 return { 14 "jsonrpc": "2.0", 15 "id": str(uu), 16 "method": method, 17 "params": params, 18 } 19 20 class PlatformMiddleware: 21 22 # id for the request is not available, meaning we cannot easily short-circuit 23 # hack workaround 24 id_seq = -1 25 re_personal = re.compile('^personal_.*') 26 ipcaddr = None 27 28 29 def __init__(self, make_request, w3): 30 self.w3 = w3 31 self.make_request = make_request 32 if self.ipcaddr == None: 33 raise AttributeError('ipcaddr not set') 34 35 36 # TODO: understand what format input params come in 37 # single entry input gives a tuple on params, wtf... 38 # dict input comes as [{}] and fails if not passed on as an array 39 @staticmethod 40 def _translate_params(params): 41 #if params.__class__.__name__ == 'tuple': 42 # r = [] 43 # for p in params: 44 # r.append(p) 45 # return r 46 47 if params.__class__.__name__ == 'list' and len(params) > 0: 48 return params[0] 49 50 return params 51 52 53 # TODO: DRY 54 def __call__(self, method, suspect_params): 55 56 self.id_seq += 1 57 logg.debug('in middleware method {} params {} ipcpath {}'.format(method, suspect_params, self.ipcaddr)) 58 59 if self.re_personal.match(method) != None: 60 params = PlatformMiddleware._translate_params(suspect_params) 61 # multiple providers is removed in web3.py 5.12.0 62 # https://github.com/ethereum/web3.py/issues/1701 63 # thus we need a workaround to use the same web3 instance 64 s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0) 65 ipc_provider_workaround = s.connect(self.ipcaddr) 66 67 logg.info('redirecting method {} params {} original params {}'.format(method, params, suspect_params)) 68 o = jsonrpc_request(method, params[0]) 69 j = json.dumps(o) 70 logg.debug('send {}'.format(j)) 71 s.send(j.encode('utf-8')) 72 r = s.recv(4096) 73 s.close() 74 logg.debug('got recv {}'.format(str(r))) 75 jr = json.loads(r) 76 jr['id'] = self.id_seq 77 #return str(json.dumps(jr)) 78 return jr 79 80 elif method == 'eth_signTransaction': 81 params = PlatformMiddleware._translate_params(suspect_params) 82 s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0) 83 ipc_provider_workaround = s.connect(self.ipcaddr) 84 logg.info('redirecting method {} params {} original params {}'.format(method, params, suspect_params)) 85 o = jsonrpc_request(method, params[0]) 86 j = json.dumps(o) 87 logg.debug('send {}'.format(j)) 88 s.send(j.encode('utf-8')) 89 r = s.recv(4096) 90 s.close() 91 logg.debug('got recv {}'.format(str(r))) 92 jr = json.loads(r) 93 jr['id'] = self.id_seq 94 #return str(json.dumps(jr)) 95 return jr 96 97 elif method == 'eth_sign': 98 params = PlatformMiddleware._translate_params(suspect_params) 99 s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0) 100 ipc_provider_workaround = s.connect(self.ipcaddr) 101 logg.info('redirecting method {} params {} original params {}'.format(method, params, suspect_params)) 102 o = jsonrpc_request(method, params) 103 j = json.dumps(o) 104 logg.debug('send {}'.format(j)) 105 s.send(j.encode('utf-8')) 106 r = s.recv(4096) 107 s.close() 108 logg.debug('got recv {}'.format(str(r))) 109 jr = json.loads(r) 110 jr['id'] = self.id_seq 111 return jr 112 113 114 115 r = self.make_request(method, suspect_params) 116 return r