commit 2e687114af2bb5bff129ed0f04a36c3ac7c3d09c
parent a7f859b952ce758e8546e52d83410f05cb951975
Author: nolash <dev@holbrook.no>
Date: Fri, 9 Apr 2021 17:39:00 +0200
Add http server jsonrpc code
Diffstat:
5 files changed, 154 insertions(+), 1 deletion(-)
diff --git a/.gitignore b/.gitignore
@@ -0,0 +1,5 @@
+__pycache__
+*.pyc
+dist/
+*.egg-info
+gmon.out
diff --git a/config/httpd.ini b/config/httpd.ini
@@ -0,0 +1,3 @@
+[httpd]
+host =
+port =
diff --git a/config/store.ini b/config/store.ini
@@ -0,0 +1,2 @@
+[store]
+base_dir = /run
diff --git a/eth_stat_syncer/runnable/server.py b/eth_stat_syncer/runnable/server.py
@@ -0,0 +1,144 @@
+# standard import
+import json
+import os
+import logging
+import argparse
+import sys
+from http.server import (
+ HTTPServer,
+ BaseHTTPRequestHandler,
+ )
+
+# external imports
+import confini
+from jsonrpc_std.parse import jsonrpc_from_str
+from jsonrpc_std.interface import jsonrpc_response
+
+# local imports
+from eth_stat_syncer.store import RunStore
+
+logging.basicConfig(level=logging.WARNING)
+logg = logging.getLogger()
+
+default_config_dir = os.environ.get('CONFINI_DIR', './config')
+
+argparser = argparse.ArgumentParser()
+argparser.add_argument('-c', '--config', dest='c', default=default_config_dir, type=str, help='rpc provider')
+argparser.add_argument('--host', type=str, help='httpd host')
+argparser.add_argument('--port', type=str, help='httpd port')
+argparser.add_argument('--store-dir', dest='store_dir', type=str, help='syncerd data store base directory')
+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('-v', action='store_true', help='be verbose')
+argparser.add_argument('-vv', action='store_true', help='be more verbose')
+args = argparser.parse_args()
+
+if args.vv:
+ logging.getLogger().setLevel(logging.DEBUG)
+elif args.v:
+ logging.getLogger().setLevel(logging.INFO)
+
+config = confini.Config(args.c, args.env_prefix)
+config.process()
+# override args
+args_override = {
+ 'HTTPD_HOST': getattr(args, 'host'),
+ 'HTTPD_PORT': getattr(args, 'port'),
+ 'STORE_BASE_DIR': getattr(args, 'store_dir'),
+ }
+config.dict_override(args_override, 'cli flag')
+logg.debug('loaded config: {}\n'.format(config))
+
+class StatRequestHandler(BaseHTTPRequestHandler):
+
+ runstore = None
+ server_version = 'eth_stat_syncer/0.0.1'
+
+
+ def do_POST(self):
+
+ if self.headers.get('Content-Type') != 'application/json':
+ self.send_response(400, 'me read json only')
+ self.end_headers()
+ return
+
+ if 'application/json' not in self.headers.get('Accept').split(','):
+ self.send_response(400, 'me json only speak')
+ self.end_headers()
+ return
+
+ l = self.headers.get('Content-Length')
+ try:
+ l = int(l)
+ except ValueError:
+ self.send_response(400, 'content length must be integer')
+ self.end_headers()
+ return
+ if l > 4096:
+ self.send_response(400, 'too much information')
+ self.end_headers()
+ return
+ if l < 0:
+ self.send_response(400, 'you are too negative')
+ self.end_headers()
+ return
+
+ b = b''
+ c = 0
+ while c < l:
+ d = self.rfile.read(l-c)
+ if d == None:
+ break
+ b += d
+ c += len(d)
+ if c > 4096:
+ self.send_response(413, 'i should slap you around for lying about your size')
+ self.end_headers()
+ return
+
+ o = None
+ err = None
+ try:
+ o = jsonrpc_from_str(b.decode('utf-8'))
+ except JSONRPCException as e:
+ err = e
+
+ if err != None:
+ res = e
+ self.send_response(200, 'alas with jsonrpc error')
+
+ else:
+ r = self.runstore.get('high', 'minute')
+ r = int(r)
+ if r == 0:
+ r = 1
+ res = jsonrpc_response(o['id'], r)
+ logg.debug('returning {} for req {} {}'.format(r, o, self.requestline))
+ self.send_response(200, 'It\'s a gas')
+
+ b = json.dumps(res).encode('utf-8')
+ l = len(b)
+ self.send_header('Content-Length', str(l))
+ self.send_header('Cache-Control', 'no-cache')
+ self.send_header('Content-Type', 'application/json')
+ self.end_headers()
+
+ c = 0
+ while c < l:
+ n = self.wfile.write(b[c:])
+ c += n
+
+
+def run(store, host=None, port=None):
+ if host == None:
+ host = ''
+ if port == None:
+ port = 8000
+ StatRequestHandler.runstore = store
+ server_address = (host, port)
+ httpd = HTTPServer(server_address, StatRequestHandler)
+ httpd.serve_forever()
+
+
+if __name__ == '__main__':
+ store = RunStore(basedir=config.get('STORE_BASE_DIR'))
+ run(store, host=config.get('HTTPD_HOST'), port=config.get('HTTPD_PORT'))
diff --git a/eth_stat_syncer/runnable/syncer.py b/eth_stat_syncer/runnable/syncer.py
@@ -91,7 +91,6 @@ def main():
syncer.loop(0.0, conn)
except NoBlockForYou:
logg.info('history done at {}'.format(syncer.backend.get()))
- pass
syncer_backend = MemBackend(chain_spec, None)
syncer_backend.set(start_block + 1, 0)