track fallbacks for invoices, pt 1

This commit is contained in:
Chris Guida 2023-10-26 14:02:13 +10:30 committed by Rusty Russell
parent 6b764c0e7c
commit cdc0bd47ff
9 changed files with 105 additions and 0 deletions

View File

@ -19,6 +19,7 @@
#include <lightningd/channel.h>
#include <lightningd/coin_mvts.h>
#include <lightningd/gossip_control.h>
#include <lightningd/invoice.h>
#include <lightningd/io_loop_with_timers.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/lightningd.h>
@ -92,6 +93,19 @@ static void filter_block_txs(struct chain_topology *topo, struct block *b)
tx->wtx, is_coinbase, &b->height, &owned);
wallet_transaction_add(topo->ld->wallet, tx->wtx,
b->height, i);
// invoice_check_onchain_payment(tx);
for (size_t k = 0; k < tx->wtx->num_outputs; k++) {
const u8 *oscript = bitcoin_tx_output_get_script(tmpctx, tx, k);
if (txfilter_scriptpubkey_matches(topo->bitcoind->ld->owned_txfilter, oscript)) {
struct amount_sat amount;
struct bitcoin_outpoint outpoint;
outpoint.txid = txid;
outpoint.n = k;
bitcoin_tx_output_get_amount_sat(tx, k, &amount);
invoice_check_onchain_payment(topo->ld, oscript, amount, &outpoint);
}
}
}
/* We did spends first, in case that tells us to watch tx. */

View File

@ -945,6 +945,31 @@ static void listincoming_done(const char *buffer,
warning_private_unused);
}
void invoice_check_onchain_payment(struct lightningd *ld,
const u8 *scriptPubKey,
struct amount_sat sat,
const struct bitcoin_outpoint *outpoint)
{
u64 inv_dbid;
const struct invoice_details *details;
struct amount_msat msat;
if (!amount_sat_to_msat(&msat, sat))
abort();
/* Does this onchain payment fulfill an invoice? */
if(!invoices_find_by_fallback_script(ld->wallet->invoices, &inv_dbid, scriptPubKey)) {
return;
}
details = invoices_get_details(tmpctx, ld->wallet->invoices, inv_dbid);
if (amount_msat_less(msat, *details->msat)) {
// notify_underpaid_onchain_invoice();
return;
}
// invoice_try_pay(...);
}
/* Since this is a dev-only option, we will crash if dev-routes is not
* an array-of-arrays-of-correct-items. */
static struct route_info *unpack_route(const tal_t *ctx,

View File

@ -62,6 +62,18 @@ invoice_check_payment(const tal_t *ctx,
const struct secret *payment_secret,
const char **err);
/**
* invoice_check_onchain_payment - check if this on-chain payment would be valid
* @ld: the lightning context
* @scriptPubKey: fallback script with which to search for invoices
* @sat: output amount
* @outpoint: the outpoint which paid it.
*/
void invoice_check_onchain_payment(struct lightningd *ld,
const u8 *scriptPubKey,
struct amount_sat sat,
const struct bitcoin_outpoint *outpoint);
/**
* invoice_try_pay - process payment for these incoming payments.
* @ld: lightningd

View File

@ -403,6 +403,11 @@ bool invoices_delete_description(struct invoices *invoices UNNEEDED,
void invoices_delete_expired(struct invoices *invoices UNNEEDED,
u64 max_expiry_time UNNEEDED)
{ fprintf(stderr, "invoices_delete_expired called!\n"); abort(); }
/* Generated stub for invoices_find_by_fallback_script */
bool invoices_find_by_fallback_script(struct invoices *invoices UNNEEDED,
u64 *inv_dbid UNNEEDED,
const u8 *scriptPubkey UNNEEDED)
{ fprintf(stderr, "invoices_find_by_fallback_script called!\n"); abort(); }
/* Generated stub for invoices_find_by_label */
bool invoices_find_by_label(struct invoices *invoices UNNEEDED,
u64 *inv_dbid UNNEEDED,

View File

@ -21,6 +21,9 @@
* - HTLC timed out
* - HTLC spent
*
* - Payments to invoice fallback addresses:
* - Reached a given depth.
*
* We do this by adding the P2SH address to the wallet, and then querying
* that using listtransactions.
*

View File

@ -371,6 +371,28 @@ bool invoices_find_by_rhash(struct invoices *invoices,
}
}
bool invoices_find_by_fallback_script(struct invoices *invoices,
u64 *inv_dbid,
const u8 *scriptPubkey)
{
struct db_stmt *stmt;
stmt = db_prepare_v2(invoices->wallet->db, SQL("SELECT invoice_id"
" FROM invoice_fallbacks"
" WHERE scriptpubkey = ?;"));
db_bind_talarr(stmt, scriptPubkey);
db_query_prepared(stmt);
if (!db_step(stmt)) {
tal_free(stmt);
return false;
} else {
*inv_dbid = db_col_u64(stmt, "invoice_id");
tal_free(stmt);
return true;
}
}
bool invoices_find_unpaid(struct invoices *invoices,
u64 *inv_dbid,
const struct sha256 *rhash)

View File

@ -89,6 +89,20 @@ bool invoices_find_by_label(struct invoices *invoices,
bool invoices_find_by_rhash(struct invoices *invoices,
u64 *inv_dbid,
const struct sha256 *rhash);
/**
* invoices_find_by_fallback_script - Search for an invoice by
* scriptpubkey in invoice_fallbacks child table
*
* @invoices - the invoice handler.
* @inv_dbid - pointer to location to put the found dbid in
* @scriptPubKey - the scriptpubkey to search for.
*
* Returns false if no invoice with that scriptpubkey exists.
* Returns true if found.
*/
bool invoices_find_by_fallback_script(struct invoices *invoices,
u64 *inv_dbid,
const u8 *scriptPubkey);
/**
* invoices_find_unpaid - Search for an unpaid, unexpired invoice by

View File

@ -95,6 +95,11 @@ bool txfilter_match(const struct txfilter *filter, const struct bitcoin_tx *tx)
return false;
}
bool txfilter_scriptpubkey_matches(const struct txfilter *filter, const u8 *scriptPubKey)
{
return scriptpubkeyset_get(&filter->scriptpubkeyset, scriptPubKey) != NULL;
}
void outpointfilter_add(struct outpointfilter *of,
const struct bitcoin_outpoint *outpoint)
{

View File

@ -32,6 +32,11 @@ void txfilter_add_derkey(struct txfilter *filter,
*/
bool txfilter_match(const struct txfilter *filter, const struct bitcoin_tx *tx);
/**
* txfilter_matches -- Check whether the scriptpubkey matches the filter
*/
bool txfilter_scriptpubkey_matches(const struct txfilter *filter, const u8 *scriptPubKey);
/**
* txfilter_add_scriptpubkey -- Add a serialized scriptpubkey to the filter
*/