@ -1,3 +1,4 @@
# include <bitcoin/preimage.h>
# include <ccan/array_size/array_size.h>
# include <plugins/libplugin.h>
# include <wire/gen_onion_wire.h>
@ -13,26 +14,58 @@ static void init(struct plugin *p, const char *buf UNUSED,
static const struct plugin_command commands [ ] = {
} ;
static struct command_result * htlc_accepted_continue ( struct command * cmd )
static struct command_result *
htlc_accepted_continue ( struct command * cmd , struct tlv_tlv_payload * payload )
{
struct json_stream * response ;
u8 * binpayload , * rawpayload ;
response = jsonrpc_stream_success ( cmd ) ;
json_add_string ( response , " result " , " continue " ) ;
if ( payload ) {
binpayload = tal_arr ( cmd , u8 , 0 ) ;
towire_tlvstream_raw ( & binpayload , payload - > fields ) ;
rawpayload = tal_arr ( cmd , u8 , 0 ) ;
towire_bigsize ( & rawpayload , tal_bytelen ( binpayload ) ) ;
towire ( & rawpayload , binpayload , tal_bytelen ( binpayload ) ) ;
json_add_string ( response , " payload " , tal_hex ( cmd , rawpayload ) ) ;
}
return command_finished ( cmd , response ) ;
}
static struct command_result * htlc_accepted_resolve ( struct command * cmd ,
char * hexpreimage )
/* Struct wrapping the information we extract from an incoming keysend
* payment */
struct keysend_in {
struct sha256 payment_hash ;
struct preimage payment_preimage ;
char * label ;
struct tlv_tlv_payload * payload ;
struct tlv_field * preimage_field ;
} ;
static struct command_result *
htlc_accepted_invoice_created ( struct command * cmd , const char * buf UNUSED ,
const jsmntok_t * result UNUSED ,
struct keysend_in * ki )
{
struct json_stream * response ;
response = jsonrpc_stream_success ( cmd ) ;
json_add_string ( response , " result " , " resolve " ) ;
json_add_string ( response , " payment_key " , hexpreimage ) ;
return command_finished ( cmd , response ) ;
int preimage_field_idx = ki - > preimage_field - ki - > payload - > fields ;
/* Remove the preimage field so `lightningd` knows how to handle
* this . */
tal_arr_remove ( & ki - > payload - > fields , preimage_field_idx ) ;
/* Finally we can resolve the payment with the preimage. */
plugin_log ( cmd - > plugin , LOG_INFORM ,
" Resolving incoming HTLC with preimage for payment_hash %s "
" provided in the onion payload. " ,
tal_hexstr ( tmpctx , & ki - > payment_hash , sizeof ( struct sha256 ) ) ) ;
return htlc_accepted_continue ( cmd , ki - > payload ) ;
}
static struct command_result * htlc_accepted_call ( struct command * cmd , const char * buf ,
const jsmntok_t * params )
static struct command_result * htlc_accepted_call ( struct command * cmd ,
const char * buf ,
const jsmntok_t * params )
{
const jsmntok_t * payloadt = json_delve ( buf , params , " .onion.payload " ) ;
const jsmntok_t * payment_hash_tok = json_delve ( buf , params , " .htlc.payment_hash " ) ;
@ -41,13 +74,15 @@ static struct command_result *htlc_accepted_call(struct command *cmd, const char
struct tlv_tlv_payload * payload ;
struct tlv_field * preimage_field = NULL ;
char * hexpreimage , * hexpaymenthash ;
struct sha256 payment_hash ;
bigsize_t s ;
bool unknown_even_type = false ;
struct tlv_field * field ;
struct keysend_in * ki ;
struct out_req * req ;
struct timeabs now = time_now ( ) ;
if ( ! payloadt )
return htlc_accepted_continue ( cmd ) ;
return htlc_accepted_continue ( cmd , NULL ) ;
rawpayload = json_tok_bin_from_hex ( cmd , buf , payloadt ) ;
max = tal_bytelen ( rawpayload ) ;
@ -55,9 +90,14 @@ static struct command_result *htlc_accepted_call(struct command *cmd, const char
s = fromwire_varint ( & rawpayload , & max ) ;
if ( s ! = max ) {
return htlc_accepted_continue ( cmd ) ;
return htlc_accepted_continue ( cmd , NULL ) ;
}
if ( ! fromwire_tlv_payload ( & rawpayload , & max , payload ) ) {
plugin_log (
cmd - > plugin , LOG_UNUSUAL , " Malformed TLV payload %.*s " ,
payloadt - > end - payloadt - > start , buf + payloadt - > start ) ;
return htlc_accepted_continue ( cmd , NULL ) ;
}
fromwire_tlv_payload ( & rawpayload , & max , payload ) ;
/* Try looking for the field that contains the preimage */
for ( int i = 0 ; i < tal_count ( payload - > fields ) ; i + + ) {
@ -74,7 +114,7 @@ static struct command_result *htlc_accepted_call(struct command *cmd, const char
/* If we don't have a preimage field then this is not a keysend, let
* someone else take care of it . */
if ( preimage_field = = NULL )
return htlc_accepted_continue ( cmd ) ;
return htlc_accepted_continue ( cmd , NULL ) ;
if ( unknown_even_type ) {
plugin_log ( cmd - > plugin , LOG_UNUSUAL ,
@ -82,7 +122,7 @@ static struct command_result *htlc_accepted_call(struct command *cmd, const char
" , can't safely accept the keysend. Deferring to "
" other plugins. " ,
preimage_field - > numtype ) ;
return htlc_accepted_continue ( cmd ) ;
return htlc_accepted_continue ( cmd , NULL ) ;
}
/* If the preimage is not 32 bytes long then we can't accept the
@ -92,15 +132,21 @@ static struct command_result *htlc_accepted_call(struct command *cmd, const char
" Sender specified a preimage that is %zu bytes long, "
" we expected 32 bytes. Ignoring this HTLC. " ,
preimage_field - > length ) ;
return htlc_accepted_continue ( cmd ) ;
return htlc_accepted_continue ( cmd , NULL ) ;
}
ki = tal ( cmd , struct keysend_in ) ;
memcpy ( & ki - > payment_preimage , preimage_field - > value , 32 ) ;
ki - > label = tal_fmt ( ki , " keysend-%lu.%09lu " , now . ts . tv_sec , now . ts . tv_nsec ) ;
ki - > payload = tal_steal ( ki , payload ) ;
ki - > preimage_field = preimage_field ;
hexpreimage = tal_hex ( cmd , preimage_field - > value ) ;
/* If the preimage doesn't hash to the payment_hash we must continue,
* maybe someone else knows how to handle these . */
sha256 ( & payment_hash , preimage_field - > value , preimage_field - > length ) ;
hexpaymenthash = tal_hexstr ( cmd , & payment_hash , sizeof ( payment_hash ) ) ;
sha256 ( & ki - > payment_hash , preimage_field - > value , preimage_field - > length ) ;
hexpaymenthash = tal_hexstr ( cmd , & ki - > payment_hash , sizeof ( ki - > payment_hash ) ) ;
if ( ! json_tok_streq ( buf , payment_hash_tok , hexpaymenthash ) ) {
plugin_log (
cmd - > plugin , LOG_UNUSUAL ,
@ -109,15 +155,29 @@ static struct command_result *htlc_accepted_call(struct command *cmd, const char
hexpreimage , hexpaymenthash ,
payment_hash_tok - > end - payment_hash_tok - > start ,
buf + payment_hash_tok - > start ) ;
return htlc_accepted_continue ( cmd ) ;
tal_free ( ki ) ;
return htlc_accepted_continue ( cmd , NULL ) ;
}
/* Finally we can resolve the payment with the preimage. */
plugin_log ( cmd - > plugin , LOG_INFORM ,
" Resolving incoming HTLC with preimage for payment_hash %s "
" provided in the onion payload. " ,
hexpaymenthash ) ;
return htlc_accepted_resolve ( cmd , hexpreimage ) ;
/* Now we can call `invoice` RPC to backfill an invoce matching this
* spontaneous payment , thus leaving us with an accounting
* trace . Creating the invoice is best effort : it may fail if the
* ` payment_hash ` is already attached to an existing invoice , and the
* label could collide ( unlikely since we use the nanosecond time ) . If
* the call to ` invoice ` fails we will just continue , and ` lightningd `
* will be nice and reject the payment . */
req = jsonrpc_request_start ( cmd - > plugin , cmd , " invoice " ,
& htlc_accepted_invoice_created ,
& htlc_accepted_invoice_created ,
ki ) ;
plugin_log ( cmd - > plugin , LOG_INFORM , " Inserting a new invoice for keysend with payment_hash %s " , hexpaymenthash ) ;
json_add_string ( req - > js , " msatoshi " , " any " ) ;
json_add_string ( req - > js , " label " , ki - > label ) ;
json_add_string ( req - > js , " description " , " Spontaneous incoming payment through keysend " ) ;
json_add_preimage ( req - > js , " preimage " , & ki - > payment_preimage ) ;
return send_outreq ( cmd - > plugin , req ) ;
}
static const struct plugin_hook hooks [ ] = {