Move middleware to web3 override package
This commit is contained in:
		
							parent
							
								
									0fa2dc1efa
								
							
						
					
					
						commit
						b9a88de30c
					
				@ -7,7 +7,7 @@ import os
 | 
			
		||||
from jsonrpc.exceptions import *
 | 
			
		||||
 | 
			
		||||
from signer import ReferenceSigner
 | 
			
		||||
from keystore import ReferenceDatabase
 | 
			
		||||
from keystore import ReferenceKeystore
 | 
			
		||||
from transaction import Transaction
 | 
			
		||||
 | 
			
		||||
logging.basicConfig(level=logging.DEBUG)
 | 
			
		||||
@ -128,7 +128,7 @@ def init():
 | 
			
		||||
    kw = {
 | 
			
		||||
            'symmetric_key': secret,
 | 
			
		||||
            }
 | 
			
		||||
    db = ReferenceDatabase('cic_signer', **kw)
 | 
			
		||||
    db = ReferenceKeystore('cic_signer', **kw)
 | 
			
		||||
    signer = ReferenceSigner(db)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -1,92 +1,11 @@
 | 
			
		||||
import logging
 | 
			
		||||
import re
 | 
			
		||||
import socket
 | 
			
		||||
import uuid
 | 
			
		||||
import json
 | 
			
		||||
from web3ext import Web3
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    # TODO: understand what format input params come in
 | 
			
		||||
    # single entry input gives a tuple on params, wtf...
 | 
			
		||||
    # dict input comes as [{}] and fails if not passed on as an array
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def _translate_params(params):
 | 
			
		||||
        if params.__class__.__name__ == 'tuple':
 | 
			
		||||
            r = []
 | 
			
		||||
            for p in params:
 | 
			
		||||
                r.append(p)
 | 
			
		||||
            return r
 | 
			
		||||
 | 
			
		||||
        if params.__class__.__name__ == 'list' and len(params) > 0:
 | 
			
		||||
            return params[0]
 | 
			
		||||
 | 
			
		||||
        return params
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def __call__(self, method, suspect_params):
 | 
			
		||||
 | 
			
		||||
        self.id_seq += 1
 | 
			
		||||
        logg.debug('in middleware method {} params {}'.format(method, suspect_params))
 | 
			
		||||
 | 
			
		||||
        if self.re_personal.match(method) != None:
 | 
			
		||||
            params = PlatformMiddleware._translate_params(suspect_params)
 | 
			
		||||
            # 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.info('redirecting method {}  params {} original params {}'.format(method, params, suspect_params))
 | 
			
		||||
            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, suspect_params)
 | 
			
		||||
        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)
 | 
			
		||||
#print(w3.eth.sendTransaction({'to': '0xd3CdA913deB6f67967B99D67aCDFa1712C293601','from': '0xc305c901078781C232A2a521C2aF7980f8385ee9','value': 1000}))
 | 
			
		||||
# TODO: remove and replace with test
 | 
			
		||||
if __name__ == '__main__':
 | 
			
		||||
    w3 = Web3(['ws://127.0.0.1:8546'])
 | 
			
		||||
    print(w3.eth.personal.newAccount('foo'))
 | 
			
		||||
    print(w3.eth.blockNumber)
 | 
			
		||||
    #print(w3.eth.sendTransaction({'to': '0xd3CdA913deB6f67967B99D67aCDFa1712C293601','from': '0xc305c901078781C232A2a521C2aF7980f8385ee9','value': 1000}))
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
        
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										31
									
								
								src/web3ext/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								src/web3ext/__init__.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,31 @@
 | 
			
		||||
import re
 | 
			
		||||
 | 
			
		||||
from web3 import Web3 as Web3super
 | 
			
		||||
from web3 import WebsocketProvider, HTTPProvider
 | 
			
		||||
from web3ext.middleware import PlatformMiddleware
 | 
			
		||||
 | 
			
		||||
re_websocket = re.compile('^wss?://')
 | 
			
		||||
re_http = re.compile('^https?://')
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#def create_middleware(ipcaddr='/var/run/cic-platform/cic.ipc'):
 | 
			
		||||
def create_middleware(ipcaddr='/tmp/foo.ipc'):
 | 
			
		||||
    PlatformMiddleware.ipcaddr = ipcaddr
 | 
			
		||||
    return PlatformMiddleware
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
# overrides the original Web3 constructor
 | 
			
		||||
def Web3(blockchain_providers=[], ipcaddr=None):
 | 
			
		||||
    if len(blockchain_providers) > 1:
 | 
			
		||||
        raise ValueError('backend only supports single provider')
 | 
			
		||||
    provider = None
 | 
			
		||||
    if re.match(re_websocket, blockchain_providers[0]) != None:
 | 
			
		||||
        provider = WebsocketProvider(blockchain_providers[0])
 | 
			
		||||
    elif re.match(re_http, blockchain_providers[0]) != None:
 | 
			
		||||
        provider = HTTPProvider(blockchain_providers[0])
 | 
			
		||||
 | 
			
		||||
    w3 = Web3super(provider)
 | 
			
		||||
 | 
			
		||||
    w3.middleware_onion.add(create_middleware())
 | 
			
		||||
    w3.eth.personal = w3.geth.personal
 | 
			
		||||
    return w3
 | 
			
		||||
							
								
								
									
										78
									
								
								src/web3ext/middleware.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								src/web3ext/middleware.py
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,78 @@
 | 
			
		||||
import logging
 | 
			
		||||
import re
 | 
			
		||||
import socket
 | 
			
		||||
import uuid
 | 
			
		||||
import json
 | 
			
		||||
 | 
			
		||||
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
 | 
			
		||||
 | 
			
		||||
    
 | 
			
		||||
    # TODO: understand what format input params come in
 | 
			
		||||
    # single entry input gives a tuple on params, wtf...
 | 
			
		||||
    # dict input comes as [{}] and fails if not passed on as an array
 | 
			
		||||
    @staticmethod
 | 
			
		||||
    def _translate_params(params):
 | 
			
		||||
        if params.__class__.__name__ == 'tuple':
 | 
			
		||||
            r = []
 | 
			
		||||
            for p in params:
 | 
			
		||||
                r.append(p)
 | 
			
		||||
            return r
 | 
			
		||||
 | 
			
		||||
        if params.__class__.__name__ == 'list' and len(params) > 0:
 | 
			
		||||
            return params[0]
 | 
			
		||||
 | 
			
		||||
        return params
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    def __call__(self, method, suspect_params):
 | 
			
		||||
 | 
			
		||||
        self.id_seq += 1
 | 
			
		||||
        logg.debug('in middleware method {} params {}'.format(method, suspect_params))
 | 
			
		||||
 | 
			
		||||
        if self.re_personal.match(method) != None:
 | 
			
		||||
            params = PlatformMiddleware._translate_params(suspect_params)
 | 
			
		||||
            # 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.info('redirecting method {}  params {} original params {}'.format(method, params, suspect_params))
 | 
			
		||||
            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, suspect_params)
 | 
			
		||||
        return r
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user