@ -14,19 +14,19 @@ struct invoice_waiter {
struct invoices {
/* Payments for r values we know about. */
struct list_head paid , unpaid ;
u64 invoices_completed ;
struct list_head invlist ;
/* Waiting for new invoices to be paid. */
struct list_head invoice_waiters ;
} ;
static struct invoice * find_inv ( const struct list_head * list ,
const struct sha256 * rhash )
const struct sha256 * rhash ,
enum invoice_status state )
{
struct invoice * i ;
list_for_each ( list , i , list ) {
if ( structeq ( rhash , & i - > rhash ) )
if ( structeq ( rhash , & i - > rhash ) & & i - > state = = state )
return i ;
}
return NULL ;
@ -34,13 +34,13 @@ static struct invoice *find_inv(const struct list_head *list,
struct invoice * find_unpaid ( struct invoices * invs , const struct sha256 * rhash )
{
return find_inv ( & invs - > unpaid , rhash ) ;
return find_inv ( & invs - > invlist , rhash , UNPAID ) ;
}
static struct invoice * find_paid ( struct invoices * invs ,
const struct sha256 * rhash )
{
return find_inv ( & invs - > paid , rhash ) ;
return find_inv ( & invs - > invlist , rhash , PAID ) ;
}
static struct invoice * find_invoice_by_label ( const struct list_head * list ,
@ -59,31 +59,24 @@ void invoice_add(struct invoices *invs,
const struct preimage * r ,
u64 msatoshi ,
const char * label ,
u64 paid_num )
enum invoice_status state )
{
struct invoice * invoice = tal ( invs , struct invoice ) ;
invoice - > msatoshi = msatoshi ;
invoice - > r = * r ;
invoice - > paid_num = paid_num ;
invoice - > state = state ;
invoice - > label = tal_strdup ( invoice , label ) ;
sha256 ( & invoice - > rhash , invoice - > r . r , sizeof ( invoice - > r . r ) ) ;
if ( paid_num ) {
list_add ( & invs - > paid , & invoice - > list ) ;
if ( paid_num > invs - > invoices_completed )
invs - > invoices_completed = paid_num ;
} else
list_add ( & invs - > unpaid , & invoice - > list ) ;
list_add ( & invs - > invlist , & invoice - > list ) ;
}
struct invoices * invoices_init ( const tal_t * ctx )
{
struct invoices * invs = tal ( ctx , struct invoices ) ;
list_head_init ( & invs - > unpaid ) ;
list_head_init ( & invs - > paid ) ;
invs - > invoices_completed = 0 ;
list_head_init ( & invs - > invlist ) ;
list_head_init ( & invs - > invoice_waiters ) ;
return invs ;
@ -97,13 +90,14 @@ static void tell_waiter(struct command *cmd, const struct invoice *paid)
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_add_bool ( response , " complete " , paid - > state = = PAID ) ;
json_object_end ( response ) ;
command_success ( cmd , response ) ;
}
/* UNIFICATION FIXME */
void db_resolve_invoice ( struct lightningd * ld ,
const char * label , u64 paid_num ) ;
const char * label ) ;
bool db_new_invoice ( struct lightningd * ld ,
u64 msatoshi ,
const char * label ,
@ -115,9 +109,7 @@ void resolve_invoice(struct lightningd *ld, struct invoice *invoice)
struct invoice_waiter * w ;
struct invoices * invs = ld - > invoices ;
invoice - > paid_num = + + invs - > invoices_completed ;
list_del_from ( & invs - > unpaid , & invoice - > list ) ;
list_add_tail ( & invs - > paid , & invoice - > list ) ;
invoice - > state = PAID ;
/* Tell all the waiters about the new paid invoice */
while ( ( w = list_pop ( & invs - > invoice_waiters ,
@ -125,7 +117,7 @@ void resolve_invoice(struct lightningd *ld, struct invoice *invoice)
list ) ) ! = NULL )
tell_waiter ( w - > cmd , invoice ) ;
db_resolve_invoice ( ld , invoice - > label , invoice - > paid_num ) ;
db_resolve_invoice ( ld , invoice - > label ) ;
}
static void json_invoice ( struct command * cmd ,
@ -146,6 +138,7 @@ static void json_invoice(struct command *cmd,
}
invoice = tal ( cmd , struct invoice ) ;
invoice - > state = UNPAID ;
if ( r ) {
if ( ! hex_decode ( buffer + r - > start , r - > end - r - > start ,
invoice - > r . r , sizeof ( invoice - > r . r ) ) ) {
@ -175,8 +168,7 @@ static void json_invoice(struct command *cmd,
invoice - > label = tal_strndup ( invoice , buffer + label - > start ,
label - > end - label - > start ) ;
if ( find_invoice_by_label ( & invs - > paid , invoice - > label )
| | find_invoice_by_label ( & invs - > unpaid , invoice - > label ) ) {
if ( find_invoice_by_label ( & invs - > invlist , invoice - > label ) ) {
command_fail ( cmd , " Duplicate label '%s' " , invoice - > label ) ;
return ;
}
@ -185,7 +177,6 @@ static void json_invoice(struct command *cmd,
INVOICE_MAX_LABEL_LEN ) ;
return ;
}
invoice - > paid_num = 0 ;
if ( ! db_new_invoice ( cmd - > ld , invoice - > msatoshi , invoice - > label ,
& invoice - > r ) ) {
@ -194,7 +185,7 @@ static void json_invoice(struct command *cmd,
}
/* OK, connect it to main state, respond with hash */
tal_steal ( invs , invoice ) ;
list_add ( & invs - > unpaid , & invoice - > list ) ;
list_add ( & invs - > invlist , & invoice - > list ) ;
json_object_start ( response , NULL ) ;
json_add_hex ( response , " rhash " ,
@ -228,7 +219,7 @@ static void json_add_invoices(struct json_result *response,
json_add_string ( response , " label " , i - > label ) ;
json_add_hex ( response , " rhash " , & i - > rhash , sizeof ( i - > rhash ) ) ;
json_add_u64 ( response , " msatoshi " , i - > msatoshi ) ;
json_add_bool ( response , " complete " , i - > paid_num ! = 0 ) ;
json_add_bool ( response , " complete " , i - > state = = PAID ) ;
json_object_end ( response ) ;
}
}
@ -249,8 +240,7 @@ static void json_listinvoice(struct command *cmd,
json_array_start ( response , NULL ) ;
json_add_invoices ( response , & invs - > paid , buffer , label ) ;
json_add_invoices ( response , & invs - > unpaid , buffer , label ) ;
json_add_invoices ( response , & invs - > invlist , buffer , label ) ;
json_array_end ( response ) ;
command_success ( cmd , response ) ;
}
@ -281,7 +271,7 @@ static void json_delinvoice(struct command *cmd,
label = tal_strndup ( cmd , buffer + labeltok - > start ,
labeltok - > end - labeltok - > start ) ;
i = find_invoice_by_label ( & invs - > unpaid , label ) ;
i = find_invoice_by_label ( & invs - > invlist , label ) ;
if ( ! i ) {
command_fail ( cmd , " Unknown invoice " ) ;
return ;
@ -290,7 +280,7 @@ static void json_delinvoice(struct command *cmd,
command_fail ( cmd , " Database error " ) ;
return ;
}
list_del_from ( & invs - > unpaid , & i - > list ) ;
list_del_from ( & invs - > invlist , & i - > list ) ;
json_object_start ( response , NULL ) ;
json_add_string ( response , " label " , i - > label ) ;
@ -325,17 +315,24 @@ static void json_waitanyinvoice(struct command *cmd,
return ;
}
if ( ! labeltok )
i = list_top ( & invs - > paid , struct invoice , list ) ;
else {
if ( ! labeltok ) {
i = list_top ( & invs - > invlist , struct invoice , list ) ;
/* Advance until we find a PAID one */
while ( i & & i - > state = = UNPAID ) {
i = list_next ( & invs - > invlist , i , list ) ;
}
} else {
label = tal_strndup ( cmd , buffer + labeltok - > start ,
labeltok - > end - labeltok - > start ) ;
i = find_invoice_by_label ( & invs - > paid , label ) ;
i = find_invoice_by_label ( & invs - > invlist , label ) ;
if ( ! i ) {
command_fail ( cmd , " Label not found " ) ;
return ;
}
i = list_next ( & invs - > paid , i , list ) ;
while ( i & & i - > state = = UNPAID ) {
i = list_next ( & invs - > invlist , i , list ) ;
}
}
/* If we found one, return it. */
@ -381,23 +378,20 @@ static void json_waitinvoice(struct command *cmd,
/* Search in paid invoices, if found return immediately */
label = tal_strndup ( cmd , buffer + labeltok - > start , labeltok - > end - labeltok - > start ) ;
i = find_invoice_by_label ( & invs - > paid , label ) ;
if ( i ) {
tell_waiter ( cmd , i ) ;
return ;
}
i = find_invoice_by_label ( & invs - > invlist , label ) ;
/* No luck in paid ones? Now try the unpaid ones. */
i = find_invoice_by_label ( & invs - > unpaid , label ) ;
if ( ! i ) {
command_fail ( cmd , " Label not found " ) ;
return ;
} else if ( i - > state = = PAID ) {
tell_waiter ( cmd , i ) ;
return ;
} else {
/* There is an unpaid one matching, let's wait... */
w = tal ( cmd , struct invoice_waiter ) ;
w - > cmd = cmd ;
list_add_tail ( & invs - > invoice_waiters , & w - > list ) ;
}
/* There is an unpaid one matching, let's wait... */
w = tal ( cmd , struct invoice_waiter ) ;
w - > cmd = cmd ;
list_add_tail ( & invs - > invoice_waiters , & w - > list ) ;
}
static const struct json_command waitinvoice_command = {