eth-gas-proxy

Middleware to selectively override EVM gas heuristics
git clone git://holbrook.no/eth-gas-proxy.git
Log | Files | Refs

commit e06ab63d8e7285d2428c00e2e0b71f1bd66c3b0c
Author: nolash <dev@holbrook.no>
Date:   Mon, 25 Jan 2021 23:04:21 +0100

Initial commit

Diffstat:
Agas_proxy/cache/__init__.py | 0
Agas_proxy/cache/base.py | 8++++++++
Agas_proxy/cache/mem.py | 15+++++++++++++++
Agas_proxy/proxy.py | 52++++++++++++++++++++++++++++++++++++++++++++++++++++
Agas_proxy/runnable/server.py | 46++++++++++++++++++++++++++++++++++++++++++++++
Atests/test_memcache.py | 25+++++++++++++++++++++++++
6 files changed, 146 insertions(+), 0 deletions(-)

diff --git a/gas_proxy/cache/__init__.py b/gas_proxy/cache/__init__.py diff --git a/gas_proxy/cache/base.py b/gas_proxy/cache/base.py @@ -0,0 +1,8 @@ +class Cache: + + def get(self): + raise NotImplementedError + + + def set(self, price): + raise NotImplementedError diff --git a/gas_proxy/cache/mem.py b/gas_proxy/cache/mem.py @@ -0,0 +1,15 @@ +from .base import Cache + +class MemCache(Cache): + + + def __init__(self): + self.lastvalue = 0 + + + def get(self): + return self.lastvalue + + + def set(self, value): + self.lastvalue = value diff --git a/gas_proxy/proxy.py b/gas_proxy/proxy.py @@ -0,0 +1,52 @@ +import json +import logging + +import websocket + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +class Oracle: + + def get(self): + raise NotImplementedError + +class Web3WebsocketOracle(Oracle): + + + def __init__(self, connection_string, cache=None): + logg.debug('connecting to {}'.format(connection_string)) + self.ws = websocket.create_connection(connection_string) + self.query = { + "jsonrpc": "2.0", + "method": "eth_gasPrice", + "params": [], + "id": 0, + } + self.cache = cache + + + def __del__(self): + self.ws.close() + + + def get(self): + o = None + try: + self.ws.send(json.dumps(self.query)) + result = self.ws.recv() + o = json.loads(result) + result_hex = o['result'][2:] + if len(result_hex) % 2 != 0: + result_hex = '0' + result_hex + result_bytes = bytes.fromhex(result_hex) + result_num = int.from_bytes(result_bytes, 'big') + except Exception as e: + if self.cache == None: + raise(e) + result_num = self.cache.get() + + if self.cache != None: + self.cache.set(result_num) + return result_num diff --git a/gas_proxy/runnable/server.py b/gas_proxy/runnable/server.py @@ -0,0 +1,46 @@ +import os +import argparse +import logging +import socket +import json + +from gas_proxy.proxy import Web3WebsocketOracle as Oracle +from gas_proxy.cache.mem import MemCache + +logging.basicConfig(level=logging.DEBUG) +logg = logging.getLogger() + + +argparser = argparse.ArgumentParser() +#argparser.add_argument('-c', type=str, default=config_dir, help='config file') +argparser.add_argument('--env-prefix', default=os.environ.get('CONFINI_ENV_PREFIX'), dest='env_prefix', type=str, help='environment prefix for variables to overwrite configuration') +argparser.add_argument('--host', default='localhost', type=str) +argparser.add_argument('--port', default=8545, type=int) +argparser.add_argument('-v', action='store_true', help='be verbose') +argparser.add_argument('-vv', action='store_true', help='be more verbose') +argparser.add_argument('provider', type=str, help='Gas price provider url') +args = argparser.parse_args() + +if args.vv: + logging.getLogger().setLevel(logging.DEBUG) +elif args.v: + logging.getLogger().setLevel(logging.INFO) + +if __name__ == '__main__': + memcache = MemCache() + ws = Oracle(args.provider, cache=memcache) + + s = socket.socket(family=socket.AF_INET, type=socket.SOCK_STREAM) + s.bind((args.host, args.port)) + s.listen(10) + + while True: + (csock, caddr) = s.accept() + d = csock.recv(4096) + o = json.loads(d) + response = { + "jsonrpc": "2.0", + "id": o['id'], + "result": ws.get(), + } + csock.send(json.dumps(response).encode('utf-8')) diff --git a/tests/test_memcache.py b/tests/test_memcache.py @@ -0,0 +1,25 @@ +import unittest + +from gas_proxy.cache.mem import MemCache + + +class Test(unittest.TestCase): + + + def setUp(self): + pass + + + def tearDown(self): + pass + + + + def test_memcache(self): + memcache = MemCache() + memcache.set(10) + self.assertEqual(memcache.get(), 10) + + +if __name__ == '__main__': + unittest.main()