mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
pytest: test Bitcoin plugin registration and the bcli plugin
This commit is contained in:
parent
4c5862eab1
commit
a47fd8cf3e
@ -80,6 +80,9 @@ void bitcoind_check_commands(struct bitcoind *bitcoind)
|
||||
for (i = 0; i < ARRAY_SIZE(methods); i++) {
|
||||
p = find_plugin_for_command(bitcoind->ld, methods[i]);
|
||||
if (p == NULL) {
|
||||
/* For testing .. */
|
||||
log_debug(bitcoind->ld->log, "Missing a Bitcoin plugin"
|
||||
" command");
|
||||
fatal("Could not access the plugin for %s, is a "
|
||||
"Bitcoin plugin (by default plugins/bcli) "
|
||||
"registered ?", methods[i]);
|
||||
|
@ -1001,6 +1001,9 @@ void setup_topology(struct chain_topology *topo,
|
||||
/* This waits for bitcoind. */
|
||||
bitcoind_check_commands(topo->bitcoind);
|
||||
|
||||
/* For testing.. */
|
||||
log_debug(topo->ld->log, "All Bitcoin plugin commands registered");
|
||||
|
||||
/* Sanity checks, then topology initialization. */
|
||||
bitcoind_getchaininfo(topo->bitcoind, true, check_chain, topo);
|
||||
|
||||
|
37
tests/plugins/bitcoin/part1.py
Executable file
37
tests/plugins/bitcoin/part1.py
Executable file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
This registers part of the Bitcoin backend methods.
|
||||
We only use it for testing startup and we don't care about the actual values.
|
||||
"""
|
||||
import time
|
||||
|
||||
from pyln.client import Plugin
|
||||
|
||||
|
||||
plugin = Plugin()
|
||||
|
||||
|
||||
@plugin.method("getfeerate")
|
||||
def getfeerate(plugin, **kwargs):
|
||||
time.sleep(1)
|
||||
return {}
|
||||
|
||||
|
||||
@plugin.method("getrawblockbyheight")
|
||||
def getblock(plugin, **kwargs):
|
||||
time.sleep(1)
|
||||
return {}
|
||||
|
||||
|
||||
@plugin.method("getchaininfo")
|
||||
def getchaininfo(plugin, **kwargs):
|
||||
time.sleep(1)
|
||||
return {}
|
||||
|
||||
|
||||
# We don't use these options, but it allows us to get to the expected failure.
|
||||
plugin.add_option("bitcoin-rpcuser", "", "")
|
||||
plugin.add_option("bitcoin-rpcpassword", "", "")
|
||||
plugin.add_option("bitcoin-rpcport", "", "")
|
||||
|
||||
plugin.run()
|
26
tests/plugins/bitcoin/part2.py
Executable file
26
tests/plugins/bitcoin/part2.py
Executable file
@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
This registers part of the Bitcoin backend methods.
|
||||
We only use it for testing startup and we don't care about the actual values.
|
||||
"""
|
||||
import time
|
||||
|
||||
from pyln.client import Plugin
|
||||
|
||||
|
||||
plugin = Plugin()
|
||||
|
||||
|
||||
@plugin.method("sendrawtransaction")
|
||||
def sendtx(plugin, **kwargs):
|
||||
time.sleep(1)
|
||||
return {}
|
||||
|
||||
|
||||
@plugin.method("getutxout")
|
||||
def gettxout(plugin, **kwargs):
|
||||
time.sleep(1)
|
||||
return {}
|
||||
|
||||
|
||||
plugin.run()
|
@ -931,3 +931,84 @@ def test_hook_chaining(node_factory):
|
||||
assert(l2.daemon.is_in_log(
|
||||
r'plugin-hook-chain-even.py: htlc_accepted called for payment_hash {}'.format(hash3)
|
||||
))
|
||||
|
||||
|
||||
def test_bitcoin_backend(node_factory, bitcoind):
|
||||
"""
|
||||
This tests interaction with the Bitcoin backend, but not specifically bcli
|
||||
"""
|
||||
l1 = node_factory.get_node(start=False, options={"disable-plugin": "bcli"},
|
||||
may_fail=True, allow_broken_log=True)
|
||||
|
||||
# We don't start if we haven't all the required methods registered.
|
||||
plugin = os.path.join(os.getcwd(), "tests/plugins/bitcoin/part1.py")
|
||||
l1.daemon.opts["plugin"] = plugin
|
||||
try:
|
||||
l1.daemon.start()
|
||||
except ValueError:
|
||||
assert l1.daemon.is_in_log("Missing a Bitcoin plugin command")
|
||||
# Now we should start if all the commands are registered, even if they
|
||||
# are registered by two distincts plugins.
|
||||
del l1.daemon.opts["plugin"]
|
||||
l1.daemon.opts["plugin-dir"] = os.path.join(os.getcwd(),
|
||||
"tests/plugins/bitcoin/")
|
||||
try:
|
||||
l1.daemon.start()
|
||||
except ValueError:
|
||||
msg = "All Bitcoin plugin commands registered"
|
||||
assert l1.daemon.is_in_log(msg)
|
||||
else:
|
||||
raise Exception("We registered all commands but couldn't start!")
|
||||
else:
|
||||
raise Exception("We could start without all commands registered !!")
|
||||
|
||||
# But restarting with just bcli is ok
|
||||
del l1.daemon.opts["plugin-dir"]
|
||||
del l1.daemon.opts["disable-plugin"]
|
||||
l1.start()
|
||||
assert l1.daemon.is_in_log("bitcoin-cli initialized and connected to"
|
||||
" bitcoind")
|
||||
|
||||
|
||||
def test_bcli(node_factory, bitcoind, chainparams):
|
||||
"""
|
||||
This tests the bcli plugin, used to gather Bitcoin data from a local
|
||||
bitcoind.
|
||||
Mostly sanity checks of the interface..
|
||||
"""
|
||||
l1, l2 = node_factory.get_nodes(2)
|
||||
|
||||
# We cant stop it dynamically
|
||||
with pytest.raises(RpcError):
|
||||
l1.rpc.plugin_stop("bcli")
|
||||
|
||||
# Failure case of feerate is tested in test_misc.py
|
||||
assert "feerate" in l1.rpc.call("getfeerate", {"blocks": 3,
|
||||
"mode": "CONSERVATIVE"})
|
||||
|
||||
resp = l1.rpc.call("getchaininfo")
|
||||
assert resp["chain"] == chainparams['name']
|
||||
for field in ["headercount", "blockcount", "ibd"]:
|
||||
assert field in resp
|
||||
|
||||
# We shouldn't get upset if we ask for an unknown-yet block
|
||||
resp = l1.rpc.call("getrawblockbyheight", {"height": 500})
|
||||
assert resp["blockhash"] is resp["block"] is None
|
||||
resp = l1.rpc.call("getrawblockbyheight", {"height": 50})
|
||||
assert resp["blockhash"] is not None and resp["blockhash"] is not None
|
||||
# Some other bitcoind-failure cases for this call are covered in
|
||||
# tests/test_misc.py
|
||||
|
||||
l1.fundwallet(10**5)
|
||||
l1.connect(l2)
|
||||
txid = l1.rpc.fundchannel(l2.info["id"], 10**4)["txid"]
|
||||
txo = l1.rpc.call("getutxout", {"txid": txid, "vout": 0})
|
||||
assert (Millisatoshi(txo["amount"]) == Millisatoshi(10**4 * 10**3)
|
||||
and txo["script"].startswith("0020"))
|
||||
l1.rpc.close(l2.info["id"])
|
||||
# When output is spent, it should give us null !
|
||||
txo = l1.rpc.call("getutxout", {"txid": txid, "vout": 0})
|
||||
assert txo["amount"] is txo["script"] is None
|
||||
|
||||
resp = l1.rpc.call("sendrawtransaction", {"tx": "dummy"})
|
||||
assert not resp["success"] and "decode failed" in resp["errmsg"]
|
||||
|
Loading…
Reference in New Issue
Block a user