Add middleware example in scripts
This commit is contained in:
parent
7c3208de4c
commit
d3627d81fd
@ -53,9 +53,10 @@ methods = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def jsonrpc_error(id, err):
|
def jsonrpc_error(rpc_id, err):
|
||||||
return {
|
return {
|
||||||
'json-rpc': '2.0',
|
'json-rpc': '2.0',
|
||||||
|
'id': rpc_id,
|
||||||
'error': {
|
'error': {
|
||||||
'code': err.CODE,
|
'code': err.CODE,
|
||||||
'message': err.MESSAGE,
|
'message': err.MESSAGE,
|
||||||
@ -71,6 +72,12 @@ def jsonrpc_ok(rpc_id, response):
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def is_valid_json(j):
|
||||||
|
if j.get('id') == 'None':
|
||||||
|
raise ValueError('id missing')
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def process_input(j):
|
def process_input(j):
|
||||||
|
|
||||||
rpc_id = j['id']
|
rpc_id = j['id']
|
||||||
@ -81,21 +88,34 @@ def process_input(j):
|
|||||||
|
|
||||||
|
|
||||||
def start_server():
|
def start_server():
|
||||||
|
try:
|
||||||
os.unlink('/tmp/foo.ipc')
|
os.unlink('/tmp/foo.ipc')
|
||||||
|
except FileNotFoundError:
|
||||||
|
pass
|
||||||
s = socket.socket(family = socket.AF_UNIX, type = socket.SOCK_STREAM)
|
s = socket.socket(family = socket.AF_UNIX, type = socket.SOCK_STREAM)
|
||||||
s.bind('/tmp/foo.ipc')
|
s.bind('/tmp/foo.ipc')
|
||||||
s.listen(10)
|
s.listen(10)
|
||||||
while True:
|
while True:
|
||||||
(csock, caddr) = s.accept()
|
(csock, caddr) = s.accept()
|
||||||
d = csock.recv(4096)
|
d = csock.recv(4096)
|
||||||
|
j = None
|
||||||
try:
|
try:
|
||||||
j = json.loads(b)
|
j = json.loads(d)
|
||||||
process_input(j)
|
is_valid_json(j)
|
||||||
logg.debug('{}'.format(d.decode('utf-8')))
|
logg.debug('{}'.format(d.decode('utf-8')))
|
||||||
csock.send(json.dumps(jsonrpc_ok(0, [])).encode('utf-8'))
|
|
||||||
except:
|
except:
|
||||||
csock.send(json.dumps(jsonrpc_error(None, JSONRPCParseError)).encode('utf-8'))
|
csock.send(json.dumps(jsonrpc_error(None, JSONRPCParseError)).encode('utf-8'))
|
||||||
csock.close()
|
csock.close()
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
(rpc_id, r) = process_input(j)
|
||||||
|
csock.send(json.dumps(jsonrpc_ok(rpc_id, r)).encode('utf-8'))
|
||||||
|
except:
|
||||||
|
# TODO: handle cases to give better error context to caller
|
||||||
|
csock.send(json.dumps(jsonrpc_error(j['id'], JSONRPCServerError)).encode('utf-8'))
|
||||||
|
|
||||||
|
csock.close()
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
os.unlink('/tmp/foo.ipc')
|
os.unlink('/tmp/foo.ipc')
|
||||||
|
81
scripts/web3_middleware.py
Normal file
81
scripts/web3_middleware.py
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
import logging
|
||||||
|
import re
|
||||||
|
import socket
|
||||||
|
import uuid
|
||||||
|
import json
|
||||||
|
|
||||||
|
from web3 import Web3, WebsocketProvider, IPCProvider
|
||||||
|
|
||||||
|
|
||||||
|
logging.basicConfig(level=logging.DEBUG)
|
||||||
|
logg = logging.getLogger('foo')
|
||||||
|
|
||||||
|
|
||||||
|
def jsonrpc_request(method, params):
|
||||||
|
uu = uuid.uuid4()
|
||||||
|
return {
|
||||||
|
"jsonrpc": "2.0",
|
||||||
|
"id": str(uu),
|
||||||
|
"method": method,
|
||||||
|
"params": params,
|
||||||
|
}
|
||||||
|
|
||||||
|
class PlatformMiddleware:
|
||||||
|
|
||||||
|
# id for the request is not available, meaning we cannot easily short-circuit
|
||||||
|
# hack workaround
|
||||||
|
id_seq = -1
|
||||||
|
re_personal = re.compile('^personal_.*')
|
||||||
|
ipcaddr = '/tmp/foo.ipc'
|
||||||
|
|
||||||
|
|
||||||
|
def __init__(self, make_request, w3):
|
||||||
|
self.w3 = w3
|
||||||
|
self.make_request = make_request
|
||||||
|
|
||||||
|
|
||||||
|
# single entry input gives a tuple on params, wtf...
|
||||||
|
@staticmethod
|
||||||
|
def _translate_params(params):
|
||||||
|
if params.__class__.__name__ == 'tuple':
|
||||||
|
r = []
|
||||||
|
for p in params:
|
||||||
|
r.append(p)
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
def __call__(self, method, suspect_params):
|
||||||
|
self.id_seq += 1
|
||||||
|
params = PlatformMiddleware._translate_params(suspect_params)
|
||||||
|
|
||||||
|
logg.debug('method {} params {} original params {}'.format(method, params, suspect_params))
|
||||||
|
if self.re_personal.match(method) != None:
|
||||||
|
# multiple providers is broken in web3.py 5.12.0
|
||||||
|
# https://github.com/ethereum/web3.py/issues/1701
|
||||||
|
# hack workaround
|
||||||
|
s = socket.socket(family=socket.AF_UNIX, type=socket.SOCK_STREAM, proto=0)
|
||||||
|
ipc_provider_workaround = s.connect(self.ipcaddr)
|
||||||
|
|
||||||
|
logg.debug('redirecting method {}'.format(method))
|
||||||
|
o = jsonrpc_request(method, params)
|
||||||
|
j = json.dumps(o)
|
||||||
|
logg.debug('send {}'.format(j))
|
||||||
|
s.send(j.encode('utf-8'))
|
||||||
|
r = s.recv(4096)
|
||||||
|
s.close()
|
||||||
|
logg.debug('got recv {}'.format(str(r)))
|
||||||
|
jr = json.loads(r)
|
||||||
|
jr['id'] = self.id_seq
|
||||||
|
#return str(json.dumps(jr))
|
||||||
|
return jr
|
||||||
|
|
||||||
|
r = self.make_request(method, params)
|
||||||
|
logg.debug('retular response {}'.format(r))
|
||||||
|
return r
|
||||||
|
|
||||||
|
|
||||||
|
w3 = Web3(WebsocketProvider('ws://127.0.0.1:8546'))
|
||||||
|
w3.eth.personal = w3.geth.personal
|
||||||
|
w3.middleware_onion.add(PlatformMiddleware)
|
||||||
|
print(w3.eth.personal.newAccount('foo'))
|
||||||
|
#print(w3.eth.blockNumber)
|
Loading…
Reference in New Issue
Block a user