diff --git a/channeld/channeld.c b/channeld/channeld.c index 2bd331a4a..a4229c9d0 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include diff --git a/lightningd/Makefile b/lightningd/Makefile index 4419d5f54..51c69531e 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -25,6 +25,7 @@ LIGHTNINGD_COMMON_OBJS := \ common/blinding.o \ common/bolt11.o \ common/channel_config.o \ + common/coin_mvt.o \ common/configdir.o \ common/crypto_state.o \ common/daemon.o \ @@ -78,6 +79,7 @@ LIGHTNINGD_SRC := \ lightningd/channel.c \ lightningd/channel_control.c \ lightningd/closing_control.c \ + lightningd/coin_mvts.c \ lightningd/connect_control.c \ lightningd/onion_message.c \ lightningd/gossip_control.c \ diff --git a/lightningd/coin_mvts.c b/lightningd/coin_mvts.c new file mode 100644 index 000000000..04441a04a --- /dev/null +++ b/lightningd/coin_mvts.c @@ -0,0 +1,26 @@ +#include +#include + +void notify_channel_mvt(struct lightningd *ld, const struct channel_coin_mvt *mvt) +{ + const struct coin_mvt *cm; + u32 timestamp; + + timestamp = time_now().ts.tv_sec; + cm = finalize_channel_mvt(mvt, mvt, timestamp, + get_block_height(ld->topology), + &ld->id); + notify_coin_mvt(ld, cm); +} + +void notify_chain_mvt(struct lightningd *ld, const struct chain_coin_mvt *mvt) +{ + const struct coin_mvt *cm; + u32 timestamp; + + timestamp = time_now().ts.tv_sec; + cm = finalize_chain_mvt(mvt, mvt, timestamp, + get_block_height(ld->topology), + &ld->id); + notify_coin_mvt(ld, cm); +} diff --git a/lightningd/coin_mvts.h b/lightningd/coin_mvts.h new file mode 100644 index 000000000..d95781117 --- /dev/null +++ b/lightningd/coin_mvts.h @@ -0,0 +1,10 @@ +#ifndef LIGHTNING_LIGHTNINGD_COIN_MVTS_H +#define LIGHTNING_LIGHTNINGD_COIN_MVTS_H +#include "config.h" + +#include +#include + +void notify_channel_mvt(struct lightningd *ld, const struct channel_coin_mvt *mvt); +void notify_chain_mvt(struct lightningd *ld, const struct chain_coin_mvt *mvt); +#endif /* LIGHTNING_LIGHTNINGD_COIN_MVTS_H */ diff --git a/lightningd/notification.c b/lightningd/notification.c index 59d5bde9d..7f034746b 100644 --- a/lightningd/notification.c +++ b/lightningd/notification.c @@ -345,3 +345,72 @@ void notify_sendpay_failure(struct lightningd *ld, jsonrpc_notification_end(n); plugins_notify(ld->plugins, take(n)); } + +static void json_mvt_id(struct json_stream *stream, enum mvt_type mvt_type, + struct mvt_id *id) +{ + switch (mvt_type) { + case CHAIN_MVT: + /* some 'journal entries' don't have a txid */ + if (id->tx_txid) + json_add_string(stream, "txid", + type_to_string(tmpctx, struct bitcoin_txid, + id->tx_txid)); + /* some chain ledger entries aren't associated with a utxo + * e.g. journal updates (due to penalty/state loss) and + * chain_fee entries */ + if (id->output_txid) { + json_add_string(stream, "utxo_txid", + type_to_string(tmpctx, struct bitcoin_txid, + id->output_txid)); + json_add_u32(stream, "vout", id->vout); + } + + /* on-chain htlcs include a payment hash */ + if (id->payment_hash) + json_add_sha256(stream, "payment_hash", id->payment_hash); + return; + case CHANNEL_MVT: + json_add_sha256(stream, "payment_hash", id->payment_hash); + if (id->part_id) + json_add_u64(stream, "part_id", id->part_id); + return; + } + abort(); +} + +static void coin_movement_notification_serialize(struct json_stream *stream, + struct coin_mvt *mvt) +{ + json_object_start(stream, "coin_movement"); + json_add_num(stream, "version", mvt->version); + json_add_node_id(stream, "node_id", mvt->node_id); + json_add_u64(stream, "movement_idx", mvt->counter); + json_add_string(stream, "type", mvt_type_str(mvt->type)); + json_add_string(stream, "account_id", mvt->account_id); + json_mvt_id(stream, mvt->type, &mvt->id); + json_add_amount_msat_only(stream, "credit", mvt->credit); + json_add_amount_msat_only(stream, "debit", mvt->debit); + json_add_string(stream, "tag", mvt_tag_str(mvt->tag)); + json_add_u32(stream, "blockheight", mvt->blockheight); + json_add_u32(stream, "timestamp", mvt->timestamp); + json_add_string(stream, "unit_of_account", mvt_unit_str(mvt->unit)); + + json_object_end(stream); +} + +REGISTER_NOTIFICATION(coin_movement, + coin_movement_notification_serialize); + +void notify_coin_mvt(struct lightningd *ld, + const struct coin_mvt *mvt) +{ + void (*serialize)(struct json_stream *, + const struct coin_mvt *) = coin_movement_notification_gen.serialize; + + struct jsonrpc_notification *n = + jsonrpc_notification_start(NULL, "coin_movement"); + serialize(n->stream, mvt); + jsonrpc_notification_end(n); + plugins_notify(ld->plugins, take(n)); +} diff --git a/lightningd/notification.h b/lightningd/notification.h index 4a7914f5f..62d6069c4 100644 --- a/lightningd/notification.h +++ b/lightningd/notification.h @@ -7,6 +7,7 @@ #include #include #include +#include #include #include #include @@ -74,4 +75,6 @@ void notify_sendpay_failure(struct lightningd *ld, const struct routing_failure *fail, const char *errmsg); +void notify_coin_mvt(struct lightningd *ld, + const struct coin_mvt *mvt); #endif /* LIGHTNING_LIGHTNINGD_NOTIFICATION_H */