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 <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2017-11-27 16:17:43 +01:00
parent 88ecae301c
commit 1eb3c9d2b3
3 changed files with 86 additions and 1 deletions

View File

@ -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 > $@

54
lightningd/txfilter.c Normal file
View File

@ -0,0 +1,54 @@
#include "txfilter.h"
#include <bitcoin/script.h>
#include <ccan/crypto/ripemd160/ripemd160.h>
#include <common/utils.h>
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;
}

30
lightningd/txfilter.h Normal file
View File

@ -0,0 +1,30 @@
#ifndef LIGHTNING_LIGHTNINGD_TXFILTER_H
#define LIGHTNING_LIGHTNINGD_TXFILTER_H
#include "config.h"
#include <bitcoin/tx.h>
#include <ccan/short_types/short_types.h>
#include <ccan/tal/tal.h>
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 */