Skip to content

Commit

Permalink
Add plugin notification topic "block_processed".
Browse files Browse the repository at this point in the history
Changelog-Added: Plugins: Added notification topic "block_processed".
  • Loading branch information
fiatjaf committed Sep 9, 2022
1 parent 9de458b commit 582d310
Show file tree
Hide file tree
Showing 6 changed files with 106 additions and 1 deletion.
14 changes: 14 additions & 0 deletions doc/PLUGINS.md
Original file line number Diff line number Diff line change
Expand Up @@ -873,6 +873,20 @@ current accounts (`account_id` matches the `account_id` emitted from
}
```

### `block_processed`

Emitted after each block is received from bitcoind, either during the initial sync or
throughout the node's life as new blocks appear.

```json
{
"block_processed": {
"hash": "000000000000000000034bdb3c01652a0aa8f63d32f949313d55af2509f9d245",
"height": 753304
}
}
```

### `openchannel_peer_sigs`

When opening a channel with a peer using the collaborative transaction protocol
Expand Down
7 changes: 6 additions & 1 deletion lightningd/chaintopology.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <lightningd/jsonrpc.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/notification.h>
#include <math.h>
#include <wallet/txfilter.h>

Expand Down Expand Up @@ -818,9 +819,13 @@ static void get_new_block(struct bitcoind *bitcoind,
/* Unexpected predecessor? Free predecessor, refetch it. */
if (!bitcoin_blkid_eq(&topo->tip->blkid, &blk->hdr.prev_hash))
remove_tip(topo);
else
else {
add_tip(topo, new_block(topo, blk, topo->tip->height + 1));

/* tell plugins a new block was processed */
notify_block_processed(topo->ld, topo->tip);
}

/* Try for next one. */
try_extend_tip(topo);
}
Expand Down
27 changes: 27 additions & 0 deletions lightningd/notification.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include <common/configdir.h>
#include <common/type_to_string.h>
#include <lightningd/channel.h>
#include <lightningd/chaintopology.h>
#include <lightningd/coin_mvts.h>
#include <lightningd/notification.h>

Expand Down Expand Up @@ -580,6 +581,32 @@ void notify_balance_snapshot(struct lightningd *ld,
plugins_notify(ld->plugins, take(n));
}

static void block_processed_notification_serialize(struct json_stream *stream,
struct block *block)
{
json_object_start(stream, "block");
json_add_string(stream, "hash",
type_to_string(tmpctx, struct bitcoin_blkid, &block->blkid));
json_add_u32(stream, "height", block->height);
json_object_end(stream);
}

REGISTER_NOTIFICATION(block_processed,
block_processed_notification_serialize);

void notify_block_processed(struct lightningd *ld,
const struct block *block)
{
void (*serialize)(struct json_stream *,
const struct block *block) = block_processed_notification_gen.serialize;

struct jsonrpc_notification *n =
jsonrpc_notification_start(NULL, "block_processed");
serialize(n->stream, block);
jsonrpc_notification_end(n);
plugins_notify(ld->plugins, take(n));
}

static void openchannel_peer_sigs_serialize(struct json_stream *stream,
const struct channel_id *cid,
const struct wally_psbt *psbt)
Expand Down
4 changes: 4 additions & 0 deletions lightningd/notification.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#define LIGHTNING_LIGHTNINGD_NOTIFICATION_H
#include "config.h"
#include <common/coin_mvt.h>
#include <lightningd/chaintopology.h>
#include <lightningd/pay.h>
#include <lightningd/plugin.h>

Expand Down Expand Up @@ -86,6 +87,9 @@ void notify_coin_mvt(struct lightningd *ld,
void notify_balance_snapshot(struct lightningd *ld,
const struct balance_snapshot *snap);

void notify_block_processed(struct lightningd *ld,
const struct block *block);

void notify_openchannel_peer_sigs(struct lightningd *ld,
const struct channel_id *cid,
const struct wally_psbt *psbt);
Expand Down
22 changes: 22 additions & 0 deletions tests/plugins/block_processed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
#!/usr/bin/env python3

from pyln.client import Plugin


plugin = Plugin()

blocks_catched = []


@plugin.subscribe("block_processed")
def notify_block_processed(plugin, block, **kwargs):
global blocks_catched
blocks_catched.append(block["height"])


@plugin.method("blockscatched")
def return_moves(plugin):
return blocks_catched


plugin.run()
33 changes: 33 additions & 0 deletions tests/test_plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2904,3 +2904,36 @@ def test_commando_badrune(node_factory):
l1.rpc.decode(base64.urlsafe_b64encode(modrune).decode('utf8'))
except RpcError:
pass


def test_block_processed_notifications(node_factory, bitcoind):
"""Test if a plugin gets notifications when a new block is found"""
base = bitcoind.rpc.getblockchaininfo()["blocks"]
plugin = [
os.path.join(os.getcwd(), "tests/plugins/block_processed.py"),
]
l1 = node_factory.get_node(options={"plugin": plugin})
ret = l1.rpc.call("blockscatched")
assert len(ret) == 1 and ret[0] == base + 0

bitcoind.generate_block(2)
sync_blockheight(bitcoind, [l1])
ret = l1.rpc.call("blockscatched")
assert len(ret) == 3 and ret[0] == base + 0 and ret[2] == base + 2

l2 = node_factory.get_node(options={"plugin": plugin})
ret = l2.rpc.call("blockscatched")
assert len(ret) == 1 and ret[0] == base + 2

l2.stop()
next_l2_base = bitcoind.rpc.getblockchaininfo()["blocks"]

bitcoind.generate_block(2)
sync_blockheight(bitcoind, [l1])
ret = l1.rpc.call("blockscatched")
assert len(ret) == 5 and ret[4] == base + 4

l2.start()
sync_blockheight(bitcoind, [l2])
ret = l2.rpc.call("blockscatched")
assert len(ret) == 3 and ret[1] == next_l2_base + 1 and ret[2] == next_l2_base + 2

0 comments on commit 582d310

Please sign in to comment.