mirror of https://github.com/oxen-io/lokinet
Merge pull request #1077 from majestrate/mock-lokid-rpc-2020-02-02
mock lokid for loopback testnetpull/1108/head
commit
6f182c4b26
@ -0,0 +1 @@
|
||||
v/
|
@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env python3
|
||||
|
||||
|
||||
import os
|
||||
from base64 import b64decode
|
||||
|
||||
from flask import Flask, jsonify, request, abort, Response, make_response
|
||||
from nacl import signing
|
||||
from nacl import encoding
|
||||
|
||||
class SVCNode:
|
||||
"""
|
||||
info on a service node
|
||||
"""
|
||||
def __init__(self):
|
||||
self._seed = os.urandom(32)
|
||||
self._ed25519_secret = signing.SigningKey(self._seed)
|
||||
|
||||
def seed(self):
|
||||
"""
|
||||
return hex seed
|
||||
"""
|
||||
return self._ed25519_secret.encode(encoding.HexEncoder).decode('ascii') + self.pubkey()
|
||||
|
||||
def pubkey(self):
|
||||
"""
|
||||
make hex public key
|
||||
"""
|
||||
return self._ed25519_secret.verify_key.encode(encoding.HexEncoder).decode('ascii')
|
||||
|
||||
def toJson(self):
|
||||
"""
|
||||
make the snode a json object for jsonrpc
|
||||
"""
|
||||
return {'pubkey_ed25519': self.pubkey(), 'active': True, 'funded': True}
|
||||
|
||||
class MockServer:
|
||||
|
||||
def __init__(self, numServiceNodes):
|
||||
self.app = Flask('lokid-rpc-mock')
|
||||
#self.app.config['SECRET_KEY'] = os.urandom(16)
|
||||
# populate service nodes
|
||||
self._serviceNodes = dict()
|
||||
for n in range(numServiceNodes):
|
||||
self.makeSNode("svc-%03d" % n)
|
||||
|
||||
self._handlers = {
|
||||
'lokinet_ping': self._lokinet_ping,
|
||||
'get_n_service_nodes' : self._get_n_service_nodes,
|
||||
'get_service_node_privkey' : self._get_service_node_privkey
|
||||
}
|
||||
#digest = HTTPDigestAuth(realm='lokid')
|
||||
|
||||
@self.app.route('/json_rpc', methods=["POST"])
|
||||
def _jsonRPC():
|
||||
j = request.get_json()
|
||||
method = j['method']
|
||||
snode = None
|
||||
if 'authorization' in request.headers:
|
||||
user = b64decode(request.headers['authorization'][6:].encode('ascii')).decode('ascii').split(':')[0]
|
||||
self.app.logger.error(user)
|
||||
if len(user) > 0:
|
||||
snode = self._serviceNodes[user]
|
||||
result = self._handlers[method](snode)
|
||||
if result:
|
||||
resp = {'jsonrpc': '2.0', 'id': j['id'], 'result': result}
|
||||
return jsonify(resp)
|
||||
else:
|
||||
r = make_response('nope', 401)
|
||||
r.headers['www-authenticate'] = 'basic'
|
||||
return r
|
||||
def after(req):
|
||||
req.content_type = "application/json"
|
||||
return req
|
||||
self.app.after_request(after)
|
||||
|
||||
def _get_n_service_nodes(self, our_snode):
|
||||
return {
|
||||
'block_hash' : 'mock',
|
||||
'service_node_states' : self.getSNodeList()
|
||||
}
|
||||
|
||||
def _get_service_node_privkey(self, our_snode):
|
||||
if our_snode is None:
|
||||
return None
|
||||
return {
|
||||
'service_node_ed25519_privkey': our_snode.seed()
|
||||
}
|
||||
|
||||
def _lokinet_ping(self, snode):
|
||||
return {
|
||||
'status' : "OK"
|
||||
}
|
||||
|
||||
def run(self):
|
||||
"""
|
||||
run mainloop and serve jsonrpc server
|
||||
"""
|
||||
self.app.run()
|
||||
|
||||
def makeSNode(self, name):
|
||||
"""
|
||||
make service node entry
|
||||
"""
|
||||
self._serviceNodes[name] = SVCNode()
|
||||
|
||||
|
||||
def getSNodeList(self):
|
||||
l = list()
|
||||
for name in self._serviceNodes:
|
||||
l.append(self._serviceNodes[name].toJson())
|
||||
return l
|
||||
|
||||
|
||||
def main():
|
||||
import sys
|
||||
serv = MockServer(int(sys.argv[1]))
|
||||
serv.run()
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
@ -0,0 +1,2 @@
|
||||
flask
|
||||
pynacl
|
Loading…
Reference in New Issue