Add http server jsonrpc code

This commit is contained in:
nolash 2021-04-09 17:39:00 +02:00
parent a7f859b952
commit 2e687114af
Signed by: lash
GPG Key ID: 21D2E7BB88C2A746
5 changed files with 154 additions and 1 deletions

5
.gitignore vendored Normal file
View File

@ -0,0 +1,5 @@
__pycache__
*.pyc
dist/
*.egg-info
gmon.out

3
config/httpd.ini Normal file
View File

@ -0,0 +1,3 @@
[httpd]
host =
port =

2
config/store.ini Normal file
View File

@ -0,0 +1,2 @@
[store]
base_dir = /run

View File

@ -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'))

View File

@ -91,7 +91,6 @@ def main():
syncer.loop(0.0, conn) syncer.loop(0.0, conn)
except NoBlockForYou: except NoBlockForYou:
logg.info('history done at {}'.format(syncer.backend.get())) logg.info('history done at {}'.format(syncer.backend.get()))
pass
syncer_backend = MemBackend(chain_spec, None) syncer_backend = MemBackend(chain_spec, None)
syncer_backend.set(start_block + 1, 0) syncer_backend.set(start_block + 1, 0)