mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
waitinvoice: RPC call for processing incoming invoices.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
27715f7732
commit
c83fb1a2dd
@ -7,6 +7,11 @@
|
|||||||
#include <ccan/tal/str/str.h>
|
#include <ccan/tal/str/str.h>
|
||||||
#include <sodium/randombytes.h>
|
#include <sodium/randombytes.h>
|
||||||
|
|
||||||
|
struct invoice_waiter {
|
||||||
|
struct list_node list;
|
||||||
|
struct command *cmd;
|
||||||
|
};
|
||||||
|
|
||||||
static struct invoice *find_inv(const struct list_head *list,
|
static struct invoice *find_inv(const struct list_head *list,
|
||||||
const struct sha256 *rhash)
|
const struct sha256 *rhash)
|
||||||
{
|
{
|
||||||
@ -65,12 +70,33 @@ void invoice_add(struct lightningd_state *dstate,
|
|||||||
list_add(&dstate->unpaid, &invoice->list);
|
list_add(&dstate->unpaid, &invoice->list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void tell_waiter(struct command *cmd, const struct invoice *paid)
|
||||||
|
{
|
||||||
|
struct json_result *response = new_json_result(cmd);
|
||||||
|
|
||||||
|
json_object_start(response, NULL);
|
||||||
|
json_add_string(response, "label", paid->label);
|
||||||
|
json_add_hex(response, "rhash", &paid->rhash, sizeof(paid->rhash));
|
||||||
|
json_add_u64(response, "msatoshi", paid->msatoshi);
|
||||||
|
json_object_end(response);
|
||||||
|
command_success(cmd, response);
|
||||||
|
}
|
||||||
|
|
||||||
bool resolve_invoice(struct lightningd_state *dstate,
|
bool resolve_invoice(struct lightningd_state *dstate,
|
||||||
struct invoice *invoice)
|
struct invoice *invoice)
|
||||||
{
|
{
|
||||||
|
struct invoice_waiter *w;
|
||||||
|
|
||||||
invoice->paid_num = ++dstate->invoices_completed;
|
invoice->paid_num = ++dstate->invoices_completed;
|
||||||
list_del_from(&dstate->unpaid, &invoice->list);
|
list_del_from(&dstate->unpaid, &invoice->list);
|
||||||
list_add_tail(&dstate->paid, &invoice->list);
|
list_add_tail(&dstate->paid, &invoice->list);
|
||||||
|
|
||||||
|
/* Tell all the waiters about the new paid invoice */
|
||||||
|
while ((w = list_pop(&dstate->invoice_waiters,
|
||||||
|
struct invoice_waiter,
|
||||||
|
list)) != NULL)
|
||||||
|
tell_waiter(w->cmd, invoice);
|
||||||
|
|
||||||
return db_resolve_invoice(dstate, invoice->label, invoice->paid_num);
|
return db_resolve_invoice(dstate, invoice->label, invoice->paid_num);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,3 +273,50 @@ const struct json_command delinvoice_command = {
|
|||||||
"Returns {label}, {rhash} and {msatoshi} on success. "
|
"Returns {label}, {rhash} and {msatoshi} on success. "
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void json_waitinvoice(struct command *cmd,
|
||||||
|
const char *buffer, const jsmntok_t *params)
|
||||||
|
{
|
||||||
|
struct invoice *i;
|
||||||
|
jsmntok_t *labeltok;
|
||||||
|
const char *label = NULL;
|
||||||
|
struct invoice_waiter *w;
|
||||||
|
|
||||||
|
if (!json_get_params(buffer, params,
|
||||||
|
"?label", &labeltok,
|
||||||
|
NULL)) {
|
||||||
|
command_fail(cmd, "Invalid arguments");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!labeltok)
|
||||||
|
i = list_top(&cmd->dstate->paid, struct invoice, list);
|
||||||
|
else {
|
||||||
|
label = tal_strndup(cmd, buffer + labeltok->start,
|
||||||
|
labeltok->end - labeltok->start);
|
||||||
|
i = find_invoice_by_label(&cmd->dstate->paid, label);
|
||||||
|
if (!i) {
|
||||||
|
command_fail(cmd, "Label not found");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
i = list_next(&cmd->dstate->paid, i, list);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we found one, return it. */
|
||||||
|
if (i) {
|
||||||
|
tell_waiter(cmd, i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Otherwise, wait. */
|
||||||
|
/* FIXME: Better to use io_wait directly? */
|
||||||
|
w = tal(cmd, struct invoice_waiter);
|
||||||
|
w->cmd = cmd;
|
||||||
|
list_add_tail(&cmd->dstate->invoice_waiters, &w->list);
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct json_command waitinvoice_command = {
|
||||||
|
"waitinvoice",
|
||||||
|
json_waitinvoice,
|
||||||
|
"Wait for the next invoice to be paid, after {label} (if supplied)))",
|
||||||
|
"Returns {label}, {rhash} and {msatoshi} on success. "
|
||||||
|
};
|
||||||
|
@ -292,6 +292,7 @@ static const struct json_command *cmdlist[] = {
|
|||||||
&invoice_command,
|
&invoice_command,
|
||||||
&listinvoice_command,
|
&listinvoice_command,
|
||||||
&delinvoice_command,
|
&delinvoice_command,
|
||||||
|
&waitinvoice_command,
|
||||||
&getroute_command,
|
&getroute_command,
|
||||||
&sendpay_command,
|
&sendpay_command,
|
||||||
&feerate_command,
|
&feerate_command,
|
||||||
|
@ -74,6 +74,7 @@ extern const struct json_command output_command;
|
|||||||
extern const struct json_command invoice_command;
|
extern const struct json_command invoice_command;
|
||||||
extern const struct json_command listinvoice_command;
|
extern const struct json_command listinvoice_command;
|
||||||
extern const struct json_command delinvoice_command;
|
extern const struct json_command delinvoice_command;
|
||||||
|
extern const struct json_command waitinvoice_command;
|
||||||
extern const struct json_command add_route_command;
|
extern const struct json_command add_route_command;
|
||||||
extern const struct json_command routefail_command;
|
extern const struct json_command routefail_command;
|
||||||
extern const struct json_command getroute_command;
|
extern const struct json_command getroute_command;
|
||||||
|
@ -258,6 +258,7 @@ static struct lightningd_state *lightningd_state(void)
|
|||||||
list_head_init(&dstate->unpaid);
|
list_head_init(&dstate->unpaid);
|
||||||
list_head_init(&dstate->paid);
|
list_head_init(&dstate->paid);
|
||||||
dstate->invoices_completed = 0;
|
dstate->invoices_completed = 0;
|
||||||
|
list_head_init(&dstate->invoice_waiters);
|
||||||
list_head_init(&dstate->addresses);
|
list_head_init(&dstate->addresses);
|
||||||
dstate->dev_never_routefail = false;
|
dstate->dev_never_routefail = false;
|
||||||
dstate->bitcoin_req_running = false;
|
dstate->bitcoin_req_running = false;
|
||||||
|
@ -113,6 +113,8 @@ struct lightningd_state {
|
|||||||
/* Payments for r values we know about. */
|
/* Payments for r values we know about. */
|
||||||
struct list_head paid, unpaid;
|
struct list_head paid, unpaid;
|
||||||
u64 invoices_completed;
|
u64 invoices_completed;
|
||||||
|
/* Waiting for new invoices to be paid. */
|
||||||
|
struct list_head invoice_waiters;
|
||||||
|
|
||||||
/* All known nodes. */
|
/* All known nodes. */
|
||||||
struct node_map *nodes;
|
struct node_map *nodes;
|
||||||
|
@ -1077,6 +1077,8 @@ if [ ! -n "$MANUALCOMMIT" ]; then
|
|||||||
|
|
||||||
[ "`lcli3 listinvoice RHASH5 | tr -s '\012\011\" ' ' '`" = "{ [ { label : RHASH5 , rhash : $RHASH5 , msatoshi : $HTLC_AMOUNT, complete : true } ] } " ]
|
[ "`lcli3 listinvoice RHASH5 | tr -s '\012\011\" ' ' '`" = "{ [ { label : RHASH5 , rhash : $RHASH5 , msatoshi : $HTLC_AMOUNT, complete : true } ] } " ]
|
||||||
|
|
||||||
|
[ "`lcli3 waitinvoice | tr -s '\012\011\" ' ' '`" = "{ label : RHASH5 , rhash : $RHASH5 , msatoshi : $HTLC_AMOUNT } " ]
|
||||||
|
|
||||||
# Can't pay twice (try from node2)
|
# Can't pay twice (try from node2)
|
||||||
ROUTE2=`lcli2 getroute $ID3 $HTLC_AMOUNT 1`
|
ROUTE2=`lcli2 getroute $ID3 $HTLC_AMOUNT 1`
|
||||||
ROUTE2=`echo $ROUTE2 | sed 's/^{ "route" : \(.*\) }$/\1/'`
|
ROUTE2=`echo $ROUTE2 | sed 's/^{ "route" : \(.*\) }$/\1/'`
|
||||||
|
Loading…
Reference in New Issue
Block a user