diff --git a/contrib/plugins/helloworld.py b/contrib/plugins/helloworld.py new file mode 100755 index 000000000..7059548a2 --- /dev/null +++ b/contrib/plugins/helloworld.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +"""Simple plugin to show how to build new plugins for c-lightning + +It demonstrates how a plugin communicates with c-lightning, how it registers +command line arguments that should be passed through and how it can register +JSON-RPC commands. We communicate with the main daemon through STDIN and STDOUT, +reading and writing JSON-RPC requests. + +""" +import json +import sys + + +greeting = "World" + + +def json_hello(request): + greeting = "Hello {}".format(request['params']['name']) + return greeting + + +def json_getmanifest(request): + global greeting + return { + "options": [ + {"name": "greeting", + "type": "string", + "default": greeting, + "description": "What name should I call you?"}, + ], + "rpcmethods": [ + { + "name": "hello", + "description": "Returns a personalized greeting for {name}", + }, + ] + } + + +def json_init(request): + """The main daemon is telling us the relevant cli options + """ + global greeting + + greeting = request['params']['options']['greeting'] + return "ok" + + +methods = { + 'hello': json_hello, + 'getmanifest': json_getmanifest, + 'init': json_init, +} + +partial = "" +for l in sys.stdin: + partial += l + try: + request = json.loads(partial) + result = { + "jsonrpc": "2.0", + "result": methods[request['method']](request), + "id": request['id'] + } + json.dump(result, fp=sys.stdout) + sys.stdout.write('\n') + sys.stdout.flush() + partial = "" + except Exception: + pass diff --git a/tests/test_plugin.py b/tests/test_plugin.py new file mode 100644 index 000000000..f590abb8b --- /dev/null +++ b/tests/test_plugin.py @@ -0,0 +1,29 @@ +from fixtures import * # noqa: F401,F403 + +import subprocess + + +def test_option_passthrough(node_factory): + """ Ensure that registering options works. + + First attempts without the plugin and then with the plugin. + """ + plugin_path = 'contrib/helloworld-plugin/main.py' + + help_out = subprocess.check_output([ + 'lightningd/lightningd', + '--help' + ]).decode('utf-8') + assert('--greeting' not in help_out) + + help_out = subprocess.check_output([ + 'lightningd/lightningd', + '--plugin={}'.format(plugin_path), + '--help' + ]).decode('utf-8') + assert('--greeting' in help_out) + + # Now try to see if it gets accepted, would fail to start if the + # option didn't exist + n = node_factory.get_node(options={'plugin': plugin_path, 'greeting': 'Mars'}) + n.stop() diff --git a/tests/utils.py b/tests/utils.py index bdb09cbd1..d7c8545a8 100644 --- a/tests/utils.py +++ b/tests/utils.py @@ -772,7 +772,7 @@ class NodeFactory(object): 'valgrind', '-q', '--trace-children=yes', - '--trace-children-skip=*bitcoin-cli*', + '--trace-children-skip=*plugins*,*python*,*bitcoin-cli*', '--error-exitcode=7', '--log-file={}/valgrind-errors.%p'.format(node.daemon.lightning_dir) ]