Skip to content

Commit

Permalink
mark invoice as paid when we detect an on-chain payment to a fallback
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisguida committed Aug 1, 2023
1 parent 41583df commit 283f5b3
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 30 deletions.
6 changes: 4 additions & 2 deletions lightningd/chaintopology.c
Original file line number Diff line number Diff line change
Expand Up @@ -92,15 +92,17 @@ static void filter_block_txs(struct chain_topology *topo, struct block *b)
fprintf(stderr, "CAG txfilter_match found %s\n", fmt_bitcoin_txid(tmpctx, &txid));
size_t k;
wallet_extract_owned_outputs(topo->bitcoind->ld->wallet,
tx->wtx, is_coinbase, &b->height, &owned);
tx->wtx, is_coinbase, &b->height, &owned);
wallet_transaction_add(topo->ld->wallet, tx->wtx,
b->height, i);
// invoice_check_onchain_payment(tx);
for (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;
fprintf(stderr, "CAG txfilter_scriptpubkey_matches found for script %s\n", tal_hex(tmpctx, oscript));
invoice_check_onchain_payment(topo->ld->wallet->invoices, oscript, bitcoin_tx_output_get_amount(tx, k));
bitcoin_tx_output_get_amount_sat(tx, k, &amount);
invoice_check_onchain_payment(topo->ld, oscript, amount);
}
}

Expand Down
2 changes: 1 addition & 1 deletion lightningd/htlc_set.c
Original file line number Diff line number Diff line change
Expand Up @@ -206,7 +206,7 @@ void htlc_set_add(struct lightningd *ld,
if (amount_msat_greater_eq(set->so_far, total_msat)) {
/* Disable timer now, in case invoice_hook is slow! */
tal_free(set->timeout);
invoice_try_pay(ld, set, details);
invoice_try_pay(ld, set, details, set->so_far);
return;
}

Expand Down
58 changes: 34 additions & 24 deletions lightningd/invoice.c
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,8 @@ invoice_payment_serialize(struct invoice_payment_hook_payload *payload,
type_to_string(tmpctx, struct amount_msat,
&payload->msat));
#ifdef DEVELOPER
invoice_payment_add_tlvs(stream, payload->set);
if (payload->set)
invoice_payment_add_tlvs(stream, payload->set);
#endif
json_object_end(stream); /* .payment */
}
Expand Down Expand Up @@ -333,8 +334,9 @@ invoice_payment_hooks_done(struct invoice_payment_hook_payload *payload STEALS)
log_info(ld->log, "Resolved invoice '%s' with amount %s in %zu htlcs",
payload->label->s,
type_to_string(tmpctx, struct amount_msat, &payload->msat),
tal_count(payload->set->htlcs));
htlc_set_fulfill(payload->set, &payload->preimage);
payload->set ? tal_count(payload->set->htlcs) : 0);
if (payload->set)
htlc_set_fulfill(payload->set, &payload->preimage);

notify_invoice_payment(ld, payload->msat, payload->preimage,
payload->label);
Expand All @@ -349,18 +351,20 @@ invoice_payment_deserialize(struct invoice_payment_hook_payload *payload,
const u8 *failmsg;

/* If peer dies or something, this can happen. */
if (!payload->set) {
log_debug(ld->log, "invoice '%s' paying htlc_in has gone!",
payload->label->s);
return false;
}

/* Did we have a hook result? */
failmsg = hook_gives_failmsg(NULL, ld,
payload->set->htlcs[0], buffer, toks);
if (failmsg) {
htlc_set_fail(payload->set, take(failmsg));
return false;
// if (!payload->set) {
// log_debug(ld->log, "invoice '%s' paying htlc_in has gone!",
// payload->label->s);
// return false;
// }

if (payload->set) {
/* Did we have a hook result? */
failmsg = hook_gives_failmsg(NULL, ld,
payload->set->htlcs[0], buffer, toks);
if (failmsg) {
htlc_set_fail(payload->set, take(failmsg));
return false;
}
}
return true;
}
Expand Down Expand Up @@ -470,18 +474,21 @@ invoice_check_payment(const tal_t *ctx,

void invoice_try_pay(struct lightningd *ld,
struct htlc_set *set,
const struct invoice_details *details)
const struct invoice_details *details,
struct amount_msat msat)
{
struct invoice_payment_hook_payload *payload;

payload = tal(NULL, struct invoice_payment_hook_payload);
payload->ld = ld;
payload->label = tal_steal(payload, details->label);
payload->msat = set->so_far;
payload->preimage = details->r;
payload->msat = msat;
payload->set = set;
tal_add_destructor2(set, invoice_payload_remove_set, payload);

// set is NULL if invoice is being paid on-chain
if (payload->set)
tal_add_destructor2(set, invoice_payload_remove_set, payload);
plugin_hook_call_invoice_payment(ld, NULL, payload);
}

Expand Down Expand Up @@ -963,30 +970,33 @@ static void listincoming_done(const char *buffer,
db_commit_transaction(ld->wallet->db);
}

void invoice_check_onchain_payment(struct invoices *invoices,
const u8 *scriptPubKey, struct amount_asset msat)
void invoice_check_onchain_payment(struct lightningd *ld,
const u8 *scriptPubKey, struct amount_sat sat)
{
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? */
fprintf(stderr, "CAG invoice_check_onchain_payment\n");
if(!invoices_find_by_fallback_script(invoices, &inv_dbid, scriptPubKey)) {
if(!invoices_find_by_fallback_script(ld->wallet->invoices, &inv_dbid, scriptPubKey)) {
fprintf(stderr, "CAG invoice_check_onchain_payment fallback script not found\n");
return;
}

fprintf(stderr, "CAG found fallback script in invoice_fallbacks!\n");
details = invoices_get_details(tmpctx, invoices, inv_dbid);
details = invoices_get_details(tmpctx, ld->wallet->invoices, inv_dbid);

if (details->msat->millisatoshis < msat.value) {
if (amount_msat_less(msat, *details->msat)) {
fprintf(stderr, "CAG invoice_check_onchain_payment payment too low\n");
// notify_underpaid_onchain_invoice();
return;
}

fprintf(stderr, "CAG invoice_check_onchain_payment successfully paid!\n");

// invoice_try_pay(...);
invoice_try_pay(ld, NULL, details, msat);
}


Expand Down
8 changes: 5 additions & 3 deletions lightningd/invoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,20 +68,22 @@ invoice_check_payment(const tal_t *ctx,
*
* Returns NULL if there's a problem, otherwise returns the invoice details.
*/
void invoice_check_onchain_payment(struct invoices *invoices,
const u8 *scriptPubKey, struct amount_asset msat);
void invoice_check_onchain_payment(struct lightningd *ld,
const u8 *scriptPubKey, struct amount_sat sat);

/**
* invoice_try_pay - process payment for these incoming payments.
* @ld: lightningd
* @set: the htlc_set used to pay this.
* @details: returned from successful invoice_check_payment.
* @msat: the amount of the output or htlc_set
*
* Either calls fulfill_htlc_set() or fail_htlc_set().
*/
void invoice_try_pay(struct lightningd *ld,
struct htlc_set *set,
const struct invoice_details *details);
const struct invoice_details *details,
struct amount_msat msat);

/* Simple enum -> string converter for JSON fields */
const char *invoice_status_str(enum invoice_status state);
Expand Down

0 comments on commit 283f5b3

Please sign in to comment.