mirror of https://github.com/oxen-io/lokinet
Merge pull request #1077 from majestrate/mock-lokid-rpc-2020-02-02
mock lokid for loopback testnet
This commit is contained in:
commit
6f182c4b26
9
Makefile
9
Makefile
|
@ -54,6 +54,7 @@ TESTNET_ROOT=/tmp/lokinet_testnet_tmp
|
|||
TESTNET_CONF=$(TESTNET_ROOT)/supervisor.conf
|
||||
TESTNET_LOG=$(TESTNET_ROOT)/testnet.log
|
||||
|
||||
TESTNET_VENV=$(TESTNET_ROOT)/v
|
||||
TESTNET_EXE=$(REPO)/lokinet-testnet
|
||||
TESTNET_CLIENTS ?= 50
|
||||
TESTNET_SERVERS ?= 50
|
||||
|
@ -208,10 +209,14 @@ testnet-configure: testnet-clean
|
|||
testnet-build: testnet-configure
|
||||
$(MAKE) -C $(BUILD_ROOT)
|
||||
|
||||
testnet:
|
||||
$(TESTNET_VENV):
|
||||
$(PYTHON3) -m venv $(TESTNET_VENV) --system-site-packages
|
||||
$(TESTNET_VENV)/bin/pip install -r $(REPO)/contrib/testnet/requirements.txt
|
||||
|
||||
testnet: $(TESTNET_VENV)
|
||||
cp $(EXE) $(TESTNET_EXE)
|
||||
mkdir -p $(TESTNET_ROOT)
|
||||
$(PYTHON3) $(REPO)/contrib/testnet/genconf.py --bin=$(TESTNET_EXE) --svc=$(TESTNET_SERVERS) --clients=$(TESTNET_CLIENTS) --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) --ifname=$(TESTNET_IFNAME) --baseport=$(TESTNET_BASEPORT) --ip=$(TESTNET_IP) --netid=$(TESTNET_NETID)
|
||||
$(PYTHON3) $(REPO)/contrib/testnet/genconf.py --bin=$(TESTNET_EXE) --svc=$(TESTNET_SERVERS) --clients=$(TESTNET_CLIENTS) --dir=$(TESTNET_ROOT) --out $(TESTNET_CONF) --ifname=$(TESTNET_IFNAME) --baseport=$(TESTNET_BASEPORT) --ip=$(TESTNET_IP) --netid=$(TESTNET_NETID) --lokid='$(TESTNET_VENV)/bin/python $(REPO)/contrib/testnet/lokid.py'
|
||||
LLARP_DEBUG=$(TESTNET_DEBUG) supervisord -n -d $(TESTNET_ROOT) -l $(TESTNET_LOG) -c $(TESTNET_CONF)
|
||||
|
||||
$(TEST_EXE): debug
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
v/
|
|
@ -18,6 +18,7 @@ def clientNodeName(id): return 'client-node-%03d' % id
|
|||
|
||||
def main():
|
||||
ap = AP()
|
||||
ap.add_argument('--lokid', type=str, required=True)
|
||||
ap.add_argument('--valgrind', type=bool, default=False)
|
||||
ap.add_argument('--dir', type=str, default='testnet_tmp')
|
||||
ap.add_argument('--svc', type=int, default=20,
|
||||
|
@ -36,7 +37,7 @@ def main():
|
|||
if args.valgrind:
|
||||
exe = 'valgrind {}'.format(args.bin)
|
||||
else:
|
||||
exe = args.bin
|
||||
exe = '{} -v'.format(args.bin)
|
||||
basedir = os.path.abspath(args.dir)
|
||||
|
||||
for nodeid in range(args.svc):
|
||||
|
@ -66,6 +67,12 @@ def main():
|
|||
config['api'] = {
|
||||
'enabled': 'false'
|
||||
}
|
||||
config['lokid'] = {
|
||||
'enabled': 'true',
|
||||
'username': 'svc-%03d' % nodeid,
|
||||
'password': 'lokinet',
|
||||
'jsonrpc': '127.0.0.1:5000'
|
||||
}
|
||||
d = os.path.join(args.dir, svcNodeName(nodeid))
|
||||
if not os.path.exists(d):
|
||||
os.mkdir(d)
|
||||
|
@ -118,6 +125,13 @@ type=null
|
|||
''')
|
||||
|
||||
with open(args.out, 'w') as f:
|
||||
f.write('''[program:mock-lokid]
|
||||
command = {} {}
|
||||
autorestart = true
|
||||
redirect_stderr=true
|
||||
stdout_logfile={}/lokid.txt
|
||||
stdout_logfile_maxbytes=0
|
||||
'''.format(args.lokid, args.svc, args.dir))
|
||||
f.write('''[program:svc-node]
|
||||
directory = {}
|
||||
command = {} daemon.ini
|
||||
|
|
|
@ -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