From 1eb3c9d2b354e5670ed8782a2794d6e0c956ec52 Mon Sep 17 00:00:00 2001 From: Christian Decker Date: Mon, 27 Nov 2017 16:17:43 +0100 Subject: [PATCH] txfilter: Add a simple transaction filter This is mainly used to filter for transactions that may be of interest to us, i.e., whether one of our keys is the recipient. It currently does onyl simple scriptpubkey checks, but will eventually be extended to use bloomfilters and add more sophisticated checks. For now the goal is to speed up the processing of blocks during startup. Signed-off-by: Christian Decker --- lightningd/Makefile | 3 ++- lightningd/txfilter.c | 54 +++++++++++++++++++++++++++++++++++++++++++ lightningd/txfilter.h | 30 ++++++++++++++++++++++++ 3 files changed, 86 insertions(+), 1 deletion(-) create mode 100644 lightningd/txfilter.c create mode 100644 lightningd/txfilter.h diff --git a/lightningd/Makefile b/lightningd/Makefile index a5cba0fd2..de338623f 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -60,6 +60,7 @@ LIGHTNINGD_SRC := \ lightningd/peer_control.c \ lightningd/peer_htlcs.c \ lightningd/subd.c \ + lightningd/txfilter.c \ lightningd/watch.c # Source files without corresponding headers @@ -85,7 +86,7 @@ ALL_GEN_HEADERS += $(LIGHTNINGD_HEADERS_GEN) # All together in one convenient var LIGHTNINGD_HEADERS = $(LIGHTNINGD_HEADERS_NOGEN) $(LIGHTNINGD_HEADERS_GEN) $(EXTERNAL_HEADERS) $(WIRE_HEADERS) $(BITCOIN_HEADERS) $(COMMON_HEADERS) $(WALLET_LIB_HEADERS) -$(LIGHTNINGD_OBJS): $(LIGHTNINGD_HEADERS) +$(LIGHTNINGD_OBJS): $(LIGHTNINGD_HEADERS) lightningd/gen_peer_state_names.h: lightningd/peer_state.h ccan/ccan/cdump/tools/cdump-enumstr ccan/ccan/cdump/tools/cdump-enumstr lightningd/peer_state.h > $@ diff --git a/lightningd/txfilter.c b/lightningd/txfilter.c new file mode 100644 index 000000000..c0d8552ef --- /dev/null +++ b/lightningd/txfilter.c @@ -0,0 +1,54 @@ +#include "txfilter.h" + +#include +#include +#include + +struct txfilter { + u8 **scriptpubkeys; +}; + + + +struct txfilter *txfilter_new(const tal_t *ctx) +{ + struct txfilter *filter = tal(ctx, struct txfilter); + filter->scriptpubkeys = tal_arr(filter, u8*, 0); + return filter; +} + +static void txfilter_add_scriptpubkey(struct txfilter *filter, u8 *script) +{ + size_t count = tal_count(filter->scriptpubkeys); + tal_resize(&filter->scriptpubkeys, count + 1); + filter->scriptpubkeys[count] = tal_dup_arr(filter, u8, script, tal_len(script), 0); +} + +void txfilter_add_derkey(struct txfilter *filter, u8 derkey[33]) +{ + tal_t *tmpctx = tal_tmpctx(filter); + u8 *skp, *p2sh; + + skp = scriptpubkey_p2wpkh_derkey(tmpctx, derkey); + p2sh = scriptpubkey_p2sh(tmpctx, skp); + + txfilter_add_scriptpubkey(filter, take(skp)); + txfilter_add_scriptpubkey(filter, take(p2sh)); + + tal_free(tmpctx); +} + + +bool txfilter_match(const struct txfilter *filter, const struct bitcoin_tx *tx) +{ + u8 *oscript; + for (size_t i = 0; i < tal_count(tx->output); i++) { + oscript = tx->output[i].script; + + for (size_t j = 0; j < tal_count(filter->scriptpubkeys); j++) { + if (scripteq(oscript, filter->scriptpubkeys[j])) + return true; + } + } + return false; +} diff --git a/lightningd/txfilter.h b/lightningd/txfilter.h new file mode 100644 index 000000000..a28699e37 --- /dev/null +++ b/lightningd/txfilter.h @@ -0,0 +1,30 @@ +#ifndef LIGHTNING_LIGHTNINGD_TXFILTER_H +#define LIGHTNING_LIGHTNINGD_TXFILTER_H +#include "config.h" +#include +#include +#include + +struct txfilter; + +/** + * txfilter_new -- Construct and initialize a new txfilter + */ +struct txfilter *txfilter_new(const tal_t *ctx); + +/** + * txfilter_add_derkey -- Add a scriptpubkeys matching the der key to the filter + * + * This ensures that we recognize the scriptpubkeys to our keys when + * filtering transactions. If any of the outputs matches the + * scriptpubkey then the transaction is marked as a match. Adds + * scriptpubkey for both raw p2wpkh and p2wpkh wrapped in p2sh. + */ +void txfilter_add_derkey(struct txfilter *filter, u8 derkey[33]); + +/** + * txfilter_match -- Check whether the tx matches the filter + */ +bool txfilter_match(const struct txfilter *filter, const struct bitcoin_tx *tx); + +#endif /* LIGHTNING_LIGHTNINGD_TXFILTER_H */