2021-12-04 21:53:56 +10:30
# include "config.h"
2018-07-27 06:56:37 +09:30
# include <ccan/cast/cast.h>
2023-09-12 13:53:19 +09:30
# include <ccan/mem/mem.h>
2017-06-20 15:47:03 +09:30
# include <ccan/tal/str/str.h>
2020-08-25 11:03:16 +09:30
# include <channeld/channeld_wiregen.h>
2020-04-11 12:52:40 +09:30
# include <common/blinding.h>
2021-09-16 14:30:42 +09:30
# include <common/configdir.h>
2020-04-11 12:52:40 +09:30
# include <common/ecdh.h>
2018-12-08 11:09:28 +10:30
# include <common/json_command.h>
2022-07-04 13:19:38 +09:30
# include <common/json_param.h>
2022-11-09 12:00:10 +10:30
# include <common/onion_decode.h>
2020-01-23 10:08:04 +10:30
# include <common/onionreply.h>
2018-08-09 12:23:04 +09:30
# include <common/timeout.h>
2021-09-16 14:30:42 +09:30
# include <common/type_to_string.h>
2023-08-07 13:11:50 +09:30
# include <connectd/connectd_wiregen.h>
2022-01-03 12:45:35 -06:00
# include <db/exec.h>
2020-08-25 11:35:45 +09:30
# include <gossipd/gossipd_wiregen.h>
2017-08-29 01:34:01 +09:30
# include <lightningd/chaintopology.h>
2021-09-17 08:01:38 +09:30
# include <lightningd/channel.h>
2020-03-18 18:40:32 -05:00
# include <lightningd/coin_mvts.h>
2017-06-20 15:15:03 +09:30
# include <lightningd/pay.h>
# include <lightningd/peer_control.h>
# include <lightningd/peer_htlcs.h>
2019-01-03 17:27:46 +01:00
# include <lightningd/plugin_hook.h>
2017-06-20 15:15:03 +09:30
# include <lightningd/subd.h>
2020-08-25 11:45:48 +09:30
# include <onchaind/onchaind_wiregen.h>
2017-06-20 15:15:03 +09:30
2019-11-21 17:26:30 +01:00
# ifndef SUPERVERBOSE
# define SUPERVERBOSE(...)
# endif
2018-02-12 20:43:04 +10:30
static bool state_update_ok ( struct channel * channel ,
2017-06-20 15:52:03 +09:30
enum htlc_state oldstate , enum htlc_state newstate ,
u64 htlc_id , const char * dir )
{
enum htlc_state expected = oldstate + 1 ;
/* We never get told about RCVD_REMOVE_HTLC, so skip over that
* ( we initialize in SENT_ADD_HTLC / RCVD_ADD_COMMIT , so those
* work ) . */
if ( expected = = RCVD_REMOVE_HTLC )
expected = RCVD_REMOVE_COMMIT ;
if ( newstate ! = expected ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel ,
" HTLC %s % " PRIu64 " invalid update %s->%s " ,
dir , htlc_id ,
htlc_state_name ( oldstate ) ,
htlc_state_name ( newstate ) ) ;
2017-06-20 15:52:03 +09:30
return false ;
}
2018-02-12 20:43:04 +10:30
log_debug ( channel - > log , " HTLC %s % " PRIu64 " %s->%s " ,
2017-06-20 15:52:03 +09:30
dir , htlc_id ,
htlc_state_name ( oldstate ) , htlc_state_name ( newstate ) ) ;
return true ;
}
2018-02-12 20:43:04 +10:30
static bool htlc_in_update_state ( struct channel * channel ,
2017-06-20 15:52:03 +09:30
struct htlc_in * hin ,
enum htlc_state newstate )
{
2018-02-12 20:43:04 +10:30
if ( ! state_update_ok ( channel , hin - > hstate , newstate , hin - > key . id , " in " ) )
2017-06-20 15:52:03 +09:30
return false ;
2018-02-12 20:43:04 +10:30
wallet_htlc_update ( channel - > peer - > ld - > wallet ,
2018-10-09 19:26:52 +10:30
hin - > dbid , newstate , hin - > preimage ,
2021-10-13 14:15:30 +10:30
max_unsigned ( channel - > next_index [ LOCAL ] ,
channel - > next_index [ REMOTE ] ) ,
2020-03-18 18:28:29 -05:00
hin - > badonion , hin - > failonion , NULL ,
hin - > we_filled ) ;
2017-09-18 20:18:29 +02:00
2017-06-20 15:52:03 +09:30
hin - > hstate = newstate ;
return true ;
}
2018-02-12 20:43:04 +10:30
static bool htlc_out_update_state ( struct channel * channel ,
2017-06-20 15:52:03 +09:30
struct htlc_out * hout ,
enum htlc_state newstate )
{
2018-02-12 20:43:04 +10:30
if ( ! state_update_ok ( channel , hout - > hstate , newstate , hout - > key . id ,
" out " ) )
2017-06-20 15:52:03 +09:30
return false ;
2020-04-14 14:02:46 -05:00
bool we_filled = false ;
2018-02-12 20:43:04 +10:30
wallet_htlc_update ( channel - > peer - > ld - > wallet , hout - > dbid , newstate ,
2021-10-13 14:15:30 +10:30
hout - > preimage ,
max_unsigned ( channel - > next_index [ LOCAL ] ,
channel - > next_index [ REMOTE ] ) ,
0 , hout - > failonion ,
2020-04-14 14:02:46 -05:00
hout - > failmsg , & we_filled ) ;
2017-09-18 20:18:29 +02:00
2017-06-20 15:52:03 +09:30
hout - > hstate = newstate ;
return true ;
}
2023-01-12 14:23:38 +10:30
/* BOLT-route-blinding #4:
* - if ` blinding_point ` is set in the incoming ` update_add_htlc ` :
* - MUST return an ` invalid_onion_blinding ` error .
* - if ` current_blinding_point ` is set in the onion payload and it is not the
* final node :
* - MUST return an ` invalid_onion_blinding ` error .
*/
static bool blind_error_return ( const struct htlc_in * hin )
{
if ( hin - > blinding )
return true ;
if ( hin - > payload
& & hin - > payload - > blinding
& & ! hin - > payload - > final )
return true ;
return false ;
}
2020-02-21 15:40:40 +10:30
static struct failed_htlc * mk_failed_htlc_badonion ( const tal_t * ctx ,
const struct htlc_in * hin ,
2020-08-31 10:43:25 +09:30
enum onion_wire badonion )
2020-02-18 10:28:58 +10:30
{
2020-02-21 15:40:40 +10:30
struct failed_htlc * f = tal ( ctx , struct failed_htlc ) ;
2020-02-18 10:28:58 +10:30
2023-01-12 14:23:38 +10:30
if ( blind_error_return ( hin ) )
2022-11-09 12:00:10 +10:30
badonion = WIRE_INVALID_ONION_BLINDING ;
2020-02-21 15:40:40 +10:30
f - > id = hin - > key . id ;
f - > onion = NULL ;
f - > badonion = badonion ;
f - > sha256_of_onion = tal ( f , struct sha256 ) ;
sha256 ( f - > sha256_of_onion , hin - > onion_routing_packet ,
sizeof ( hin - > onion_routing_packet ) ) ;
return f ;
2020-02-18 10:28:58 +10:30
}
static struct failed_htlc * mk_failed_htlc ( const tal_t * ctx ,
const struct htlc_in * hin ,
2020-02-21 15:40:40 +10:30
const struct onionreply * failonion )
2020-02-18 10:28:58 +10:30
{
struct failed_htlc * f = tal ( ctx , struct failed_htlc ) ;
2023-01-12 14:23:38 +10:30
if ( blind_error_return ( hin ) ) {
2022-11-09 12:00:10 +10:30
return mk_failed_htlc_badonion ( ctx , hin ,
WIRE_INVALID_ONION_BLINDING ) ;
}
2022-11-09 12:00:10 +10:30
/* Also, at head of the blinded path, return "normal" invalid
* onion blinding . */
if ( hin - > payload & & hin - > payload - > blinding ) {
struct sha256 sha ;
sha256 ( & sha , hin - > onion_routing_packet ,
sizeof ( hin - > onion_routing_packet ) ) ;
failonion = create_onionreply ( tmpctx , hin - > shared_secret ,
towire_invalid_onion_blinding ( tmpctx , & sha ) ) ;
}
2020-02-18 10:28:58 +10:30
f - > id = hin - > key . id ;
2020-02-21 15:40:40 +10:30
f - > sha256_of_onion = NULL ;
f - > badonion = 0 ;
/* Wrap onion error */
f - > onion = wrap_onionreply ( f , hin - > shared_secret , failonion ) ;
2020-02-18 10:28:58 +10:30
return f ;
}
2020-02-27 14:17:16 +10:30
static void tell_channeld_htlc_failed ( const struct htlc_in * hin ,
const struct failed_htlc * failed_htlc )
{
/* Tell peer, if we can. */
if ( ! hin - > key . channel - > owner )
return ;
/* onchaind doesn't care, it can't do anything but wait */
2023-10-02 09:29:51 +10:30
if ( ! channel_state_can_remove_htlc ( hin - > key . channel - > state ) )
2020-02-27 14:17:16 +10:30
return ;
subd_send_msg ( hin - > key . channel - > owner ,
2020-08-25 11:03:16 +09:30
take ( towire_channeld_fail_htlc ( NULL , failed_htlc ) ) ) ;
2020-02-27 14:17:16 +10:30
}
2017-06-20 15:52:03 +09:30
static void fail_in_htlc ( struct htlc_in * hin ,
2020-02-21 15:40:02 +10:30
const struct onionreply * failonion TAKES )
2017-06-20 15:15:03 +09:30
{
2020-02-21 15:40:40 +10:30
struct failed_htlc * failed_htlc ;
2017-06-20 15:52:03 +09:30
assert ( ! hin - > preimage ) ;
2020-02-21 15:40:02 +10:30
hin - > failonion = dup_onionreply ( hin , failonion ) ;
2017-06-20 15:52:03 +09:30
/* We update state now to signal it's in progress, for persistence. */
2018-02-12 20:43:04 +10:30
htlc_in_update_state ( hin - > key . channel , hin , SENT_REMOVE_HTLC ) ;
2018-10-09 19:15:52 +10:30
htlc_in_check ( hin , __func__ ) ;
2017-06-20 15:52:03 +09:30
2022-11-09 12:00:10 +10:30
failed_htlc = mk_failed_htlc ( tmpctx , hin , hin - > failonion ) ;
2020-04-11 12:52:40 +09:30
2022-01-25 06:31:52 +10:30
bool we_filled = false ;
wallet_htlc_update ( hin - > key . channel - > peer - > ld - > wallet ,
hin - > dbid , hin - > hstate ,
hin - > preimage ,
max_unsigned ( hin - > key . channel - > next_index [ LOCAL ] ,
hin - > key . channel - > next_index [ REMOTE ] ) ,
hin - > badonion ,
hin - > failonion , NULL , & we_filled ) ;
2020-02-27 14:17:16 +10:30
tell_channeld_htlc_failed ( hin , failed_htlc ) ;
2017-06-20 15:15:03 +09:30
}
2020-02-21 15:38:31 +10:30
/* Immediately fail HTLC with a BADONION code */
static void local_fail_in_htlc_badonion ( struct htlc_in * hin ,
2020-08-31 10:43:25 +09:30
enum onion_wire badonion )
2020-02-21 15:38:31 +10:30
{
2020-02-21 15:40:40 +10:30
struct failed_htlc * failed_htlc ;
2020-02-21 15:38:31 +10:30
assert ( ! hin - > preimage ) ;
assert ( badonion & BADONION ) ;
2020-02-21 15:40:44 +10:30
hin - > badonion = badonion ;
2020-02-21 15:38:31 +10:30
/* We update state now to signal it's in progress, for persistence. */
htlc_in_update_state ( hin - > key . channel , hin , SENT_REMOVE_HTLC ) ;
htlc_in_check ( hin , __func__ ) ;
2020-02-21 15:40:40 +10:30
failed_htlc = mk_failed_htlc_badonion ( tmpctx , hin , badonion ) ;
2020-02-27 14:17:16 +10:30
tell_channeld_htlc_failed ( hin , failed_htlc ) ;
2020-02-21 15:38:31 +10:30
}
2017-06-20 15:52:03 +09:30
/* This is used for cases where we can immediately fail the HTLC. */
2020-02-21 15:38:39 +10:30
void local_fail_in_htlc ( struct htlc_in * hin , const u8 * failmsg TAKES )
2019-04-11 09:38:55 +09:30
{
2020-02-21 15:40:02 +10:30
struct onionreply * failonion = create_onionreply ( NULL ,
hin - > shared_secret ,
failmsg ) ;
2020-02-21 15:38:39 +10:30
if ( taken ( failmsg ) )
tal_free ( failmsg ) ;
2020-02-21 15:40:02 +10:30
fail_in_htlc ( hin , take ( failonion ) ) ;
2020-02-21 15:38:39 +10:30
}
/* Helper to create (common) WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS */
2020-07-20 15:19:52 +09:30
const u8 * failmsg_incorrect_or_unknown_ ( const tal_t * ctx ,
struct lightningd * ld ,
const struct htlc_in * hin ,
const char * file , int line )
2020-02-21 15:38:39 +10:30
{
2020-07-20 15:19:52 +09:30
log_debug ( ld - > log , " WIRE_INCORRECT_OR_UNKNOWN_PAYMENT_DETAILS: %s:%u " ,
file , line ) ;
2020-02-21 15:38:39 +10:30
return towire_incorrect_or_unknown_payment_details (
ctx , hin - > msat ,
2020-04-15 19:49:46 +09:30
get_block_height ( ld - > topology ) ) ;
2019-04-11 09:38:55 +09:30
}
2017-06-20 15:42:03 +09:30
/* localfail are for handing to the local payer if it's local. */
2022-01-25 06:31:52 +10:30
static void fail_out_htlc ( struct htlc_out * hout , const char * localfail )
2017-06-20 15:42:03 +09:30
{
htlc_out_check ( hout , __func__ ) ;
2020-02-21 15:36:58 +10:30
assert ( hout - > failmsg | | hout - > failonion ) ;
2019-04-15 22:27:22 +08:00
2018-10-10 06:51:31 +10:30
if ( hout - > am_origin ) {
2022-01-25 06:31:52 +10:30
payment_failed ( hout - > key . channel - > peer - > ld , hout , localfail ) ;
2018-10-09 19:17:52 +10:30
} else if ( hout - > in ) {
2022-01-25 06:31:52 +10:30
const struct onionreply * failonion ;
/* If we have an onion, simply copy it. */
if ( hout - > failonion )
failonion = hout - > failonion ;
/* Otherwise, we need to onionize this local error. */
else
failonion = create_onionreply ( hout ,
hout - > in - > shared_secret ,
hout - > failmsg ) ;
fail_in_htlc ( hout - > in , failonion ) ;
2020-12-03 11:55:21 +10:30
} else {
2022-01-25 06:31:52 +10:30
log_broken ( hout - > key . channel - > log , " Neither origin nor in? " ) ;
2017-06-20 15:42:03 +09:30
}
}
2017-06-20 15:15:03 +09:30
/* BOLT #4:
*
2023-04-07 16:06:14 +09:30
* - if it is not the final node :
* - MUST return an error if :
* . . .
* - incoming ` amount_msat ` - ` fee ` < ` amt_to_forward ` ( where ` fee ` is the advertised fee as described in [ BOLT # 7 ] ( 07 - routing - gossip . md # htlc - fees ) )
2017-06-20 15:15:03 +09:30
*/
2020-01-31 12:08:12 +10:30
static bool check_fwd_amount ( struct htlc_in * hin ,
struct amount_msat amt_to_forward ,
struct amount_msat amt_in_htlc ,
2021-09-22 22:56:14 +09:30
u32 feerate_base , u32 feerate_ppm )
2017-06-20 15:15:03 +09:30
{
2021-09-22 22:56:14 +09:30
struct amount_msat fee ;
2019-02-21 14:15:55 +10:30
struct amount_msat fwd ;
2021-09-22 22:56:14 +09:30
if ( ! amount_msat_fee ( & fee , amt_to_forward ,
feerate_base , feerate_ppm ) ) {
log_broken ( hin - > key . channel - > log , " Fee overflow forwarding %s! " ,
type_to_string ( tmpctx , struct amount_msat ,
& amt_to_forward ) ) ;
return false ;
}
2019-02-21 14:15:55 +10:30
if ( amount_msat_sub ( & fwd , amt_in_htlc , fee )
& & amount_msat_greater_eq ( fwd , amt_to_forward ) )
2017-06-20 15:15:03 +09:30
return true ;
2019-02-21 14:15:55 +10:30
2018-02-12 20:43:04 +10:30
log_debug ( hin - > key . channel - > log , " HTLC % " PRIu64 " incorrect amount: "
2019-02-21 14:15:55 +10:30
" %s in, %s out, fee reqd %s " ,
hin - > key . id ,
type_to_string ( tmpctx , struct amount_msat , & amt_in_htlc ) ,
type_to_string ( tmpctx , struct amount_msat , & amt_to_forward ) ,
type_to_string ( tmpctx , struct amount_msat , & fee ) ) ;
2017-06-20 15:15:03 +09:30
return false ;
}
/* BOLT #4:
*
2023-04-07 16:06:14 +09:30
* - if it is not the final node :
* - MUST return an error if :
* . . .
* - ` cltv_expiry ` - ` cltv_expiry_delta ` < ` outgoing_cltv_value `
2023-04-07 16:25:33 +09:30
* - If it is the final node :
2023-04-07 16:24:26 +09:30
* . . .
* - MUST return an error if :
* . . .
* - incoming ` cltv_expiry ` < ` outgoing_cltv_value ` .
2017-06-20 15:15:03 +09:30
*/
2017-10-09 11:53:13 +10:30
static bool check_cltv ( struct htlc_in * hin ,
u32 cltv_expiry , u32 outgoing_cltv_value , u32 delta )
2017-06-20 15:15:03 +09:30
{
2019-01-04 00:08:35 +00:00
if ( delta < cltv_expiry & & cltv_expiry - delta > = outgoing_cltv_value )
2017-06-20 15:15:03 +09:30
return true ;
2018-02-12 20:43:04 +10:30
log_debug ( hin - > key . channel - > log , " HTLC % " PRIu64 " incorrect CLTV: "
2017-06-20 15:15:03 +09:30
" %u in, %u out, delta reqd %u " ,
2017-10-09 11:53:13 +10:30
hin - > key . id , cltv_expiry , outgoing_cltv_value , delta ) ;
2017-06-20 15:15:03 +09:30
return false ;
}
2019-04-11 09:38:55 +09:30
void fulfill_htlc ( struct htlc_in * hin , const struct preimage * preimage )
2017-06-20 15:15:03 +09:30
{
u8 * msg ;
2018-03-24 08:26:08 +00:00
struct channel * channel = hin - > key . channel ;
struct wallet * wallet = channel - > peer - > ld - > wallet ;
2017-06-20 15:15:03 +09:30
2019-04-11 09:38:55 +09:30
if ( hin - > hstate ! = RCVD_ADD_ACK_REVOCATION ) {
log_debug ( channel - > log ,
" HTLC fulfilled, but not ready any more (%s). " ,
htlc_state_name ( hin - > hstate ) ) ;
return ;
}
2017-06-20 15:29:03 +09:30
hin - > preimage = tal_dup ( hin , struct preimage , preimage ) ;
2017-06-20 15:15:03 +09:30
2017-06-20 15:52:03 +09:30
/* We update state now to signal it's in progress, for persistence. */
2018-03-24 08:26:08 +00:00
htlc_in_update_state ( channel , hin , SENT_REMOVE_HTLC ) ;
2018-10-09 19:15:52 +10:30
htlc_in_check ( hin , __func__ ) ;
2018-03-24 08:26:08 +00:00
/* Update channel stats */
wallet_channel_stats_incr_in_fulfilled ( wallet ,
channel - > dbid ,
2019-02-21 14:15:55 +10:30
hin - > msat ) ;
2017-06-20 15:52:03 +09:30
2017-09-20 14:15:41 +09:30
/* No owner? We'll either send to channeld in peer_htlcs, or
* onchaind in onchaind_tell_fulfill . */
2018-03-24 08:26:08 +00:00
if ( ! channel - > owner ) {
log_debug ( channel - > log , " HTLC fulfilled, but no owner. " ) ;
2017-09-20 14:15:41 +09:30
return ;
}
2023-01-31 09:38:31 +10:30
if ( streq ( channel - > owner - > name , " onchaind " ) ) {
2021-12-01 10:24:31 -06:00
msg = towire_onchaind_known_preimage ( hin , preimage ) ;
2017-09-20 14:15:41 +09:30
} else {
2018-07-27 06:56:37 +09:30
struct fulfilled_htlc fulfilled_htlc ;
fulfilled_htlc . id = hin - > key . id ;
fulfilled_htlc . payment_preimage = * preimage ;
2020-08-25 11:03:16 +09:30
msg = towire_channeld_fulfill_htlc ( hin , & fulfilled_htlc ) ;
2017-09-20 14:15:41 +09:30
}
2018-03-24 08:26:08 +00:00
subd_send_msg ( channel - > owner , take ( msg ) ) ;
2017-06-20 15:15:03 +09:30
}
2017-06-20 15:23:03 +09:30
static void handle_localpay ( struct htlc_in * hin ,
2019-02-21 14:15:55 +10:30
struct amount_msat amt_to_forward ,
2019-11-23 10:49:23 +10:30
u32 outgoing_cltv_value ,
struct amount_msat total_msat ,
2022-03-31 19:40:50 +10:30
const struct secret * payment_secret ,
const u8 * payment_metadata )
2017-06-20 15:15:03 +09:30
{
2020-02-21 15:38:39 +10:30
const u8 * failmsg ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = hin - > key . channel - > peer - > ld ;
2017-06-20 15:15:03 +09:30
/* BOLT #4:
2023-04-07 16:25:33 +09:30
* - If it is the final node :
2023-04-07 16:06:14 +09:30
* - MUST treat ` total_msat ` as if it were equal to ` amt_to_forward ` if it
* is not present .
* - MUST return an error if :
2023-04-07 16:24:26 +09:30
* - incoming ` amount_msat ` < ` amt_to_forward ` .
2017-06-20 15:15:03 +09:30
*/
2023-04-07 16:24:26 +09:30
if ( amount_msat_less ( hin - > msat , amt_to_forward ) ) {
2020-01-31 12:08:12 +10:30
log_debug ( hin - > key . channel - > log ,
" HTLC % " PRIu64 " final incorrect amount: "
" %s in, %s expected " ,
hin - > key . id ,
type_to_string ( tmpctx , struct amount_msat , & hin - > msat ) ,
type_to_string ( tmpctx , struct amount_msat ,
& amt_to_forward ) ) ;
/* BOLT #4:
* 1. type : 19 ( ` final_incorrect_htlc_amount ` )
* 2. data :
* * [ ` u64 ` : ` incoming_htlc_amt ` ]
*
2023-09-12 10:12:01 +09:30
* The amount in the HTLC is less than the value in the onion .
2020-01-31 12:08:12 +10:30
*/
2020-02-21 15:38:39 +10:30
failmsg = towire_final_incorrect_htlc_amount ( NULL , hin - > msat ) ;
2017-06-20 15:15:03 +09:30
goto fail ;
}
/* BOLT #4:
2023-04-07 16:25:33 +09:30
* - If it is the final node :
2023-04-07 16:06:14 +09:30
* - MUST treat ` total_msat ` as if it were equal to ` amt_to_forward ` if it
* is not present .
* - MUST return an error if :
* . . .
2023-04-07 16:24:26 +09:30
* - incoming ` cltv_expiry ` < ` outgoing_cltv_value ` .
2017-06-20 15:15:03 +09:30
*/
2019-12-12 10:25:39 +10:30
if ( ! check_cltv ( hin , hin - > cltv_expiry , outgoing_cltv_value , 0 ) ) {
2023-04-07 16:06:14 +09:30
/* BOLT #4:
*
* 1. type : 18 ( ` final_incorrect_cltv_expiry ` )
* 2. data :
* * [ ` u32 ` : ` cltv_expiry ` ]
*
2023-09-12 10:12:01 +09:30
* The CLTV expiry in the HTLC is less than the value in the onion .
2023-04-07 16:06:14 +09:30
*/
2020-02-21 15:38:39 +10:30
failmsg = towire_final_incorrect_cltv_expiry ( NULL ,
hin - > cltv_expiry ) ;
2017-06-20 15:15:03 +09:30
goto fail ;
}
/* BOLT #4:
*
2023-04-07 16:24:26 +09:30
* incoming ` cltv_expiry ` < ` current_block_height ` + ` min_final_cltv_expiry_delta ` . */
2017-10-23 14:46:57 +10:30
if ( get_block_height ( ld - > topology ) + ld - > config . cltv_final
2019-12-12 10:25:39 +10:30
> hin - > cltv_expiry ) {
2018-02-12 20:43:04 +10:30
log_debug ( hin - > key . channel - > log ,
2017-11-08 14:34:11 +01:00
" Expiry cltv too soon %u < %u + %u " ,
2019-12-12 10:25:39 +10:30
hin - > cltv_expiry ,
2017-06-20 15:23:03 +09:30
get_block_height ( ld - > topology ) ,
2017-10-23 14:46:57 +10:30
ld - > config . cltv_final ) ;
2020-04-15 19:49:46 +09:30
failmsg = failmsg_incorrect_or_unknown ( NULL , ld , hin ) ;
2017-06-20 15:15:03 +09:30
goto fail ;
}
2022-03-31 19:40:50 +10:30
/* We don't expect payment_metadata; reject here */
if ( payment_metadata ) {
log_debug ( hin - > key . channel - > log ,
" Unexpected payment_metadata %s " ,
tal_hex ( tmpctx , payment_metadata ) ) ;
/* BOLT #4:
* 1. type : PERM | 22 ( ` invalid_onion_payload ` )
* 2. data :
* * [ ` bigsize ` : ` type ` ]
* * [ ` u16 ` : ` offset ` ]
*
* The decrypted onion per - hop payload was not understood by the processing node
* or is incomplete . If the failure can be narrowed down to a specific tlv type in
* the payload , the erring node may include that ` type ` and its byte ` offset ` in
* the decrypted byte stream .
*/
2023-04-07 16:06:14 +09:30
failmsg = towire_invalid_onion_payload ( NULL , TLV_PAYLOAD_PAYMENT_METADATA ,
2022-03-31 19:40:50 +10:30
/* FIXME: offset? */ 0 ) ;
goto fail ;
}
2019-12-12 10:25:45 +10:30
htlc_set_add ( ld , hin , total_msat , payment_secret ) ;
2017-06-20 15:15:03 +09:30
return ;
fail :
2020-02-21 15:38:39 +10:30
local_fail_in_htlc ( hin , take ( failmsg ) ) ;
2017-06-20 15:15:03 +09:30
}
/*
* A catchall in case outgoing peer disconnects before getting fwd .
*
* We could queue this and wait for it to come back , but this is simple .
*/
2018-02-14 12:23:13 +10:30
static void destroy_hout_subd_died ( struct htlc_out * hout )
2017-06-20 15:15:03 +09:30
{
2021-10-29 18:58:29 +02:00
struct db * db = hout - > key . channel - > peer - > ld - > wallet - > db ;
/* Under some circumstances we may need to start a DB
* transaction and commit it here again . This is the case when
* we ' re getting called from the destructor chain . */
bool have_tx =
db_in_transaction ( db ) ;
2018-02-12 20:43:04 +10:30
log_debug ( hout - > key . channel - > log ,
2017-06-20 15:15:03 +09:30
" Failing HTLC % " PRIu64 " due to peer death " ,
2017-06-20 15:42:03 +09:30
hout - > key . id ) ;
2017-06-20 15:15:03 +09:30
2022-01-25 06:31:52 +10:30
hout - > failmsg = towire_temporary_channel_failure ( hout ,
2024-01-31 13:46:16 +10:30
channel_update_for_error ( tmpctx ,
hout - > key . channel ) ) ;
2018-10-09 19:15:52 +10:30
/* Assign a temporary state (we're about to free it!) so checks
2020-02-21 15:36:58 +10:30
* are happy that it has a failure message */
2018-10-09 19:15:52 +10:30
assert ( hout - > hstate = = SENT_ADD_HTLC ) ;
hout - > hstate = RCVD_REMOVE_HTLC ;
2021-10-29 18:58:29 +02:00
if ( ! have_tx )
db_begin_transaction ( db ) ;
2022-01-25 06:31:52 +10:30
fail_out_htlc ( hout , " Outgoing subdaemon died " ) ;
2021-10-29 18:58:29 +02:00
if ( ! have_tx )
db_commit_transaction ( db ) ;
2017-06-20 15:15:03 +09:30
}
2017-06-20 15:20:03 +09:30
/* This is where channeld gives us the HTLC id, and also reports if it
* failed immediately . */
2018-02-21 16:06:07 +01:00
static void rcvd_htlc_reply ( struct subd * subd , const u8 * msg , const int * fds UNUSED ,
2017-06-20 15:23:03 +09:30
struct htlc_out * hout )
2017-06-20 15:15:03 +09:30
{
2020-02-21 15:36:58 +10:30
u8 * failmsg ;
2020-01-22 16:28:19 +10:30
char * failurestr ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = subd - > ld ;
2017-06-20 15:15:03 +09:30
2020-08-25 11:03:16 +09:30
if ( ! fromwire_channeld_offer_htlc_reply ( msg , msg ,
2017-06-20 15:23:03 +09:30
& hout - > key . id ,
2020-02-21 15:36:58 +10:30
& failmsg ,
2017-06-20 15:15:03 +09:30
& failurestr ) ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( subd - > channel ,
2018-02-12 20:43:04 +10:30
" Bad channel_offer_htlc_reply " ) ;
2017-06-20 15:23:03 +09:30
tal_free ( hout ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:15:03 +09:30
}
2020-02-21 15:36:58 +10:30
if ( tal_count ( failmsg ) ) {
2023-10-24 14:20:06 +10:30
/* It's our job to append the channel_update */
if ( fromwire_peektype ( failmsg ) & UPDATE ) {
2024-01-31 13:46:16 +10:30
const u8 * update = channel_update_for_error ( tmpctx , hout - > key . channel ) ;
2023-10-24 14:20:06 +10:30
towire ( & failmsg , update , tal_bytelen ( update ) ) ;
}
2020-02-21 15:36:58 +10:30
hout - > failmsg = tal_steal ( hout , failmsg ) ;
2018-10-10 06:51:31 +10:30
if ( hout - > am_origin ) {
2020-01-22 16:28:19 +10:30
char * localfail = tal_fmt ( msg , " %s: %s " ,
2020-08-31 10:43:25 +09:30
onion_wire_name ( fromwire_peektype ( failmsg ) ) ,
2020-01-22 16:28:19 +10:30
failurestr ) ;
2022-01-25 06:31:52 +10:30
payment_failed ( ld , hout , localfail ) ;
2019-04-15 22:27:22 +08:00
} else if ( hout - > in ) {
2020-02-21 15:36:58 +10:30
struct onionreply * failonion ;
failonion = create_onionreply ( hout ,
hout - > in - > shared_secret ,
hout - > failmsg ) ;
2020-02-21 15:40:02 +10:30
fail_in_htlc ( hout - > in , failonion ) ;
2019-04-15 22:27:22 +08:00
/* here we haven't called connect_htlc_out(),
2022-07-09 12:53:24 +09:30
* so set htlc field with NULL ( db wants it to exist ! ) */
2019-04-15 22:27:22 +08:00
wallet_forwarded_payment_add ( ld - > wallet ,
2022-03-31 13:44:27 +10:30
hout - > in ,
2022-09-28 14:19:35 +09:30
FORWARD_STYLE_TLV ,
2022-07-09 12:53:24 +09:30
channel_scid_or_local_alias ( hout - > key . channel ) , NULL ,
2019-04-15 22:27:22 +08:00
FORWARD_LOCAL_FAILED ,
2020-02-21 15:36:58 +10:30
fromwire_peektype ( hout - > failmsg ) ) ;
2019-04-15 22:27:22 +08:00
}
2018-01-29 18:54:08 +00:00
/* Prevent hout from being failed twice. */
2018-02-14 12:23:13 +10:30
tal_del_destructor ( hout , destroy_hout_subd_died ) ;
2017-12-15 20:59:45 +10:30
tal_free ( hout ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:15:03 +09:30
}
2023-01-03 15:16:52 +10:30
if ( find_htlc_out ( subd - > ld - > htlcs_out , hout - > key . channel , hout - > key . id )
2017-12-21 14:20:47 +10:30
| | hout - > key . id = = HTLC_INVALID_ID ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( subd - > channel ,
2017-06-20 15:47:03 +09:30
" Bad offer_htlc_reply HTLC id % " PRIu64
" is a duplicate " ,
hout - > key . id ) ;
2017-06-20 15:34:03 +09:30
tal_free ( hout ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:34:03 +09:30
}
2017-06-20 15:20:03 +09:30
/* Add it to lookup table now we know id. */
2023-01-03 15:16:52 +10:30
connect_htlc_out ( subd - > ld - > htlcs_out , hout ) ;
2017-06-20 15:15:03 +09:30
2017-06-20 15:20:03 +09:30
/* When channeld includes it in commitment, we'll make it persistent. */
2017-06-20 15:15:03 +09:30
}
2021-05-21 11:45:54 +09:30
static void htlc_offer_timeout ( struct htlc_out * out )
2018-08-09 12:23:04 +09:30
{
2021-05-21 11:45:54 +09:30
struct channel * channel = out - > key . channel ;
out - > timeout = NULL ;
/* Otherwise, timer would be removed. */
assert ( out - > hstate = = SENT_ADD_HTLC ) ;
2018-08-23 21:00:13 +09:30
2018-08-09 12:23:04 +09:30
/* If owner died, we should already be taken care of. */
2023-10-02 09:29:51 +10:30
if ( ! channel - > owner | | ! channel_state_can_add_htlc ( channel - > state ) )
2018-08-09 12:23:04 +09:30
return ;
log_unusual ( channel - > owner - > log ,
2021-05-21 11:45:54 +09:30
" Adding HTLC % " PRIu64 " too slow: killing connection " ,
out - > key . id ) ;
2023-10-02 09:29:48 +10:30
channel_fail_transient ( channel , true ,
2019-08-07 16:13:16 +09:30
" Adding HTLC timed out: killed connection " ) ;
2018-08-09 12:23:04 +09:30
}
2020-02-21 15:40:02 +10:30
/* Returns failmsg, or NULL on success. */
const u8 * send_htlc_out ( const tal_t * ctx ,
struct channel * out ,
struct amount_msat amount , u32 cltv ,
2021-12-07 14:09:28 -06:00
struct amount_msat final_msat ,
2020-02-21 15:40:02 +10:30
const struct sha256 * payment_hash ,
2020-04-11 12:52:40 +09:30
const struct pubkey * blinding ,
2020-02-21 15:40:02 +10:30
u64 partid ,
2021-09-29 12:33:57 +02:00
u64 groupid ,
2020-02-21 15:40:02 +10:30
const u8 * onion_routing_packet ,
struct htlc_in * in ,
2022-01-25 06:31:52 +10:30
struct htlc_out * * houtp )
2017-06-20 15:42:03 +09:30
{
u8 * msg ;
2020-02-18 10:24:58 +10:30
* houtp = NULL ;
2023-10-02 09:29:51 +10:30
if ( ! channel_state_can_add_htlc ( out - > state ) ) {
2017-06-20 15:44:03 +09:30
log_info ( out - > log , " Attempt to send HTLC but not ready (%s) " ,
2018-02-12 20:43:04 +10:30
channel_state_name ( out ) ) ;
2020-02-21 15:40:02 +10:30
return towire_unknown_next_peer ( ctx ) ;
2017-06-20 15:44:03 +09:30
}
2018-02-12 20:43:04 +10:30
if ( ! out - > owner ) {
2017-06-20 15:44:03 +09:30
log_info ( out - > log , " Attempt to send HTLC but unowned (%s) " ,
2018-02-12 20:43:04 +10:30
channel_state_name ( out ) ) ;
2022-01-25 06:31:52 +10:30
return towire_temporary_channel_failure ( ctx ,
2024-01-31 13:46:16 +10:30
channel_update_for_error ( tmpctx , out ) ) ;
2017-06-20 15:44:03 +09:30
}
2019-08-10 20:17:49 +09:30
if ( ! topology_synced ( out - > peer - > ld - > topology ) ) {
log_info ( out - > log , " Attempt to send HTLC but still syncing "
" with bitcoin network " ) ;
2020-02-27 14:42:17 +10:30
return towire_temporary_node_failure ( ctx ) ;
2019-08-10 20:17:49 +09:30
}
2017-06-20 15:42:03 +09:30
/* Make peer's daemon own it, catch if it dies. */
2020-02-18 10:24:58 +10:30
* houtp = new_htlc_out ( out - > owner , out , amount , cltv ,
2020-04-11 12:52:40 +09:30
payment_hash , onion_routing_packet ,
blinding , in = = NULL ,
2021-12-07 14:09:28 -06:00
final_msat ,
2021-09-29 12:33:57 +02:00
partid , groupid , in ) ;
2020-02-18 10:24:58 +10:30
tal_add_destructor ( * houtp , destroy_hout_subd_died ) ;
2017-06-20 15:42:03 +09:30
2021-05-21 11:45:54 +09:30
/* Give channel 30 seconds to commit this htlc. */
2023-09-21 15:06:28 +09:30
if ( ! out - > peer - > ld - > dev_no_htlc_timeout ) {
2021-05-21 11:45:54 +09:30
( * houtp ) - > timeout = new_reltimer ( out - > peer - > ld - > timers ,
* houtp , time_from_sec ( 30 ) ,
2018-08-09 12:23:04 +09:30
htlc_offer_timeout ,
2021-05-21 11:45:54 +09:30
* houtp ) ;
}
2020-08-25 11:03:16 +09:30
msg = towire_channeld_offer_htlc ( out , amount , cltv , payment_hash ,
2020-04-11 12:52:40 +09:30
onion_routing_packet , blinding ) ;
2020-02-18 10:24:58 +10:30
subd_req ( out - > peer - > ld , out - > owner , take ( msg ) , - 1 , 0 , rcvd_htlc_reply ,
* houtp ) ;
2017-06-20 15:44:03 +09:30
2020-02-21 15:40:02 +10:30
return NULL ;
2017-06-20 15:42:03 +09:30
}
2022-09-25 22:44:12 +09:30
/* What's the best channel to this peer?
* If @ hint is set , channel must match that one . */
static struct channel * best_channel ( struct lightningd * ld ,
const struct peer * next_peer ,
struct amount_msat amt_to_forward ,
struct channel * hint )
{
struct amount_msat best_spendable = AMOUNT_MSAT ( 0 ) ;
struct channel * channel , * best = hint ;
/* Seek channel with largest spendable! */
list_for_each ( & next_peer - > channels , channel , list ) {
struct amount_msat spendable ;
2023-10-02 09:29:51 +10:30
if ( ! channel_state_can_add_htlc ( channel - > state ) )
2022-09-25 22:44:12 +09:30
continue ;
spendable = channel_amount_spendable ( channel ) ;
if ( ! amount_msat_greater ( spendable , best_spendable ) )
continue ;
/* Don't override if fees differ... */
if ( hint ) {
if ( hint - > feerate_base ! = channel - > feerate_base
| | hint - > feerate_ppm ! = channel - > feerate_ppm )
continue ;
}
/* Or if this would be below min for channel! */
if ( amount_msat_less ( amt_to_forward ,
channel - > channel_info . their_config . htlc_minimum ) )
continue ;
best = channel ;
best_spendable = spendable ;
}
return best ;
}
/* forward_to is where we're actually sending it (or NULL), and
* forward_scid is where they asked to send it ( or NULL ) . */
2017-06-20 15:23:03 +09:30
static void forward_htlc ( struct htlc_in * hin ,
2017-06-20 15:15:03 +09:30
u32 cltv_expiry ,
2019-02-21 14:15:55 +10:30
struct amount_msat amt_to_forward ,
2017-06-20 15:15:03 +09:30
u32 outgoing_cltv_value ,
2022-09-25 22:44:12 +09:30
const struct short_channel_id * forward_scid ,
const struct channel_id * forward_to ,
2020-12-08 17:18:53 +10:30
const u8 next_onion [ TOTAL_PACKET_SIZE ( ROUTING_INFO_SIZE ) ] ,
2020-04-11 12:52:40 +09:30
const struct pubkey * next_blinding )
2017-06-20 15:15:03 +09:30
{
2020-02-21 15:40:02 +10:30
const u8 * failmsg ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = hin - > key . channel - > peer - > ld ;
2022-03-23 09:29:20 +10:30
struct channel * next ;
2019-04-15 22:27:22 +08:00
struct htlc_out * hout = NULL ;
2022-03-23 09:29:20 +10:30
2022-09-25 22:44:12 +09:30
if ( forward_to ) {
next = channel_by_cid ( ld , forward_to ) ;
/* Update this to where we're actually trying to send. */
if ( next )
forward_scid = channel_scid_or_local_alias ( next ) ;
2022-11-09 12:00:10 +10:30
} else
2022-09-25 22:44:12 +09:30
next = NULL ;
2022-03-23 09:29:20 +10:30
2017-11-28 15:34:20 +10:30
/* Unknown peer, or peer not ready. */
2023-10-02 09:29:51 +10:30
if ( ! next | | ! channel_state_can_add_htlc ( next - > state ) ) {
2020-02-21 15:40:02 +10:30
local_fail_in_htlc ( hin , take ( towire_unknown_next_peer ( NULL ) ) ) ;
2019-04-15 22:27:22 +08:00
wallet_forwarded_payment_add ( hin - > key . channel - > peer - > ld - > wallet ,
2022-09-28 14:19:35 +09:30
hin , FORWARD_STYLE_TLV ,
2022-09-25 22:44:12 +09:30
forward_scid , NULL ,
2019-04-15 22:27:22 +08:00
FORWARD_LOCAL_FAILED ,
2020-02-21 15:40:02 +10:30
WIRE_UNKNOWN_NEXT_PEER ) ;
2017-11-28 15:34:20 +10:30
return ;
2017-06-20 15:15:03 +09:30
}
/* BOLT #7:
*
2018-06-17 19:43:44 +09:30
* The origin node :
* - SHOULD accept HTLCs that pay a fee equal to or greater than :
2018-10-26 16:31:30 +10:30
* - fee_base_msat + ( amount_to_forward * fee_proportional_millionths / 1000000 )
2017-06-20 15:15:03 +09:30
*/
2021-09-22 22:56:14 +09:30
if ( ! check_fwd_amount ( hin , amt_to_forward , hin - > msat ,
next - > feerate_base ,
next - > feerate_ppm ) ) {
2022-09-10 11:44:31 +09:30
/* BOLT #7:
* - If it creates a new ` channel_update ` with updated channel parameters :
* - SHOULD keep accepting the previous channel parameters for 10 minutes
*/
2021-09-23 12:12:47 +09:30
if ( ! time_before ( time_now ( ) , next - > old_feerate_timeout )
| | ! check_fwd_amount ( hin , amt_to_forward , hin - > msat ,
next - > old_feerate_base ,
next - > old_feerate_ppm ) ) {
failmsg = towire_fee_insufficient ( tmpctx , hin - > msat ,
2024-01-31 13:46:16 +10:30
channel_update_for_error ( tmpctx ,
next ) ) ;
2021-09-23 12:12:47 +09:30
goto fail ;
}
log_info ( hin - > key . channel - > log ,
" Allowing payment using older feerate " ) ;
2017-06-20 15:15:03 +09:30
}
2022-03-21 11:28:54 +10:30
if ( amount_msat_greater ( amt_to_forward , next - > htlc_maximum_msat )
| | amount_msat_less ( amt_to_forward , next - > htlc_minimum_msat ) ) {
/* Are we in old-range grace-period? */
2022-03-21 11:28:27 +10:30
if ( ! time_before ( time_now ( ) , next - > old_feerate_timeout )
2022-03-21 11:28:54 +10:30
| | amount_msat_less ( amt_to_forward , next - > old_htlc_minimum_msat )
2022-03-21 11:28:27 +10:30
| | amount_msat_greater ( amt_to_forward , next - > old_htlc_maximum_msat ) ) {
failmsg = towire_temporary_channel_failure ( tmpctx ,
2024-01-31 13:46:16 +10:30
channel_update_for_error ( tmpctx , next ) ) ;
2022-03-21 11:28:27 +10:30
goto fail ;
}
log_info ( hin - > key . channel - > log ,
2022-03-21 11:28:54 +10:30
" Allowing htlc using older htlc_minimum/maximum_msat " ) ;
2022-03-21 11:28:27 +10:30
}
2017-10-09 11:53:13 +10:30
if ( ! check_cltv ( hin , cltv_expiry , outgoing_cltv_value ,
2017-10-23 14:46:57 +10:30
ld - > config . cltv_expiry_delta ) ) {
2020-02-21 15:40:02 +10:30
failmsg = towire_incorrect_cltv_expiry ( tmpctx , cltv_expiry ,
2024-01-31 13:46:16 +10:30
channel_update_for_error ( tmpctx , next ) ) ;
2017-06-20 15:15:03 +09:30
goto fail ;
}
2019-10-03 15:20:12 +09:30
2017-11-02 10:20:47 +10:30
/* BOLT #2:
2017-06-20 15:15:03 +09:30
*
2018-06-17 19:43:44 +09:30
* An offering node :
* - MUST estimate a timeout deadline for each HTLC it offers .
* - MUST NOT offer an HTLC with a timeout deadline before its
* ` cltv_expiry ` .
2017-06-20 15:15:03 +09:30
*/
2017-11-02 10:20:47 +10:30
/* In our case, G = 1, so we need to expire it one after it's expiration.
* But never offer an expired HTLC ; that ' s dumb . */
2018-02-12 20:43:04 +10:30
if ( get_block_height ( ld - > topology ) > = outgoing_cltv_value ) {
log_debug ( hin - > key . channel - > log ,
2017-11-02 10:20:47 +10:30
" Expiry cltv %u too close to current %u " ,
2017-06-20 15:15:03 +09:30
outgoing_cltv_value ,
2018-02-12 20:43:04 +10:30
get_block_height ( ld - > topology ) ) ;
2022-01-25 06:31:52 +10:30
failmsg = towire_expiry_too_soon ( tmpctx ,
2024-01-31 13:46:16 +10:30
channel_update_for_error ( tmpctx , next ) ) ;
2017-06-20 15:15:03 +09:30
goto fail ;
}
2017-11-01 12:51:00 +10:30
/* BOLT #4:
*
2018-06-17 19:43:44 +09:30
* - if the ` cltv_expiry ` is unreasonably far in the future :
* - return an ` expiry_too_far ` error .
2017-11-01 12:51:00 +10:30
*/
2018-02-12 20:43:04 +10:30
if ( get_block_height ( ld - > topology )
2018-05-17 14:16:22 +09:30
+ ld - > config . locktime_max < outgoing_cltv_value ) {
2018-02-12 20:43:04 +10:30
log_debug ( hin - > key . channel - > log ,
2017-10-23 14:46:57 +10:30
" Expiry cltv %u too far from current %u + max %u " ,
outgoing_cltv_value ,
2018-02-12 20:43:04 +10:30
get_block_height ( ld - > topology ) ,
2018-05-17 14:16:22 +09:30
ld - > config . locktime_max ) ;
2020-02-21 15:40:02 +10:30
failmsg = towire_expiry_too_far ( tmpctx ) ;
2017-10-23 14:46:57 +10:30
goto fail ;
}
2020-02-21 15:40:02 +10:30
failmsg = send_htlc_out ( tmpctx , next , amt_to_forward ,
2021-12-07 14:09:28 -06:00
outgoing_cltv_value , AMOUNT_MSAT ( 0 ) ,
& hin - > payment_hash ,
2021-09-29 12:33:57 +02:00
next_blinding , 0 /* partid */ , 0 /* groupid */ ,
2022-01-25 06:31:52 +10:30
next_onion , hin , & hout ) ;
2020-02-21 15:40:02 +10:30
if ( ! failmsg )
2017-06-20 15:44:03 +09:30
return ;
2017-06-20 15:15:03 +09:30
fail :
2022-01-25 06:31:52 +10:30
local_fail_in_htlc ( hin , failmsg ) ;
2019-04-15 22:27:22 +08:00
wallet_forwarded_payment_add ( ld - > wallet ,
2022-09-28 14:19:35 +09:30
hin , FORWARD_STYLE_TLV , forward_scid , hout ,
2019-04-15 22:27:22 +08:00
FORWARD_LOCAL_FAILED ,
2020-02-21 15:40:02 +10:30
fromwire_peektype ( failmsg ) ) ;
2017-06-20 15:15:03 +09:30
}
2019-01-03 17:27:46 +01:00
/**
* Data passed to the plugin , and as the context for the hook callback
*/
struct htlc_accepted_hook_payload {
struct route_step * route_step ;
2019-12-05 20:36:28 +10:30
/* NULL if it couldn't be parsed! */
struct onion_payload * payload ;
2019-01-03 17:27:46 +01:00
struct htlc_in * hin ;
struct channel * channel ;
struct lightningd * ld ;
2020-04-11 12:52:40 +09:30
struct pubkey * next_blinding ;
2022-09-25 22:44:12 +09:30
/* NULL if we couldn't find it */
struct channel_id * fwd_channel_id ;
2019-01-09 16:07:49 +01:00
u8 * next_onion ;
2020-03-04 14:20:59 +01:00
u64 failtlvtype ;
size_t failtlvpos ;
2019-01-03 17:27:46 +01:00
} ;
2020-02-21 15:40:45 +10:30
/* We only handle the simplest cases here */
static u8 * convert_failcode ( const tal_t * ctx ,
struct lightningd * ld ,
unsigned int failure_code )
{
switch ( failure_code ) {
case WIRE_INVALID_REALM :
return towire_invalid_realm ( ctx ) ;
case WIRE_TEMPORARY_NODE_FAILURE :
return towire_temporary_node_failure ( ctx ) ;
case WIRE_PERMANENT_NODE_FAILURE :
return towire_permanent_node_failure ( ctx ) ;
case WIRE_REQUIRED_NODE_FEATURE_MISSING :
return towire_required_node_feature_missing ( ctx ) ;
case WIRE_PERMANENT_CHANNEL_FAILURE :
return towire_permanent_channel_failure ( ctx ) ;
case WIRE_REQUIRED_CHANNEL_FEATURE_MISSING :
return towire_required_channel_feature_missing ( ctx ) ;
case WIRE_UNKNOWN_NEXT_PEER :
return towire_unknown_next_peer ( ctx ) ;
default :
log_broken ( ld - > log ,
" htlc_accepted_hook plugin returned failure_code %u, "
" turning to WIRE_TEMPORARY_NODE_FAILURE " ,
failure_code ) ;
return towire_temporary_node_failure ( ctx ) ;
}
}
2020-03-26 14:25:05 +01:00
static void
htlc_accepted_hook_try_resolve ( struct htlc_accepted_hook_payload * request ,
struct preimage * payment_preimage )
{
struct sha256 payment_hash ;
struct htlc_in * hin = request - > hin ;
u8 * unknown_details ;
/* Verify that the provided secret hashes to what we need. */
sha256 ( & payment_hash , payment_preimage , sizeof ( struct preimage ) ) ;
if ( ! sha256_eq ( & payment_hash , & hin - > payment_hash ) ) {
log_broken (
request - > channel - > log ,
" Plugin returned a preimage (sha256(%s) = %s) that doesn't "
" match the HTLC hash (%s) it tries to resolve. " ,
type_to_string ( tmpctx , struct preimage , payment_preimage ) ,
type_to_string ( tmpctx , struct sha256 , & payment_hash ) ,
type_to_string ( tmpctx , struct sha256 , & hin - > payment_hash ) ) ;
unknown_details = tal_arr ( NULL , u8 , 0 ) ;
towire_u16 ( & unknown_details , 0x400f ) ;
local_fail_in_htlc ( hin , take ( unknown_details ) ) ;
} else {
2020-04-14 14:02:46 -05:00
hin - > we_filled = tal ( hin , bool ) ;
* hin - > we_filled = true ;
2020-03-26 14:25:05 +01:00
fulfill_htlc ( hin , payment_preimage ) ;
}
}
2020-04-07 16:40:30 +09:30
static u8 * prepend_length ( const tal_t * ctx , const u8 * payload TAKES )
{
u8 buf [ BIGSIZE_MAX_LEN ] , * ret ;
size_t len ;
len = bigsize_put ( buf , tal_bytelen ( payload ) ) ;
ret = tal_arr ( ctx , u8 , len + tal_bytelen ( payload ) ) ;
memcpy ( ret , buf , len ) ;
memcpy ( ret + len , payload , tal_bytelen ( payload ) ) ;
if ( taken ( payload ) )
tal_free ( payload ) ;
return ret ;
}
2019-01-03 17:27:46 +01:00
/**
2020-04-15 19:51:34 +09:30
* Callback when a plugin answers to the htlc_accepted hook
2019-01-03 17:27:46 +01:00
*/
2020-04-15 19:51:34 +09:30
static bool htlc_accepted_hook_deserialize ( struct htlc_accepted_hook_payload * request ,
const char * buffer ,
const jsmntok_t * toks )
2019-01-03 17:27:46 +01:00
{
2020-04-07 16:40:30 +09:30
struct route_step * rs = request - > route_step ;
2020-04-15 19:51:34 +09:30
struct htlc_in * hin = request - > hin ;
struct lightningd * ld = request - > ld ;
struct preimage payment_preimage ;
2022-09-25 22:44:12 +09:30
const jsmntok_t * resulttok , * paykeytok , * payloadtok , * fwdtok ;
2022-10-17 11:14:38 +10:30
u8 * failonion ;
2019-01-09 16:12:35 +01:00
if ( ! toks | | ! buffer )
2020-04-15 19:51:34 +09:30
return true ;
2019-01-09 16:12:35 +01:00
resulttok = json_get_member ( buffer , toks , " result " ) ;
/* If the result is "continue" we can just return NULL since
* this is the default behavior for this hook anyway */
if ( ! resulttok ) {
fatal ( " Plugin return value does not contain 'result' key %s " ,
json_strdup ( tmpctx , buffer , toks ) ) ;
}
2020-04-07 16:40:30 +09:30
payloadtok = json_get_member ( buffer , toks , " payload " ) ;
if ( payloadtok ) {
2022-10-17 11:14:38 +10:30
u8 * payload = json_tok_bin_from_hex ( rs , buffer , payloadtok ) ;
2020-04-07 16:40:30 +09:30
if ( ! payload )
fatal ( " Bad payload for htlc_accepted "
" hook: %.*s " ,
payloadtok - > end - payloadtok - > start ,
buffer + payloadtok - > start ) ;
tal_free ( request - > payload ) ;
tal_free ( rs - > raw_payload ) ;
rs - > raw_payload = prepend_length ( rs , take ( payload ) ) ;
2022-10-17 11:14:38 +10:30
request - > payload = onion_decode ( request ,
feature_offered ( ld - > our_features - > bits [ INIT_FEATURE ] ,
OPT_ROUTE_BLINDING ) ,
rs ,
2022-10-17 11:07:05 +10:30
hin - > blinding ,
2021-06-17 13:00:24 +02:00
ld - > accept_extra_tlv_types ,
2022-10-17 11:14:38 +10:30
hin - > msat ,
hin - > cltv_expiry ,
2020-04-07 16:40:30 +09:30
& request - > failtlvtype ,
& request - > failtlvpos ) ;
2022-10-17 11:14:38 +10:30
}
2020-04-07 16:40:30 +09:30
2022-09-25 22:44:12 +09:30
fwdtok = json_get_member ( buffer , toks , " forward_to " ) ;
if ( fwdtok ) {
tal_free ( request - > fwd_channel_id ) ;
request - > fwd_channel_id = tal ( request , struct channel_id ) ;
if ( ! json_to_channel_id ( buffer , fwdtok ,
request - > fwd_channel_id ) ) {
fatal ( " Bad forward_to for htlc_accepted "
" hook: %.*s " ,
fwdtok - > end - fwdtok - > start ,
buffer + fwdtok - > start ) ;
}
}
2019-01-09 16:12:35 +01:00
if ( json_tok_streq ( buffer , resulttok , " continue " ) ) {
2020-04-15 19:51:34 +09:30
return true ;
2019-01-09 16:12:35 +01:00
}
if ( json_tok_streq ( buffer , resulttok , " fail " ) ) {
2020-04-15 19:51:34 +09:30
u8 * failmsg ;
2020-11-10 11:14:06 -03:00
const jsmntok_t * failoniontok , * failmsgtok , * failcodetok ;
2019-01-09 16:12:35 +01:00
2020-11-10 13:42:38 -06:00
failoniontok = json_get_member ( buffer , toks , " failure_onion " ) ;
failmsgtok = json_get_member ( buffer , toks , " failure_message " ) ;
if ( failoniontok ) {
failonion = json_tok_bin_from_hex ( tmpctx , buffer ,
failoniontok ) ;
2020-11-06 18:12:42 -03:00
if ( ! failonion )
fatal ( " Bad failure_onion for htlc_accepted "
" hook: %.*s " ,
failoniontok - > end - failoniontok - > start ,
buffer + failoniontok - > start ) ;
2020-11-10 13:42:38 -06:00
if ( failmsgtok )
log_broken ( ld - > log , " Both 'failure_onion' and "
" 'failure_message' provided. "
" Ignoring 'failure_message'. " ) ;
fail_in_htlc ( hin , take ( new_onionreply ( NULL ,
failonion ) ) ) ;
2020-11-06 18:12:42 -03:00
return false ;
2020-11-10 11:14:06 -03:00
}
2020-11-10 13:42:38 -06:00
if ( failmsgtok ) {
2020-11-10 11:14:06 -03:00
failmsg = json_tok_bin_from_hex ( NULL , buffer ,
failmsgtok ) ;
if ( ! failmsg )
fatal ( " Bad failure_message for htlc_accepted "
" hook: %.*s " ,
failmsgtok - > end - failmsgtok - > start ,
buffer + failmsgtok - > start ) ;
local_fail_in_htlc ( hin , take ( failmsg ) ) ;
return false ;
2024-01-25 10:58:55 +10:30
} else if ( ( failcodetok = json_get_member ( buffer , toks ,
" failure_code " ) )
& & lightningd_deprecated_in_ok ( ld , ld - > log , ld - > deprecated_ok ,
" htlc_accepted_hook " , " failure_code " ,
" v0.8 " , " v24.02 " , NULL ) ) {
2020-02-21 15:40:45 +10:30
unsigned int failcode ;
if ( ! json_to_number ( buffer , failcodetok , & failcode ) )
fatal ( " Bad failure_code for htlc_accepted "
" hook: %.*s " ,
failcodetok - > end
- failcodetok - > start ,
buffer + failcodetok - > start ) ;
2020-04-15 19:51:34 +09:30
failmsg = convert_failcode ( NULL , ld , failcode ) ;
2020-11-10 11:14:06 -03:00
local_fail_in_htlc ( hin , take ( failmsg ) ) ;
return false ;
} else {
2020-04-15 19:51:34 +09:30
failmsg = towire_temporary_node_failure ( NULL ) ;
2020-11-10 11:14:06 -03:00
local_fail_in_htlc ( hin , take ( failmsg ) ) ;
return false ;
}
2019-01-09 16:12:35 +01:00
} else if ( json_tok_streq ( buffer , resulttok , " resolve " ) ) {
paykeytok = json_get_member ( buffer , toks , " payment_key " ) ;
if ( ! paykeytok )
fatal (
" Plugin did not specify a 'payment_key' in return "
" value to the htlc_accepted hook: %s " ,
json_strdup ( tmpctx , buffer , resulttok ) ) ;
2020-04-15 19:51:34 +09:30
if ( ! json_to_preimage ( buffer , paykeytok , & payment_preimage ) )
2019-01-09 16:12:35 +01:00
fatal ( " Plugin specified an invalid 'payment_key': %s " ,
json_tok_full ( buffer , resulttok ) ) ;
2020-03-26 14:25:05 +01:00
htlc_accepted_hook_try_resolve ( request , & payment_preimage ) ;
2020-04-15 19:51:34 +09:30
return false ;
2019-01-09 16:12:35 +01:00
} else {
fatal ( " Plugin responded with an unknown result to the "
" htlc_accepted hook: %s " ,
json_strdup ( tmpctx , buffer , resulttok ) ) ;
}
2019-01-03 17:27:46 +01:00
}
static void htlc_accepted_hook_serialize ( struct htlc_accepted_hook_payload * p ,
2021-06-02 17:33:23 +02:00
struct json_stream * s ,
struct plugin * plugin )
2019-01-03 17:27:46 +01:00
{
2019-01-09 16:07:49 +01:00
const struct route_step * rs = p - > route_step ;
2021-06-02 18:04:01 +02:00
struct htlc_in * hin = p - > hin ;
2019-02-21 14:21:28 +01:00
s32 expiry = hin - > cltv_expiry , blockheight = p - > ld - > topology - > tip - > height ;
2021-06-02 18:04:01 +02:00
tal_free ( hin - > status ) ;
hin - > status =
tal_fmt ( hin , " Waiting for the htlc_accepted hook of plugin %s " ,
plugin - > shortname ) ;
2019-01-09 16:07:49 +01:00
json_object_start ( s , " onion " ) ;
2019-12-05 20:36:28 +10:30
json_add_hex_talarr ( s , " payload " , rs - > raw_payload ) ;
if ( p - > payload ) {
2022-09-28 14:19:35 +09:30
json_add_string ( s , " type " , " tlv " ) ;
2019-01-09 16:07:49 +01:00
2019-12-05 20:36:28 +10:30
if ( p - > payload - > forward_channel )
json_add_short_channel_id ( s , " short_channel_id " ,
p - > payload - > forward_channel ) ;
2022-11-09 12:00:10 +10:30
if ( p - > payload - > forward_node_id )
json_add_pubkey ( s , " next_node_id " ,
p - > payload - > forward_node_id ) ;
2023-03-14 15:51:50 +10:30
json_add_amount_msat ( s , " forward_msat " ,
p - > payload - > amt_to_forward ) ;
2019-12-05 20:36:28 +10:30
json_add_u32 ( s , " outgoing_cltv_value " , p - > payload - > outgoing_cltv ) ;
/* These are specified together in TLV, so only print total_msat
* if payment_secret set ( ie . modern , and final hop ) */
if ( p - > payload - > payment_secret ) {
2023-03-14 15:51:50 +10:30
json_add_amount_msat ( s , " total_msat " ,
* p - > payload - > total_msat ) ;
2019-12-05 20:36:28 +10:30
json_add_secret ( s , " payment_secret " ,
p - > payload - > payment_secret ) ;
}
2022-03-31 19:40:50 +10:30
if ( p - > payload - > payment_metadata ) {
json_add_hex_talarr ( s , " payment_metadata " ,
p - > payload - > payment_metadata ) ;
}
2019-11-23 10:49:23 +10:30
}
2019-01-09 16:07:49 +01:00
json_add_hex_talarr ( s , " next_onion " , p - > next_onion ) ;
2019-06-08 10:58:31 +02:00
json_add_secret ( s , " shared_secret " , hin - > shared_secret ) ;
2019-01-09 16:07:49 +01:00
json_object_end ( s ) ;
2022-09-25 22:44:12 +09:30
if ( p - > fwd_channel_id )
json_add_channel_id ( s , " forward_to " , p - > fwd_channel_id ) ;
2019-01-09 16:07:49 +01:00
json_object_start ( s , " htlc " ) ;
2022-06-29 12:41:12 +02:00
json_add_short_channel_id (
s , " short_channel_id " ,
channel_scid_or_local_alias ( hin - > key . channel ) ) ;
2022-06-01 22:36:11 -03:00
json_add_u64 ( s , " id " , hin - > key . id ) ;
2023-03-14 15:51:50 +10:30
json_add_amount_msat ( s , " amount_msat " , hin - > msat ) ;
2019-02-21 14:21:28 +01:00
json_add_u32 ( s , " cltv_expiry " , expiry ) ;
json_add_s32 ( s , " cltv_expiry_relative " , expiry - blockheight ) ;
2019-08-10 16:39:04 +08:00
json_add_sha256 ( s , " payment_hash " , & hin - > payment_hash ) ;
2019-01-09 16:07:49 +01:00
json_object_end ( s ) ;
2019-01-03 17:27:46 +01:00
}
/**
* Callback when a plugin answers to the htlc_accepted hook
*/
static void
2020-04-15 19:51:34 +09:30
htlc_accepted_hook_final ( struct htlc_accepted_hook_payload * request STEALS )
2019-01-03 17:27:46 +01:00
{
struct route_step * rs = request - > route_step ;
struct htlc_in * hin = request - > hin ;
struct channel * channel = request - > channel ;
2020-04-15 19:51:34 +09:30
2021-06-04 10:47:47 +02:00
request - > hin - > status = tal_free ( request - > hin - > status ) ;
2021-06-17 15:16:55 +02:00
/* Hand the payload to the htlc_in since we'll want to have that info
* handy for the hooks and notifications . */
request - > hin - > payload = tal_steal ( request - > hin , request - > payload ) ;
2020-04-15 19:51:34 +09:30
/* *Now* we barf if it failed to decode */
if ( ! request - > payload ) {
2019-01-09 16:12:35 +01:00
log_debug ( channel - > log ,
2020-04-15 19:51:34 +09:30
" Failing HTLC because of an invalid payload " ) ;
local_fail_in_htlc ( hin ,
take ( towire_invalid_onion_payload (
NULL , request - > failtlvtype ,
request - > failtlvpos ) ) ) ;
} else if ( rs - > nextcase = = ONION_FORWARD ) {
forward_htlc ( hin , hin - > cltv_expiry ,
request - > payload - > amt_to_forward ,
request - > payload - > outgoing_cltv ,
request - > payload - > forward_channel ,
2022-09-25 22:44:12 +09:30
request - > fwd_channel_id ,
2020-04-15 19:51:34 +09:30
serialize_onionpacket ( tmpctx , rs - > next ) ,
request - > next_blinding ) ;
} else
handle_localpay ( hin ,
request - > payload - > amt_to_forward ,
request - > payload - > outgoing_cltv ,
* request - > payload - > total_msat ,
2022-03-31 19:40:50 +10:30
request - > payload - > payment_secret ,
request - > payload - > payment_metadata ) ;
2019-01-03 17:27:46 +01:00
tal_free ( request ) ;
}
2020-04-11 12:52:40 +09:30
/* Apply tweak to ephemeral key if blinding is non-NULL, then do ECDH */
static bool ecdh_maybe_blinding ( const struct pubkey * ephemeral_key ,
const struct pubkey * blinding ,
struct secret * ss )
{
struct pubkey point = * ephemeral_key ;
if ( blinding ) {
struct secret hmac ;
2022-10-17 11:07:05 +10:30
struct secret blinding_ss ;
2020-04-11 12:52:40 +09:30
2022-10-17 11:07:05 +10:30
ecdh ( blinding , & blinding_ss ) ;
2020-04-11 12:52:40 +09:30
/* b(i) = HMAC256("blinded_node_id", ss(i)) * k(i) */
2022-10-17 11:07:05 +10:30
subkey_from_hmac ( " blinded_node_id " , & blinding_ss , & hmac ) ;
2020-04-11 12:52:40 +09:30
/* We instead tweak the *ephemeral* key from the onion and use
* our normal privkey : since hsmd knows only how to ECDH with
* our real key */
if ( secp256k1_ec_pubkey_tweak_mul ( secp256k1_ctx ,
& point . pubkey ,
hmac . data ) ! = 1 ) {
return false ;
}
}
ecdh ( & point , ss ) ;
return true ;
}
2020-12-22 13:28:55 -06:00
REGISTER_PLUGIN_HOOK ( htlc_accepted ,
htlc_accepted_hook_deserialize ,
htlc_accepted_hook_final ,
htlc_accepted_hook_serialize ,
struct htlc_accepted_hook_payload * ) ;
2022-09-25 22:44:12 +09:30
/* Figures out how to fwd, allocating return off hp */
static struct channel_id * calc_forwarding_channel ( struct lightningd * ld ,
2023-01-12 14:22:38 +10:30
struct htlc_accepted_hook_payload * hp )
2022-09-25 22:44:12 +09:30
{
const struct onion_payload * p = hp - > payload ;
2022-11-09 12:00:10 +10:30
struct peer * peer ;
2022-09-25 22:44:12 +09:30
struct channel * c , * best ;
2023-01-12 14:22:38 +10:30
if ( ! p )
2022-09-25 22:44:12 +09:30
return NULL ;
2023-01-12 14:22:38 +10:30
if ( p - > final )
2022-09-25 22:44:12 +09:30
return NULL ;
2022-11-09 12:00:10 +10:30
if ( p - > forward_channel ) {
2023-01-05 12:11:36 +01:00
log_debug ( hp - > channel - > log ,
" Looking up channel by scid=%s to forward htlc_id=% " PRIu64 ,
type_to_string ( tmpctx , struct short_channel_id ,
p - > forward_channel ) ,
hp - > hin - > key . id ) ;
2022-11-09 12:00:10 +10:30
c = any_channel_by_scid ( ld , p - > forward_channel , false ) ;
2023-01-05 12:11:36 +01:00
if ( ! c ) {
log_unusual ( hp - > channel - > log , " No peer channel with scid=%s " ,
type_to_string ( tmpctx , struct short_channel_id ,
p - > forward_channel ) ) ;
2022-11-09 12:00:10 +10:30
return NULL ;
2023-01-05 12:11:36 +01:00
}
2022-11-09 12:00:10 +10:30
peer = c - > peer ;
} else {
struct node_id id ;
2023-01-05 12:11:36 +01:00
if ( ! p - > forward_node_id ) {
log_unusual ( hp - > channel - > log ,
" Neither forward_channel nor "
" forward_node_id was set in payload " ) ;
2022-11-09 12:00:10 +10:30
return NULL ;
2023-01-05 12:11:36 +01:00
}
2022-11-09 12:00:10 +10:30
node_id_from_pubkey ( & id , p - > forward_node_id ) ;
peer = peer_by_id ( ld , & id ) ;
2023-01-05 12:11:36 +01:00
log_debug ( hp - > channel - > log , " Looking up peer by node_id=%s " ,
type_to_string ( tmpctx , struct node_id , & id ) ) ;
if ( ! peer ) {
log_unusual (
hp - > channel - > log , " No peer with node_id=%s " ,
type_to_string ( tmpctx , struct node_id , & id ) ) ;
2022-11-09 12:00:10 +10:30
return NULL ;
2023-01-05 12:11:36 +01:00
}
2022-11-09 12:00:10 +10:30
c = NULL ;
}
2022-09-25 22:44:12 +09:30
2022-11-09 12:00:10 +10:30
best = best_channel ( ld , peer , p - > amt_to_forward , c ) ;
if ( ! c ) {
if ( ! best )
return NULL ;
log_debug ( hp - > channel - > log ,
" Chose channel %s for peer %s " ,
type_to_string ( tmpctx , struct short_channel_id ,
channel_scid_or_local_alias ( best ) ) ,
type_to_string ( tmpctx , struct node_id ,
& peer - > id ) ) ;
} else if ( best ! = c ) {
2022-09-25 22:44:12 +09:30
log_debug ( hp - > channel - > log ,
" Chose a better channel than %s: %s " ,
type_to_string ( tmpctx , struct short_channel_id ,
p - > forward_channel ) ,
type_to_string ( tmpctx , struct short_channel_id ,
channel_scid_or_local_alias ( best ) ) ) ;
}
2023-01-05 12:11:36 +01:00
log_debug ( hp - > channel - > log ,
" Decided to forward htlc_id=% " PRIu64
" over channel with scid=%s with peer %s " ,
hp - > hin - > key . id ,
type_to_string ( tmpctx , struct short_channel_id ,
channel_scid_or_local_alias ( best ) ) ,
type_to_string ( tmpctx , struct node_id , & best - > peer - > id ) ) ;
2022-09-25 22:44:12 +09:30
return tal_dup ( hp , struct channel_id , & best - > cid ) ;
}
2019-05-21 17:48:51 +02:00
/**
* Everyone is committed to this htlc of theirs
*
2020-02-21 15:38:31 +10:30
* @ param ctx : context for failmsg , if any .
2019-05-21 17:48:51 +02:00
* @ param channel : The channel this HTLC was accepted from .
* @ param id : the ID of the HTLC we accepted
* @ param replay : Are we loading from the database and therefore should not
* perform the transition to RCVD_ADD_ACK_REVOCATION ?
2020-02-21 15:38:31 +10:30
* @ param [ out ] badonion : Set non - zero if the onion was bad .
* @ param [ out ] failmsg : If there was some other error .
*
* If this returns false , exactly one of @ badonion or @ failmsg is set .
2019-05-21 17:48:51 +02:00
*/
2020-02-21 15:38:31 +10:30
static bool peer_accepted_htlc ( const tal_t * ctx ,
struct channel * channel , u64 id ,
bool replay ,
2020-08-31 10:43:25 +09:30
enum onion_wire * badonion ,
2020-02-21 15:38:31 +10:30
u8 * * failmsg )
2017-06-20 15:15:03 +09:30
{
2017-06-20 15:23:03 +09:30
struct htlc_in * hin ;
2017-06-20 15:15:03 +09:30
struct route_step * rs ;
2020-12-08 21:05:32 +10:30
struct onionpacket * op ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2019-01-03 17:27:46 +01:00
struct htlc_accepted_hook_payload * hook_payload ;
2022-10-17 11:14:39 +10:30
const bool opt_blinding
= feature_offered ( ld - > our_features - > bits [ INIT_FEATURE ] ,
OPT_ROUTE_BLINDING ) ;
2017-06-20 15:20:03 +09:30
2020-02-21 15:38:31 +10:30
* failmsg = NULL ;
* badonion = 0 ;
2023-01-03 15:16:52 +10:30
hin = find_htlc_in ( ld - > htlcs_in , channel , id ) ;
2017-06-20 15:23:03 +09:30
if ( ! hin ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel ,
2017-06-20 15:47:03 +09:30
" peer_got_revoke unknown htlc % " PRIu64 , id ) ;
2020-02-21 15:38:31 +10:30
* failmsg = towire_temporary_node_failure ( ctx ) ;
2020-04-11 12:52:40 +09:30
goto fail ;
2017-06-20 15:15:03 +09:30
}
2021-09-28 14:08:11 -05:00
if ( hin - > fail_immediate & & htlc_in_update_state ( channel , hin , RCVD_ADD_ACK_REVOCATION ) ) {
log_debug ( channel - > log , " failing immediately, as requested " ) ;
/* Failing the htlc, typically done because of htlc dust */
* failmsg = towire_temporary_node_failure ( ctx ) ;
goto fail ;
}
2020-02-21 15:38:31 +10:30
if ( ! replay & & ! htlc_in_update_state ( channel , hin , RCVD_ADD_ACK_REVOCATION ) ) {
* failmsg = towire_temporary_node_failure ( ctx ) ;
2020-04-11 12:52:40 +09:30
goto fail ;
2020-02-21 15:38:31 +10:30
}
2018-10-09 19:15:52 +10:30
htlc_in_check ( hin , __func__ ) ;
2017-06-20 15:20:03 +09:30
2023-09-21 15:06:28 +09:30
if ( channel - > peer - > dev_ignore_htlcs ) {
2018-04-03 16:49:42 +09:30
log_debug ( channel - > log , " their htlc % " PRIu64 " dev_ignore_htlcs " ,
id ) ;
return true ;
}
2023-09-21 15:06:28 +09:30
2017-06-26 10:52:56 +09:30
/* BOLT #2:
*
2018-06-17 19:43:44 +09:30
* - SHOULD fail to route any HTLC added after it has sent ` shutdown ` .
*/
2023-10-02 09:29:51 +10:30
if ( ! channel_state_can_add_htlc ( channel - > state ) ) {
2020-02-21 15:38:31 +10:30
* failmsg = towire_permanent_channel_failure ( ctx ) ;
log_debug ( channel - > log ,
" Rejecting their htlc % " PRIu64
" since we're shutting down " ,
id ) ;
2020-04-11 12:52:40 +09:30
goto fail ;
2017-06-26 10:52:56 +09:30
}
2017-11-02 10:22:39 +10:30
/* BOLT #2:
*
2018-06-17 19:43:44 +09:30
* A fulfilling node :
* - for each HTLC it is attempting to fulfill :
* - MUST estimate a fulfillment deadline .
* - MUST fail ( and not forward ) an HTLC whose fulfillment deadline is
* already past .
2017-11-02 10:22:39 +10:30
*/
/* Our deadline is half the cltv_delta we insist on, so this check is
* a subset of the cltv check done in handle_localpay and
* forward_htlc . */
2020-12-08 21:05:32 +10:30
op = parse_onionpacket ( tmpctx , hin - > onion_routing_packet ,
sizeof ( hin - > onion_routing_packet ) ,
badonion ) ;
if ( ! op ) {
2020-02-21 15:38:31 +10:30
log_debug ( channel - > log ,
" Rejecting their htlc % " PRIu64
" since onion is unparsable %s " ,
2020-08-31 10:43:25 +09:30
id , onion_wire_name ( * badonion ) ) ;
2020-02-18 10:28:58 +10:30
/* Now we can fail it. */
2020-04-11 12:52:40 +09:30
goto fail ;
2017-06-20 15:20:03 +09:30
}
2017-06-20 15:15:03 +09:30
2020-12-08 21:05:32 +10:30
rs = process_onionpacket ( tmpctx , op , hin - > shared_secret ,
2017-06-20 15:23:03 +09:30
hin - > payment_hash . u . u8 ,
2020-03-12 10:29:01 +10:30
sizeof ( hin - > payment_hash ) , true ) ;
2017-06-20 15:15:03 +09:30
if ( ! rs ) {
2020-02-21 15:38:31 +10:30
* badonion = WIRE_INVALID_ONION_HMAC ;
log_debug ( channel - > log ,
" Rejecting their htlc % " PRIu64
2020-04-11 12:52:40 +09:30
" since onion is unprocessable %s ss=%s " ,
2020-08-31 10:43:25 +09:30
id , onion_wire_name ( * badonion ) ,
2020-04-11 12:52:40 +09:30
type_to_string ( tmpctx , struct secret , hin - > shared_secret ) ) ;
goto fail ;
2017-06-20 15:15:03 +09:30
}
2020-04-15 19:50:41 +09:30
hook_payload = tal ( NULL , struct htlc_accepted_hook_payload ) ;
2019-11-14 10:45:53 +10:30
2019-01-03 17:27:46 +01:00
hook_payload - > route_step = tal_steal ( hook_payload , rs ) ;
2022-10-17 11:14:38 +10:30
hook_payload - > payload = onion_decode ( hook_payload ,
feature_offered ( ld - > our_features - > bits [ INIT_FEATURE ] ,
OPT_ROUTE_BLINDING ) ,
rs ,
2022-10-17 11:07:05 +10:30
hin - > blinding ,
2021-06-17 13:00:24 +02:00
ld - > accept_extra_tlv_types ,
2022-10-17 11:14:38 +10:30
hin - > msat ,
hin - > cltv_expiry ,
2020-03-04 14:20:59 +01:00
& hook_payload - > failtlvtype ,
& hook_payload - > failtlvpos ) ;
2019-01-03 17:27:46 +01:00
hook_payload - > ld = ld ;
hook_payload - > hin = hin ;
hook_payload - > channel = channel ;
2019-01-09 16:07:49 +01:00
hook_payload - > next_onion = serialize_onionpacket ( hook_payload , rs - > next ) ;
2020-04-11 12:52:40 +09:30
/* We could have blinding from hin or from inside onion. */
2022-10-17 11:14:39 +10:30
if ( opt_blinding
& & hook_payload - > payload & & hook_payload - > payload - > blinding ) {
2020-04-11 12:52:40 +09:30
struct sha256 sha ;
blinding_hash_e_and_ss ( hook_payload - > payload - > blinding ,
& hook_payload - > payload - > blinding_ss ,
& sha ) ;
hook_payload - > next_blinding = tal ( hook_payload , struct pubkey ) ;
blinding_next_pubkey ( hook_payload - > payload - > blinding , & sha ,
hook_payload - > next_blinding ) ;
} else
hook_payload - > next_blinding = NULL ;
2022-09-25 22:44:12 +09:30
/* The scid is merely used to indicate the next peer, it is not
* a requirement ( nor , ideally , observable anyway ) . We can change
* to a more - preferred one now , that way the hook sees the value
* we ' re actually going to ( try to ) use */
/* We don't store actual channel as it could vanish while
* we ' re in hook */
hook_payload - > fwd_channel_id
2023-01-12 14:22:38 +10:30
= calc_forwarding_channel ( ld , hook_payload ) ;
2022-09-25 22:44:12 +09:30
2022-09-13 06:49:12 +09:30
plugin_hook_call_htlc_accepted ( ld , NULL , hook_payload ) ;
2017-06-20 15:20:03 +09:30
2019-01-03 17:27:46 +01:00
/* Falling through here is ok, after all the HTLC locked */
2017-06-20 15:20:03 +09:30
return true ;
2020-04-11 12:52:40 +09:30
fail :
/* In a blinded path, *all* failures are "invalid_onion_blinding" */
if ( hin - > blinding ) {
* failmsg = tal_free ( * failmsg ) ;
* badonion = WIRE_INVALID_ONION_BLINDING ;
}
return false ;
2017-06-20 15:15:03 +09:30
}
2018-02-12 20:43:04 +10:30
static void fulfill_our_htlc_out ( struct channel * channel , struct htlc_out * hout ,
2017-08-23 11:25:16 +09:30
const struct preimage * preimage )
{
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2020-04-14 14:02:46 -05:00
bool we_filled = false ;
2018-02-12 20:43:04 +10:30
2018-01-02 14:18:22 +10:30
assert ( ! hout - > preimage ) ;
2017-08-23 11:25:16 +09:30
hout - > preimage = tal_dup ( hout , struct preimage , preimage ) ;
htlc_out_check ( hout , __func__ ) ;
2018-10-09 19:26:52 +10:30
wallet_htlc_update ( ld - > wallet , hout - > dbid , hout - > hstate ,
2021-10-13 14:15:30 +10:30
hout - > preimage ,
max_unsigned ( channel - > next_index [ LOCAL ] ,
channel - > next_index [ REMOTE ] ) ,
0 , hout - > failonion ,
2020-04-14 14:02:46 -05:00
hout - > failmsg , & we_filled ) ;
2018-03-24 08:26:08 +00:00
/* Update channel stats */
wallet_channel_stats_incr_out_fulfilled ( ld - > wallet ,
channel - > dbid ,
2019-02-21 14:15:55 +10:30
hout - > msat ) ;
2017-08-23 11:25:16 +09:30
2018-10-10 06:51:31 +10:30
if ( hout - > am_origin )
2023-07-22 20:56:27 +09:30
payment_succeeded ( ld , & hout - > payment_hash , hout - > partid , hout - > groupid , preimage ) ;
2018-10-17 00:16:50 +02:00
else if ( hout - > in ) {
2023-07-27 16:42:20 +09:30
/* Did we abandon the incoming? Oops! */
if ( hout - > in - > failonion ) {
/* FIXME: Accounting? */
log_unusual ( channel - > log , " FUNDS LOSS of %s: peer took funds onchain before we could time out the HTLC, but we abandoned incoming HTLC to save the incoming channel " ,
fmt_amount_msat ( tmpctx , hout - > msat ) ) ;
} else {
fulfill_htlc ( hout - > in , preimage ) ;
wallet_forwarded_payment_add ( ld - > wallet , hout - > in ,
FORWARD_STYLE_TLV ,
channel_scid_or_local_alias ( hout - > key . channel ) , hout ,
FORWARD_SETTLED , 0 ) ;
}
2018-10-17 00:16:50 +02:00
}
2017-08-23 11:25:16 +09:30
}
2018-02-12 20:42:55 +10:30
static bool peer_fulfilled_our_htlc ( struct channel * channel ,
2017-06-20 15:20:03 +09:30
const struct fulfilled_htlc * fulfilled )
2017-06-20 15:15:03 +09:30
{
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2017-06-20 15:23:03 +09:30
struct htlc_out * hout ;
2017-06-20 15:15:03 +09:30
2023-01-03 15:16:52 +10:30
hout = find_htlc_out ( ld - > htlcs_out , channel , fulfilled - > id ) ;
2017-06-20 15:23:03 +09:30
if ( ! hout ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel ,
2017-06-20 15:47:03 +09:30
" fulfilled_our_htlc unknown htlc % " PRIu64 ,
fulfilled - > id ) ;
2017-06-20 15:20:03 +09:30
return false ;
2017-06-20 15:15:03 +09:30
}
2018-02-12 20:43:04 +10:30
if ( ! htlc_out_update_state ( channel , hout , RCVD_REMOVE_COMMIT ) )
2017-06-20 15:20:03 +09:30
return false ;
2018-02-12 20:43:04 +10:30
fulfill_our_htlc_out ( channel , hout , & fulfilled - > payment_preimage ) ;
2017-08-23 11:25:16 +09:30
return true ;
}
2017-06-20 15:20:03 +09:30
2018-02-12 20:43:04 +10:30
void onchain_fulfilled_htlc ( struct channel * channel ,
const struct preimage * preimage )
2017-08-23 11:25:16 +09:30
{
struct htlc_out_map_iter outi ;
struct htlc_out * hout ;
struct sha256 payment_hash ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2017-06-20 15:20:03 +09:30
2017-08-23 11:25:16 +09:30
sha256 ( & payment_hash , preimage , sizeof ( * preimage ) ) ;
/* FIXME: use db to look this up! */
2023-01-03 15:16:52 +10:30
for ( hout = htlc_out_map_first ( ld - > htlcs_out , & outi ) ;
2017-08-23 11:25:16 +09:30
hout ;
2023-01-03 15:16:52 +10:30
hout = htlc_out_map_next ( ld - > htlcs_out , & outi ) ) {
2018-02-12 20:43:04 +10:30
if ( hout - > key . channel ! = channel )
2017-08-23 11:25:16 +09:30
continue ;
2018-02-14 16:38:54 +10:30
/* It's possible that we failed some and succeeded one,
* if we got multiple errors . */
2020-02-21 15:36:58 +10:30
if ( hout - > failmsg | | hout - > failonion )
2018-02-14 16:38:54 +10:30
continue ;
2018-07-04 15:00:02 +09:30
if ( ! sha256_eq ( & hout - > payment_hash , & payment_hash ) )
2017-08-23 11:25:16 +09:30
continue ;
2018-01-02 14:18:22 +10:30
/* We may have already fulfilled before going onchain, or
* we can fulfill onchain multiple times . */
2018-10-09 19:15:52 +10:30
if ( ! hout - > preimage ) {
/* Force state to something which allows a preimage */
hout - > hstate = RCVD_REMOVE_HTLC ;
2018-02-12 20:43:04 +10:30
fulfill_our_htlc_out ( channel , hout , preimage ) ;
2018-10-09 19:15:52 +10:30
}
2018-01-02 14:18:22 +10:30
2017-08-23 11:25:16 +09:30
/* We keep going: this is something of a leak, but onchain
* we have no real way of distinguishing HTLCs anyway */
}
2017-06-20 15:15:03 +09:30
}
2018-02-12 20:42:55 +10:30
static bool peer_failed_our_htlc ( struct channel * channel ,
2017-06-20 15:20:03 +09:30
const struct failed_htlc * failed )
2017-06-20 15:15:03 +09:30
{
2017-06-20 15:23:03 +09:30
struct htlc_out * hout ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2017-06-20 15:15:03 +09:30
2023-01-03 15:16:52 +10:30
hout = find_htlc_out ( ld - > htlcs_out , channel , failed - > id ) ;
2017-06-20 15:23:03 +09:30
if ( ! hout ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel ,
2017-06-20 15:47:03 +09:30
" failed_our_htlc unknown htlc % " PRIu64 ,
failed - > id ) ;
2017-06-20 15:20:03 +09:30
return false ;
}
2018-02-12 20:43:04 +10:30
if ( ! htlc_out_update_state ( channel , hout , RCVD_REMOVE_COMMIT ) )
2017-06-20 15:20:03 +09:30
return false ;
2020-02-18 10:28:58 +10:30
if ( failed - > sha256_of_onion ) {
struct sha256 our_sha256_of_onion ;
2020-02-21 15:36:58 +10:30
u8 * failmsg ;
2020-02-18 10:28:58 +10:30
/* BOLT #2:
*
* - if the ` sha256_of_onion ` in ` update_fail_malformed_htlc `
2023-09-12 13:53:19 +09:30
* doesn ' t match the onion it sent and is not all zero :
2020-02-18 10:28:58 +10:30
* - MAY retry or choose an alternate error response .
*/
sha256 ( & our_sha256_of_onion , hout - > onion_routing_packet ,
sizeof ( hout - > onion_routing_packet ) ) ;
2023-09-12 13:53:19 +09:30
if ( ! sha256_eq ( failed - > sha256_of_onion , & our_sha256_of_onion )
& & ! memeqzero ( failed - > sha256_of_onion ,
sizeof ( failed - > sha256_of_onion ) ) ) {
2020-02-18 10:28:58 +10:30
log_unusual ( channel - > log ,
" update_fail_malformed_htlc for bad onion "
" for htlc with id % " PRIu64 " . " ,
hout - > key . id ) ;
2023-09-12 13:53:19 +09:30
}
2020-02-18 10:28:58 +10:30
/* BOLT #2:
*
* - otherwise , a receiving node which has an outgoing HTLC
* canceled by ` update_fail_malformed_htlc ` :
*
* - MUST return an error in the ` update_fail_htlc `
* sent to the link which originally sent the HTLC , using the
* ` failure_code ` given and setting the data to
* ` sha256_of_onion ` .
*/
2020-02-21 15:36:58 +10:30
/* All badonion codes are the same form, so we make them
* manually , which covers any unknown cases too . Grep fodder :
* towire_invalid_onion_version , towire_invalid_onion_hmac ,
* towire_invalid_onion_key . */
failmsg = tal_arr ( hout , u8 , 0 ) ;
towire_u16 ( & failmsg , failed - > badonion ) ;
towire_sha256 ( & failmsg , failed - > sha256_of_onion ) ;
hout - > failmsg = failmsg ;
2020-02-18 10:28:58 +10:30
} else {
hout - > failonion = dup_onionreply ( hout , failed - > onion ) ;
}
2017-11-28 15:33:04 +10:30
2018-02-12 20:43:04 +10:30
log_debug ( channel - > log , " Our HTLC % " PRIu64 " failed (%u) " , failed - > id ,
2020-02-21 15:36:58 +10:30
fromwire_peektype ( hout - > failmsg ) ) ;
2017-06-20 15:23:03 +09:30
htlc_out_check ( hout , __func__ ) ;
2018-10-17 00:16:50 +02:00
if ( hout - > in )
2019-04-15 22:27:22 +08:00
wallet_forwarded_payment_add ( ld - > wallet , hout - > in ,
2022-09-28 14:19:35 +09:30
FORWARD_STYLE_TLV ,
2022-07-09 12:53:23 +09:30
channel_scid_or_local_alias ( channel ) ,
2020-02-21 15:36:58 +10:30
hout , FORWARD_FAILED ,
hout - > failmsg
? fromwire_peektype ( hout - > failmsg )
: 0 ) ;
2018-10-17 00:16:50 +02:00
2017-06-20 15:20:03 +09:30
return true ;
}
2022-03-30 14:13:12 +10:30
/* We've had a bug report about not failing incoming HTLCs. This does a sanity
* check , if we think we ' ve already failed this HTLC */
static void check_already_failed ( const struct channel * channel , struct htlc_out * hout )
{
htlc_out_check ( hout , __func__ ) ;
if ( ! hout - > in )
return ;
/* in should have been failed/succeeded already */
if ( hout - > in - > badonion ! = 0
| | hout - > in - > failonion
| | hout - > in - > preimage )
return ;
/* Print out what we think this htlc already has (failed/succeeded) */
log_broken ( channel - > log , " HTLC id % " PRIu64 " already complete, but ->in not resolved! "
" failonion = %s, failmsg = %s, preimage = %s " ,
hout - > key . id ,
hout - > failonion ? tal_hex ( tmpctx , hout - > failonion - > contents ) : " (null) " ,
hout - > failmsg ? tal_hex ( tmpctx , hout - > failmsg ) : " (null) " ,
hout - > preimage ? type_to_string ( tmpctx , struct preimage , hout - > preimage ) : " (null) " ) ;
if ( hout - > preimage ) {
/* Log on both ours and theirs! */
log_broken ( channel - > log ,
" MISSING incoming success for % " PRIu64 " : succeeding incoming now " ,
hout - > key . id ) ;
log_broken ( hout - > in - > key . channel - > log ,
" MISSED incoming success for % " PRIu64 " : succeeding now " ,
hout - > in - > key . id ) ;
fulfill_htlc ( hout - > in , hout - > preimage ) ;
} else {
log_broken ( channel - > log ,
" MISSING incoming fail for % " PRIu64 " : failing incoming now " ,
hout - > key . id ) ;
log_broken ( hout - > in - > key . channel - > log ,
" MISSED incoming fail for % " PRIu64 " : failing now " ,
hout - > in - > key . id ) ;
local_fail_in_htlc ( hout - > in ,
take ( towire_permanent_channel_failure ( NULL ) ) ) ;
}
}
/* This case searches harder to see if there are any incoming HTLCs */
static void fail_dangling_htlc_in ( struct lightningd * ld ,
const struct sha256 * payment_hash )
{
struct htlc_in * hin ;
struct htlc_in_map_iter ini ;
2023-01-03 15:16:52 +10:30
for ( hin = htlc_in_map_first ( ld - > htlcs_in , & ini ) ;
2022-03-30 14:13:12 +10:30
hin ;
2023-01-03 15:16:52 +10:30
hin = htlc_in_map_next ( ld - > htlcs_in , & ini ) ) {
2022-03-30 14:13:12 +10:30
if ( ! sha256_eq ( & hin - > payment_hash , payment_hash ) )
continue ;
if ( hin - > badonion ) {
log_broken ( hin - > key . channel - > log ,
" htlc % " PRIu64 " already failed with badonion " ,
hin - > key . id ) ;
} else if ( hin - > preimage ) {
log_broken ( hin - > key . channel - > log ,
" htlc % " PRIu64 " already succeeded with preimage " ,
hin - > key . id ) ;
} else if ( hin - > failonion ) {
log_broken ( hin - > key . channel - > log ,
" htlc % " PRIu64 " already failed with failonion %s " ,
hin - > key . id ,
tal_hex ( tmpctx , hin - > failonion - > contents ) ) ;
} else {
log_broken ( hin - > key . channel - > log ,
" htlc % " PRIu64 " has matching hash: failing " ,
hin - > key . id ) ;
local_fail_in_htlc ( hin ,
take ( towire_permanent_channel_failure ( NULL ) ) ) ;
}
}
}
2018-02-12 20:43:04 +10:30
void onchain_failed_our_htlc ( const struct channel * channel ,
2017-09-27 06:32:47 +09:30
const struct htlc_stub * htlc ,
2022-03-30 14:13:12 +10:30
const char * why ,
bool should_exist )
2017-09-27 06:32:47 +09:30
{
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2018-10-23 20:10:22 +10:30
struct htlc_out * hout ;
2022-03-30 14:13:12 +10:30
log_debug ( channel - > log , " onchain_failed_our_htlc " ) ;
2023-01-03 15:16:52 +10:30
hout = find_htlc_out ( ld - > htlcs_out , channel , htlc - > id ) ;
2022-03-30 14:13:12 +10:30
if ( ! hout ) {
2022-03-30 14:13:12 +10:30
/* For penalty transactions, tell onchaind about all possible
* HTLCs : they may not all exist any more . */
if ( should_exist )
log_broken ( channel - > log , " HTLC id % " PRIu64 " not found! " ,
htlc - > id ) ;
/* Immediate corruption sanity check if this happens */
2023-01-03 15:16:52 +10:30
htable_check ( & ld - > htlcs_out - > raw , " onchain_failed_our_htlc out " ) ;
htable_check ( & ld - > htlcs_in - > raw , " onchain_failed_our_htlc in " ) ;
2018-10-23 20:10:22 +10:30
return ;
2022-03-30 14:13:12 +10:30
}
2017-09-27 06:32:47 +09:30
2022-06-26 14:10:01 +09:30
/* We can have hout->failonion (which gets set when we process the
* received commitment_signed ) , but not failed hin yet , because the peer
* hadn ' t revoke_and_acked our own commitment without that htlc . */
if ( hout - > failonion & & hout - > in
& & hout - > in - > badonion = = 0
& & ! hout - > in - > failonion
& & ! hout - > in - > preimage ) {
log_debug ( channel - > log , " HTLC out % " PRIu64 " can now fail HTLC upstream! " ,
htlc - > id ) ;
fail_in_htlc ( hout - > in , hout - > failonion ) ;
}
2018-10-09 19:28:52 +10:30
/* Don't fail twice (or if already succeeded)! */
2022-03-30 14:13:12 +10:30
if ( hout - > failonion | | hout - > failmsg | | hout - > preimage ) {
log_debug ( channel - > log , " HTLC id % " PRIu64 " failonion = %p, failmsg = %p, preimage = %p " ,
htlc - > id ,
hout - > failonion ,
hout - > failmsg ,
hout - > preimage ) ;
2022-03-30 14:13:12 +10:30
check_already_failed ( channel , hout ) ;
2017-09-27 06:32:47 +09:30
return ;
2022-03-30 14:13:12 +10:30
}
2017-09-27 06:32:47 +09:30
2020-02-21 15:36:58 +10:30
hout - > failmsg = towire_permanent_channel_failure ( hout ) ;
2017-09-27 06:32:47 +09:30
2018-10-09 19:15:52 +10:30
/* Force state to something which expects a failure, and save to db */
hout - > hstate = RCVD_REMOVE_HTLC ;
htlc_out_check ( hout , __func__ ) ;
2020-04-14 14:02:46 -05:00
bool we_filled = false ;
2018-10-23 20:10:22 +10:30
wallet_htlc_update ( ld - > wallet , hout - > dbid , hout - > hstate ,
2021-10-13 14:15:30 +10:30
hout - > preimage ,
max_unsigned ( channel - > next_index [ LOCAL ] ,
channel - > next_index [ REMOTE ] ) ,
0 , hout - > failonion ,
2020-04-14 14:02:46 -05:00
hout - > failmsg , & we_filled ) ;
2018-10-09 19:15:52 +10:30
2018-10-10 06:51:31 +10:30
if ( hout - > am_origin ) {
2022-03-30 14:13:12 +10:30
log_debug ( channel - > log , " HTLC id % " PRIu64 " am origin " ,
htlc - > id ) ;
2018-03-01 11:32:38 +01:00
assert ( why ! = NULL ) ;
2018-02-12 20:43:04 +10:30
char * localfail = tal_fmt ( channel , " %s: %s " ,
2020-08-31 10:43:25 +09:30
onion_wire_name ( WIRE_PERMANENT_CHANNEL_FAILURE ) ,
2017-09-27 06:32:47 +09:30
why ) ;
2022-01-25 06:31:52 +10:30
payment_failed ( ld , hout , localfail ) ;
2017-09-27 06:32:47 +09:30
tal_free ( localfail ) ;
2019-04-15 22:27:22 +08:00
} else if ( hout - > in ) {
2022-03-30 14:13:12 +10:30
log_debug ( channel - > log , " HTLC id % " PRIu64 " has incoming " ,
htlc - > id ) ;
2023-07-24 12:38:50 +09:30
/* Careful! We might have already timed out incoming
* HTLC in consider_failing_incoming */
if ( hout - > in - > badonion = = 0
& & ! hout - > in - > failonion
& & ! hout - > in - > preimage ) {
local_fail_in_htlc ( hout - > in ,
take ( towire_permanent_channel_failure ( NULL ) ) ) ;
}
2019-04-15 22:27:22 +08:00
wallet_forwarded_payment_add ( hout - > key . channel - > peer - > ld - > wallet ,
2022-09-28 14:19:35 +09:30
hout - > in , FORWARD_STYLE_TLV ,
2022-07-09 12:53:23 +09:30
channel_scid_or_local_alias ( channel ) , hout ,
2019-04-15 22:27:22 +08:00
FORWARD_LOCAL_FAILED ,
2020-02-21 15:36:58 +10:30
hout - > failmsg
? fromwire_peektype ( hout - > failmsg )
: 0 ) ;
2022-03-30 14:13:12 +10:30
} else {
2022-03-30 14:13:12 +10:30
log_broken ( channel - > log , " HTLC id % " PRIu64 " is from nowhere? " ,
htlc - > id ) ;
2022-03-30 14:13:12 +10:30
/* Immediate corruption sanity check if this happens */
2023-01-03 15:16:52 +10:30
htable_check ( & ld - > htlcs_out - > raw , " onchain_failed_our_htlc out " ) ;
htable_check ( & ld - > htlcs_in - > raw , " onchain_failed_our_htlc in " ) ;
2022-03-30 14:13:12 +10:30
fail_dangling_htlc_in ( ld , & hout - > payment_hash ) ;
}
2017-09-27 06:32:47 +09:30
}
2018-02-12 20:43:04 +10:30
static void remove_htlc_in ( struct channel * channel , struct htlc_in * hin )
2017-06-20 15:23:03 +09:30
{
htlc_in_check ( hin , __func__ ) ;
2020-02-21 15:40:44 +10:30
assert ( hin - > failonion | | hin - > preimage | | hin - > badonion ) ;
2017-06-20 15:29:03 +09:30
2018-02-12 20:43:04 +10:30
log_debug ( channel - > log , " Removing in HTLC % " PRIu64 " state %s %s " ,
2017-06-20 15:29:03 +09:30
hin - > key . id , htlc_state_name ( hin - > hstate ) ,
2017-11-28 15:33:04 +10:30
hin - > preimage ? " FULFILLED "
2020-08-31 10:43:25 +09:30
: hin - > badonion ? onion_wire_name ( hin - > badonion )
2017-11-28 15:33:04 +10:30
: " REMOTEFAIL " ) ;
2017-06-20 15:29:03 +09:30
/* If we fulfilled their HTLC, credit us. */
if ( hin - > preimage ) {
2019-02-21 14:15:55 +10:30
struct amount_msat oldamt = channel - > our_msat ;
2020-03-18 18:40:32 -05:00
const struct channel_coin_mvt * mvt ;
2019-02-21 14:15:55 +10:30
if ( ! amount_msat_add ( & channel - > our_msat , channel - > our_msat ,
hin - > msat ) ) {
channel_internal_error ( channel ,
" Overflow our_msat %s + HTLC %s " ,
type_to_string ( tmpctx ,
struct amount_msat ,
& channel - > our_msat ) ,
type_to_string ( tmpctx ,
struct amount_msat ,
& hin - > msat ) ) ;
}
log_debug ( channel - > log , " Balance %s -> %s " ,
type_to_string ( tmpctx , struct amount_msat , & oldamt ) ,
type_to_string ( tmpctx , struct amount_msat ,
& channel - > our_msat ) ) ;
if ( amount_msat_greater ( channel - > our_msat ,
channel - > msat_to_us_max ) )
channel - > msat_to_us_max = channel - > our_msat ;
2020-03-18 18:40:32 -05:00
/* Coins have definitively moved, log a movement */
2021-12-07 10:05:29 -06:00
if ( hin - > we_filled & & * hin - > we_filled )
2020-04-14 14:01:18 -05:00
mvt = new_channel_mvt_invoice_hin ( hin , hin , channel ) ;
else
mvt = new_channel_mvt_routed_hin ( hin , hin , channel ) ;
2021-12-07 10:05:29 -06:00
if ( ! mvt )
log_broken ( channel - > log ,
" Unable to calculate fees collected. "
" Not logging an inbound HTLC " ) ;
else
notify_channel_mvt ( channel - > peer - > ld , mvt ) ;
2017-06-20 15:29:03 +09:30
}
2017-06-20 15:23:03 +09:30
tal_free ( hin ) ;
}
2017-06-20 15:20:03 +09:30
2018-02-12 20:43:04 +10:30
static void remove_htlc_out ( struct channel * channel , struct htlc_out * hout )
2017-06-20 15:20:03 +09:30
{
2017-06-20 15:23:03 +09:30
htlc_out_check ( hout , __func__ ) ;
2020-02-21 15:36:58 +10:30
assert ( hout - > failonion | | hout - > preimage | | hout - > failmsg ) ;
2018-02-12 20:43:04 +10:30
log_debug ( channel - > log , " Removing out HTLC % " PRIu64 " state %s %s " ,
2017-06-20 15:29:03 +09:30
hout - > key . id , htlc_state_name ( hout - > hstate ) ,
2017-11-28 15:33:04 +10:30
hout - > preimage ? " FULFILLED "
2020-08-31 10:43:25 +09:30
: hout - > failmsg ? onion_wire_name ( fromwire_peektype ( hout - > failmsg ) )
2017-11-28 15:33:04 +10:30
: " REMOTEFAIL " ) ;
2017-06-20 15:20:03 +09:30
/* If it's failed, now we can forward since it's completely locked-in */
2017-06-20 15:37:03 +09:30
if ( ! hout - > preimage ) {
2022-01-25 06:31:52 +10:30
fail_out_htlc ( hout , NULL ) ;
2017-06-20 15:29:03 +09:30
} else {
2020-03-18 18:40:32 -05:00
const struct channel_coin_mvt * mvt ;
2019-02-21 14:15:55 +10:30
struct amount_msat oldamt = channel - > our_msat ;
2017-06-20 15:29:03 +09:30
/* We paid for this HTLC, so deduct balance. */
2019-02-21 14:15:55 +10:30
if ( ! amount_msat_sub ( & channel - > our_msat , channel - > our_msat ,
hout - > msat ) ) {
channel_internal_error ( channel ,
" Underflow our_msat %s - HTLC %s " ,
type_to_string ( tmpctx ,
struct amount_msat ,
& channel - > our_msat ) ,
type_to_string ( tmpctx ,
struct amount_msat ,
& hout - > msat ) ) ;
}
log_debug ( channel - > log , " Balance %s -> %s " ,
type_to_string ( tmpctx , struct amount_msat , & oldamt ) ,
type_to_string ( tmpctx , struct amount_msat ,
& channel - > our_msat ) ) ;
if ( amount_msat_less ( channel - > our_msat , channel - > msat_to_us_min ) )
channel - > msat_to_us_min = channel - > our_msat ;
2020-03-18 18:40:32 -05:00
/* Coins have definitively moved, log a movement */
2020-04-14 14:01:18 -05:00
if ( hout - > am_origin )
mvt = new_channel_mvt_invoice_hout ( hout , hout , channel ) ;
else
mvt = new_channel_mvt_routed_hout ( hout , hout , channel ) ;
2020-03-18 18:40:32 -05:00
2021-12-07 10:05:29 -06:00
if ( ! mvt )
log_broken ( channel - > log ,
2021-12-07 14:09:28 -06:00
" Unable to calculate fees. "
2021-12-07 10:05:29 -06:00
" Not logging an outbound HTLC " ) ;
else
notify_channel_mvt ( channel - > peer - > ld , mvt ) ;
2017-06-20 15:15:03 +09:30
}
2017-06-20 15:23:03 +09:30
tal_free ( hout ) ;
2017-06-20 15:20:03 +09:30
}
2018-02-12 20:43:04 +10:30
static bool update_in_htlc ( struct channel * channel ,
u64 id , enum htlc_state newstate )
2017-06-20 15:20:03 +09:30
{
2017-06-20 15:23:03 +09:30
struct htlc_in * hin ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2017-06-20 15:20:03 +09:30
2023-01-03 15:16:52 +10:30
hin = find_htlc_in ( ld - > htlcs_in , channel , id ) ;
2017-06-20 15:23:03 +09:30
if ( ! hin ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel , " Can't find in HTLC % " PRIu64 , id ) ;
2017-06-20 15:23:03 +09:30
return false ;
}
2017-06-20 15:20:03 +09:30
2018-02-12 20:43:04 +10:30
if ( ! htlc_in_update_state ( channel , hin , newstate ) )
2017-06-20 15:23:03 +09:30
return false ;
2018-10-09 19:15:52 +10:30
htlc_in_check ( hin , __func__ ) ;
2017-06-20 15:23:03 +09:30
if ( newstate = = SENT_REMOVE_ACK_REVOCATION )
2018-02-12 20:43:04 +10:30
remove_htlc_in ( channel , hin ) ;
2017-06-20 15:23:03 +09:30
return true ;
}
2018-02-12 20:43:04 +10:30
static bool update_out_htlc ( struct channel * channel ,
u64 id , enum htlc_state newstate )
2017-06-20 15:23:03 +09:30
{
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2017-06-20 15:23:03 +09:30
struct htlc_out * hout ;
2023-01-03 15:16:52 +10:30
hout = find_htlc_out ( ld - > htlcs_out , channel , id ) ;
2017-06-20 15:23:03 +09:30
if ( ! hout ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel , " Can't find out HTLC % " PRIu64 , id ) ;
2017-06-20 15:20:03 +09:30
return false ;
}
2017-11-23 21:54:19 +01:00
if ( ! hout - > dbid ) {
2018-02-12 20:43:04 +10:30
wallet_htlc_save_out ( ld - > wallet , channel , hout ) ;
2018-03-24 08:26:08 +00:00
/* Update channel stats */
wallet_channel_stats_incr_out_offered ( ld - > wallet ,
channel - > dbid ,
2019-02-21 14:15:55 +10:30
hout - > msat ) ;
2017-11-23 21:54:19 +01:00
2019-04-15 22:27:22 +08:00
if ( hout - > in ) {
2020-02-13 12:41:01 +10:30
wallet_forwarded_payment_add ( ld - > wallet , hout - > in ,
2022-09-28 14:19:35 +09:30
FORWARD_STYLE_TLV ,
2022-07-09 12:53:23 +09:30
channel_scid_or_local_alias ( channel ) , hout ,
2019-04-15 22:27:22 +08:00
FORWARD_OFFERED , 0 ) ;
}
2017-11-23 21:54:19 +01:00
}
2017-09-18 20:18:29 +02:00
2018-02-12 20:43:04 +10:30
if ( ! htlc_out_update_state ( channel , hout , newstate ) )
2017-06-20 15:20:03 +09:30
return false ;
/* First transition into commitment; now it outlives peer. */
2017-06-20 15:23:03 +09:30
if ( newstate = = SENT_ADD_COMMIT ) {
2018-02-14 12:23:13 +10:30
tal_del_destructor ( hout , destroy_hout_subd_died ) ;
2021-05-21 11:45:54 +09:30
hout - > timeout = tal_free ( hout - > timeout ) ;
2018-02-12 20:43:04 +10:30
tal_steal ( ld , hout ) ;
2017-06-20 15:23:03 +09:30
} else if ( newstate = = RCVD_REMOVE_ACK_REVOCATION ) {
2018-02-12 20:43:04 +10:30
remove_htlc_out ( channel , hout ) ;
2017-06-20 15:20:03 +09:30
}
return true ;
}
2018-02-12 20:43:04 +10:30
static bool changed_htlc ( struct channel * channel ,
2017-06-20 15:23:03 +09:30
const struct changed_htlc * changed )
{
if ( htlc_state_owner ( changed - > newstate ) = = LOCAL )
2018-02-12 20:43:04 +10:30
return update_out_htlc ( channel , changed - > id , changed - > newstate ) ;
2017-06-20 15:23:03 +09:30
else
2018-02-12 20:43:04 +10:30
return update_in_htlc ( channel , changed - > id , changed - > newstate ) ;
2017-06-20 15:23:03 +09:30
}
2019-06-27 09:55:17 +09:30
/* FIXME: This should be a complete check, not just a sanity check.
* Perhaps that means we need a cookie from the HSM ? */
static bool valid_commitment_tx ( struct channel * channel ,
const struct bitcoin_tx * tx )
{
/* We've had past issues where all outputs are trimmed. */
if ( tx - > wtx - > num_outputs = = 0 ) {
channel_internal_error ( channel ,
" channel_got_commitsig: zero output tx! %s " ,
type_to_string ( tmpctx , struct bitcoin_tx , tx ) ) ;
return false ;
}
return true ;
}
2018-02-12 20:43:04 +10:30
static bool peer_save_commitsig_received ( struct channel * channel , u64 commitnum ,
2018-01-10 13:13:23 +10:30
struct bitcoin_tx * tx ,
2018-12-03 09:45:06 +10:30
const struct bitcoin_signature * commit_sig )
2017-06-20 15:48:03 +09:30
{
2018-02-12 20:43:04 +10:30
if ( commitnum ! = channel - > next_index [ LOCAL ] ) {
channel_internal_error ( channel ,
2017-06-20 15:48:03 +09:30
" channel_got_commitsig: expected commitnum % " PRIu64
" got % " PRIu64 ,
2018-02-12 20:43:04 +10:30
channel - > next_index [ LOCAL ] , commitnum ) ;
2017-06-20 15:48:03 +09:30
return false ;
}
2019-06-27 09:55:17 +09:30
/* Basic sanity check */
if ( ! valid_commitment_tx ( channel , tx ) )
return false ;
2018-02-12 20:43:04 +10:30
channel - > next_index [ LOCAL ] + + ;
2017-06-20 15:48:03 +09:30
2023-07-27 14:37:52 -07:00
/* DTODO: Add inflight_commit_sigs to the DB */
2018-02-12 20:43:04 +10:30
/* Update channel->last_sig and channel->last_tx before saving to db */
2023-01-30 16:36:03 +10:30
channel_set_last_tx ( channel , tx , commit_sig ) ;
2018-01-10 13:13:23 +10:30
2017-06-20 15:48:03 +09:30
return true ;
}
2018-02-12 20:43:04 +10:30
static bool peer_save_commitsig_sent ( struct channel * channel , u64 commitnum )
2017-06-20 15:48:03 +09:30
{
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2018-02-12 20:43:04 +10:30
if ( commitnum ! = channel - > next_index [ REMOTE ] ) {
channel_internal_error ( channel ,
2017-06-20 15:48:03 +09:30
" channel_sent_commitsig: expected commitnum % " PRIu64
2023-07-27 14:37:52 -07:00
" got % " PRIu64 " (while sending commitsig) " ,
2018-02-12 20:43:04 +10:30
channel - > next_index [ REMOTE ] , commitnum ) ;
2017-06-20 15:48:03 +09:30
return false ;
}
2018-02-12 20:43:04 +10:30
channel - > next_index [ REMOTE ] + + ;
2017-06-20 15:48:03 +09:30
/* FIXME: Save to database, with sig and HTLCs. */
2018-02-12 20:43:04 +10:30
wallet_channel_save ( ld - > wallet , channel ) ;
2017-06-20 15:48:03 +09:30
return true ;
}
2019-12-13 03:48:25 +10:30
static void adjust_channel_feerate_bounds ( struct channel * channel , u32 feerate )
{
if ( feerate > channel - > max_possible_feerate )
channel - > max_possible_feerate = feerate ;
if ( feerate < channel - > min_possible_feerate )
channel - > min_possible_feerate = feerate ;
}
2018-02-12 20:43:04 +10:30
void peer_sending_commitsig ( struct channel * channel , const u8 * msg )
2017-06-20 15:20:03 +09:30
{
u64 commitnum ;
2019-12-13 03:48:25 +10:30
struct fee_states * fee_states ;
2021-06-22 16:47:33 -05:00
struct height_states * blockheight_states ;
2017-06-20 15:20:03 +09:30
struct changed_htlc * changed_htlcs ;
2017-06-20 15:43:03 +09:30
size_t i , maxid = 0 , num_local_added = 0 ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2020-05-07 10:19:32 +09:30
struct penalty_base * pbase ;
2017-06-20 15:20:03 +09:30
2020-08-25 11:03:16 +09:30
if ( ! fromwire_channeld_sending_commitsig ( msg , msg ,
2017-06-20 15:20:03 +09:30
& commitnum ,
2020-05-07 10:19:32 +09:30
& pbase ,
2019-12-13 03:48:25 +10:30
& fee_states ,
2021-06-22 16:47:33 -05:00
& blockheight_states ,
2023-10-26 13:01:55 +10:30
& changed_htlcs )
2021-06-22 16:47:33 -05:00
| | ! fee_states_valid ( fee_states , channel - > opener )
| | ! height_states_valid ( blockheight_states , channel - > opener ) ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel , " bad channel_sending_commitsig %s " ,
2018-02-12 20:43:04 +10:30
tal_hex ( channel , msg ) ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:15:03 +09:30
}
2017-06-20 15:20:03 +09:30
for ( i = 0 ; i < tal_count ( changed_htlcs ) ; i + + ) {
2018-02-12 20:43:04 +10:30
if ( ! changed_htlc ( channel , changed_htlcs + i ) ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel ,
2017-06-20 15:20:03 +09:30
" channel_sending_commitsig: update failed " ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:15:03 +09:30
}
2017-06-20 15:43:03 +09:30
/* While we're here, sanity check added ones are in
* ascending order . */
if ( changed_htlcs [ i ] . newstate = = SENT_ADD_COMMIT ) {
num_local_added + + ;
if ( changed_htlcs [ i ] . id > maxid )
maxid = changed_htlcs [ i ] . id ;
}
}
if ( num_local_added ! = 0 ) {
2018-02-12 20:43:04 +10:30
if ( maxid ! = channel - > next_htlc_id + num_local_added - 1 ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel ,
2017-06-20 15:43:03 +09:30
" channel_sending_commitsig: "
" Added % " PRIu64 " , maxid now % " PRIu64
" from % " PRIu64 ,
2018-02-12 20:43:04 +10:30
num_local_added , maxid , channel - > next_htlc_id ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:43:03 +09:30
}
2018-02-12 20:43:04 +10:30
channel - > next_htlc_id + = num_local_added ;
2017-06-20 15:15:03 +09:30
}
2019-12-13 03:48:25 +10:30
/* FIXME: We could detect if this changed, and adjust bounds and write
* it to db iff it has . */
2020-09-17 11:28:59 +09:30
tal_free ( channel - > fee_states ) ;
channel - > fee_states = tal_steal ( channel , fee_states ) ;
2019-12-13 03:48:25 +10:30
adjust_channel_feerate_bounds ( channel ,
get_feerate ( fee_states ,
2019-09-09 11:11:24 -05:00
channel - > opener ,
2019-12-13 03:48:25 +10:30
REMOTE ) ) ;
2017-11-21 15:56:59 +10:30
2021-06-22 16:47:33 -05:00
tal_free ( channel - > blockheight_states ) ;
channel - > blockheight_states = tal_steal ( channel , blockheight_states ) ;
2018-02-12 20:43:04 +10:30
if ( ! peer_save_commitsig_sent ( channel , commitnum ) )
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:32:03 +09:30
2018-01-13 15:33:51 +01:00
/* Last was commit. */
2018-02-12 20:43:04 +10:30
channel - > last_was_revoke = false ;
tal_free ( channel - > last_sent_commit ) ;
channel - > last_sent_commit = tal_steal ( channel , changed_htlcs ) ;
wallet_channel_save ( ld - > wallet , channel ) ;
2017-06-20 15:33:03 +09:30
2020-05-07 10:19:38 +09:30
if ( pbase )
wallet_penalty_base_add ( ld - > wallet , channel - > dbid , pbase ) ;
2017-06-20 15:20:03 +09:30
/* Tell it we've got it, and to go ahead with commitment_signed. */
2018-02-12 20:43:04 +10:30
subd_send_msg ( channel - > owner ,
2020-08-25 11:03:16 +09:30
take ( towire_channeld_sending_commitsig_reply ( msg ) ) ) ;
2017-06-20 15:15:03 +09:30
}
2018-02-12 20:42:55 +10:30
static bool channel_added_their_htlc ( struct channel * channel ,
2020-02-18 10:28:58 +10:30
const struct added_htlc * added )
2017-06-20 15:20:03 +09:30
{
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2017-06-20 15:23:03 +09:30
struct htlc_in * hin ;
2020-02-18 10:28:58 +10:30
struct secret shared_secret ;
2020-12-08 21:05:32 +10:30
struct onionpacket * op ;
2020-08-31 10:43:25 +09:30
enum onion_wire failcode ;
2017-06-20 15:20:03 +09:30
2018-01-21 13:19:21 +10:30
/* BOLT #2:
*
* - receiving an ` amount_msat ` equal to 0 , OR less than its own ` htlc_minimum_msat ` :
2022-03-31 19:40:50 +10:30
* - SHOULD send a ` warning ` and close the connection , or send an
* ` error ` and fail the channel .
2018-01-21 13:19:21 +10:30
*/
2019-02-21 14:15:55 +10:30
if ( amount_msat_eq ( added - > amount , AMOUNT_MSAT ( 0 ) )
| | amount_msat_less ( added - > amount , channel - > our_config . htlc_minimum ) ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel ,
2019-02-21 14:15:55 +10:30
" trying to add HTLC amount %s "
" but minimum is %s " ,
type_to_string ( tmpctx ,
struct amount_msat ,
& added - > amount ) ,
2019-02-21 14:15:54 +10:30
type_to_string ( tmpctx ,
struct amount_msat ,
& channel - > our_config . htlc_minimum ) ) ;
2018-01-21 13:19:21 +10:30
return false ;
}
2020-02-18 10:28:58 +10:30
/* Do the work of extracting shared secret now if possible. */
2020-04-11 12:52:40 +09:30
/* FIXME: We do this *again* in peer_accepted_htlc! */
2020-12-08 21:05:32 +10:30
op = parse_onionpacket ( tmpctx , added - > onion_routing_packet ,
sizeof ( added - > onion_routing_packet ) ,
& failcode ) ;
if ( op ) {
if ( ! ecdh_maybe_blinding ( & op - > ephemeralkey ,
2022-10-17 11:07:05 +10:30
added - > blinding ,
2020-04-11 12:52:40 +09:30
& shared_secret ) ) {
log_debug ( channel - > log , " htlc % " PRIu64
" : can't tweak pubkey " , added - > id ) ;
return false ;
}
2020-02-18 10:28:58 +10:30
}
2019-01-08 10:49:50 +10:30
2017-06-20 15:20:03 +09:30
/* This stays around even if we fail it immediately: it *is*
* part of the current commitment . */
2019-02-21 14:15:55 +10:30
hin = new_htlc_in ( channel , channel , added - > id , added - > amount ,
2017-06-20 15:23:03 +09:30
added - > cltv_expiry , & added - > payment_hash ,
2020-12-08 21:05:32 +10:30
op ? & shared_secret : NULL ,
2022-10-17 11:07:05 +10:30
added - > blinding ,
2021-09-28 14:08:11 -05:00
added - > onion_routing_packet ,
added - > fail_immediate ) ;
2017-06-20 15:23:03 +09:30
2017-09-18 20:18:29 +02:00
/* Save an incoming htlc to the wallet */
2018-02-12 20:43:04 +10:30
wallet_htlc_save_in ( ld - > wallet , channel , hin ) ;
2018-03-24 08:26:08 +00:00
/* Update channel stats */
wallet_channel_stats_incr_in_offered ( ld - > wallet , channel - > dbid ,
2019-02-21 14:15:55 +10:30
added - > amount ) ;
2017-06-20 15:20:03 +09:30
2018-02-12 20:42:55 +10:30
log_debug ( channel - > log , " Adding their HTLC % " PRIu64 , added - > id ) ;
2023-01-03 15:16:52 +10:30
connect_htlc_in ( channel - > peer - > ld - > htlcs_in , hin ) ;
2018-01-21 13:19:21 +10:30
return true ;
2017-06-20 15:20:03 +09:30
}
/* The peer doesn't tell us this separately, but logically it's a separate
* step to receiving commitsig */
2018-02-12 20:42:55 +10:30
static bool peer_sending_revocation ( struct channel * channel ,
2017-06-20 15:20:03 +09:30
struct added_htlc * added ,
struct fulfilled_htlc * fulfilled ,
2018-02-08 11:54:46 +10:30
struct failed_htlc * * failed ,
2017-06-20 15:20:03 +09:30
struct changed_htlc * changed )
{
size_t i ;
for ( i = 0 ; i < tal_count ( added ) ; i + + ) {
2018-02-12 20:43:04 +10:30
if ( ! update_in_htlc ( channel , added [ i ] . id , SENT_ADD_REVOCATION ) )
2017-06-20 15:20:03 +09:30
return false ;
}
for ( i = 0 ; i < tal_count ( fulfilled ) ; i + + ) {
2018-02-12 20:43:04 +10:30
if ( ! update_out_htlc ( channel , fulfilled [ i ] . id ,
2017-06-20 15:23:03 +09:30
SENT_REMOVE_REVOCATION ) )
2017-06-20 15:20:03 +09:30
return false ;
}
for ( i = 0 ; i < tal_count ( failed ) ; i + + ) {
2018-02-12 20:43:04 +10:30
if ( ! update_out_htlc ( channel , failed [ i ] - > id , SENT_REMOVE_REVOCATION ) )
2017-06-20 15:20:03 +09:30
return false ;
}
for ( i = 0 ; i < tal_count ( changed ) ; i + + ) {
if ( changed [ i ] . newstate = = RCVD_ADD_ACK_COMMIT ) {
2018-02-12 20:43:04 +10:30
if ( ! update_out_htlc ( channel , changed [ i ] . id ,
2017-06-20 15:23:03 +09:30
SENT_ADD_ACK_REVOCATION ) )
2017-06-20 15:20:03 +09:30
return false ;
} else {
2018-02-12 20:43:04 +10:30
if ( ! update_in_htlc ( channel , changed [ i ] . id ,
2017-06-20 15:23:03 +09:30
SENT_REMOVE_ACK_REVOCATION ) )
2017-06-20 15:20:03 +09:30
return false ;
}
}
2018-02-12 20:42:55 +10:30
channel - > last_was_revoke = true ;
2017-06-20 15:20:03 +09:30
return true ;
}
2019-08-10 20:18:13 +09:30
struct deferred_commitsig {
struct channel * channel ;
const u8 * msg ;
} ;
static void retry_deferred_commitsig ( struct chain_topology * topo ,
struct deferred_commitsig * d )
{
peer_got_commitsig ( d - > channel , d - > msg ) ;
tal_free ( d ) ;
}
2017-06-20 15:20:03 +09:30
/* This also implies we're sending revocation */
2018-02-12 20:43:04 +10:30
void peer_got_commitsig ( struct channel * channel , const u8 * msg )
2017-06-20 15:20:03 +09:30
{
u64 commitnum ;
2019-12-13 03:48:25 +10:30
struct fee_states * fee_states ;
2021-06-22 16:47:33 -05:00
struct height_states * blockheight_states ;
2020-08-14 03:15:02 +09:30
struct bitcoin_signature commit_sig , * htlc_sigs ;
2017-06-20 15:20:03 +09:30
struct added_htlc * added ;
struct fulfilled_htlc * fulfilled ;
2018-02-08 11:54:46 +10:30
struct failed_htlc * * failed ;
2017-06-20 15:20:03 +09:30
struct changed_htlc * changed ;
2018-02-08 11:55:12 +10:30
struct bitcoin_tx * tx ;
2023-07-27 14:37:52 -07:00
struct commitsig * * inflight_commit_sigs ;
struct channel_inflight * inflight ;
2017-06-20 15:20:03 +09:30
size_t i ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2017-06-20 15:20:03 +09:30
2020-08-25 11:03:16 +09:30
if ( ! fromwire_channeld_got_commitsig ( msg , msg ,
2017-06-20 15:20:03 +09:30
& commitnum ,
2019-12-13 03:48:25 +10:30
& fee_states ,
2021-06-22 16:47:33 -05:00
& blockheight_states ,
2017-06-20 15:20:03 +09:30
& commit_sig ,
& htlc_sigs ,
& added ,
& fulfilled ,
& failed ,
2017-08-18 14:13:52 +09:30
& changed ,
2023-07-27 14:37:52 -07:00
& tx ,
& inflight_commit_sigs )
2021-06-22 16:47:33 -05:00
| | ! fee_states_valid ( fee_states , channel - > opener )
| | ! height_states_valid ( blockheight_states , channel - > opener ) ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel ,
2020-08-25 11:03:16 +09:30
" bad fromwire_channeld_got_commitsig %s " ,
2018-02-12 20:43:04 +10:30
tal_hex ( channel , msg ) ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:15:03 +09:30
}
2019-12-10 20:37:18 +10:30
/* If we're not synced with bitcoin network, we can't accept
* any new HTLCs . We stall at this point , in the hope that it
* won ' t take long ! */
if ( added & & ! topology_synced ( ld - > topology ) ) {
struct deferred_commitsig * d ;
log_unusual ( channel - > log ,
" Deferring incoming commit until we sync " ) ;
/* If subdaemon dies, we want to forget this. */
d = tal ( channel - > owner , struct deferred_commitsig ) ;
d - > channel = channel ;
2020-02-27 12:47:01 +10:30
d - > msg = tal_dup_talarr ( d , u8 , msg ) ;
2019-12-10 20:37:18 +10:30
topology_add_sync_waiter ( d , ld - > topology ,
retry_deferred_commitsig , d ) ;
return ;
}
2019-10-15 12:58:30 +02:00
tx - > chainparams = chainparams ;
2017-06-20 15:15:03 +09:30
2018-02-12 20:43:04 +10:30
log_debug ( channel - > log ,
2017-06-20 15:20:03 +09:30
" got commitsig % " PRIu64
2023-07-27 14:37:52 -07:00
" : feerate %u, blockheight: %u, %zu added, %zu fulfilled, "
" %zu failed, %zu changed. %zu splice commitments. " ,
2019-09-09 11:11:24 -05:00
commitnum , get_feerate ( fee_states , channel - > opener , LOCAL ) ,
2021-06-22 16:47:33 -05:00
get_blockheight ( blockheight_states , channel - > opener , LOCAL ) ,
2019-12-13 03:48:25 +10:30
tal_count ( added ) , tal_count ( fulfilled ) ,
2023-07-27 14:37:52 -07:00
tal_count ( failed ) , tal_count ( changed ) ,
tal_count ( inflight_commit_sigs ) ) ;
i = 0 ;
list_for_each ( & channel - > inflights , inflight , list ) {
2023-08-15 22:58:53 -04:00
if ( ! inflight - > splice_locked_memonly )
i + + ;
2023-07-27 14:37:52 -07:00
}
if ( i ! = tal_count ( inflight_commit_sigs ) ) {
channel_internal_error ( channel , " Got commitsig with incorrect "
" number of splice commitments. "
" lightningd expects %zu but got %zu. " ,
i , tal_count ( inflight_commit_sigs ) ) ;
return ;
}
2017-06-20 15:20:03 +09:30
/* New HTLCs */
2018-01-21 13:19:21 +10:30
for ( i = 0 ; i < tal_count ( added ) ; i + + ) {
2020-02-18 10:28:58 +10:30
if ( ! channel_added_their_htlc ( channel , & added [ i ] ) )
2018-01-21 13:19:21 +10:30
return ;
}
2017-06-20 15:20:03 +09:30
/* Save information now for fulfilled & failed HTLCs */
for ( i = 0 ; i < tal_count ( fulfilled ) ; i + + ) {
2018-02-12 20:42:55 +10:30
if ( ! peer_fulfilled_our_htlc ( channel , & fulfilled [ i ] ) )
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:20:03 +09:30
}
for ( i = 0 ; i < tal_count ( failed ) ; i + + ) {
2018-02-12 20:42:55 +10:30
if ( ! peer_failed_our_htlc ( channel , failed [ i ] ) )
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:20:03 +09:30
}
2017-06-20 15:23:03 +09:30
2017-06-20 15:20:03 +09:30
for ( i = 0 ; i < tal_count ( changed ) ; i + + ) {
2018-02-12 20:43:04 +10:30
if ( ! changed_htlc ( channel , & changed [ i ] ) ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel ,
2017-06-20 15:47:03 +09:30
" got_commitsig: update failed " ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:20:03 +09:30
}
}
2020-09-17 11:28:59 +09:30
tal_free ( channel - > fee_states ) ;
channel - > fee_states = tal_steal ( channel , fee_states ) ;
2019-12-13 03:48:25 +10:30
adjust_channel_feerate_bounds ( channel ,
get_feerate ( fee_states ,
2019-09-09 11:11:24 -05:00
channel - > opener ,
2019-12-13 03:48:25 +10:30
LOCAL ) ) ;
2021-06-22 16:47:33 -05:00
tal_free ( channel - > blockheight_states ) ;
channel - > blockheight_states = tal_steal ( channel , blockheight_states ) ;
2018-04-03 16:49:39 +09:30
2017-06-20 15:20:03 +09:30
/* Since we're about to send revoke, bump state again. */
2018-02-12 20:42:55 +10:30
if ( ! peer_sending_revocation ( channel , added , fulfilled , failed , changed ) )
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:20:03 +09:30
2018-02-12 20:43:04 +10:30
if ( ! peer_save_commitsig_received ( channel , commitnum , tx , & commit_sig ) )
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:32:03 +09:30
2018-02-12 20:43:04 +10:30
wallet_channel_save ( ld - > wallet , channel ) ;
2018-01-13 15:33:51 +01:00
2018-02-12 20:42:55 +10:30
tal_free ( channel - > last_htlc_sigs ) ;
channel - > last_htlc_sigs = tal_steal ( channel , htlc_sigs ) ;
2023-07-27 14:37:52 -07:00
/* Delete all HTLCs and add last_htlc_sigs back in */
2018-02-12 20:43:04 +10:30
wallet_htlc_sigs_save ( ld - > wallet , channel - > dbid ,
2018-02-12 20:42:55 +10:30
channel - > last_htlc_sigs ) ;
2023-07-27 14:37:52 -07:00
/* Now append htlc sigs for inflights */
i = 0 ;
list_for_each ( & channel - > inflights , inflight , list ) {
2023-08-15 22:58:53 -04:00
struct commitsig * commit ;
if ( inflight - > splice_locked_memonly )
continue ;
commit = inflight_commit_sigs [ i ] ;
2023-07-27 14:37:52 -07:00
2023-08-15 22:58:53 -04:00
tal_free ( inflight - > last_tx ) ;
inflight - > last_tx = clone_bitcoin_tx ( inflight , commit - > tx ) ;
2023-07-27 14:37:52 -07:00
inflight - > last_tx - > chainparams = chainparams ;
inflight - > last_sig = commit - > commit_signature ;
wallet_inflight_save ( ld - > wallet , inflight ) ;
wallet_htlc_sigs_add ( ld - > wallet , channel - > dbid ,
inflight - > funding - > outpoint ,
commit - > htlc_signatures ) ;
i + + ;
}
2017-08-18 14:13:52 +09:30
2017-06-20 15:20:03 +09:30
/* Tell it we've committed, and to go ahead with revoke. */
2020-08-25 11:03:16 +09:30
msg = towire_channeld_got_commitsig_reply ( msg ) ;
2018-02-12 20:42:55 +10:30
subd_send_msg ( channel - > owner , take ( msg ) ) ;
2017-06-20 15:20:03 +09:30
}
2017-06-20 15:25:03 +09:30
/* Shuffle them over, forgetting the ancient one. */
2018-02-12 20:43:04 +10:30
void update_per_commit_point ( struct channel * channel ,
2017-06-20 15:45:03 +09:30
const struct pubkey * per_commitment_point )
2017-06-20 15:25:03 +09:30
{
2018-02-19 11:36:12 +10:30
struct channel_info * ci = & channel - > channel_info ;
2017-06-20 15:45:03 +09:30
ci - > old_remote_per_commit = ci - > remote_per_commit ;
ci - > remote_per_commit = * per_commitment_point ;
2017-06-20 15:25:03 +09:30
}
2020-05-07 10:24:26 +09:30
struct commitment_revocation_payload {
struct bitcoin_txid commitment_txid ;
const struct bitcoin_tx * penalty_tx ;
struct wallet * wallet ;
2021-09-03 16:24:46 +02:00
u64 channel_dbid ;
2020-05-07 10:24:26 +09:30
u64 commitnum ;
2021-09-03 16:24:46 +02:00
struct channel_id channel_id ;
2020-05-07 10:24:26 +09:30
} ;
static void commitment_revocation_hook_serialize (
2021-06-02 17:33:23 +02:00
struct commitment_revocation_payload * payload , struct json_stream * stream ,
struct plugin * plugin )
2020-05-07 10:24:26 +09:30
{
json_add_txid ( stream , " commitment_txid " , & payload - > commitment_txid ) ;
json_add_tx ( stream , " penalty_tx " , payload - > penalty_tx ) ;
2021-09-03 16:24:46 +02:00
json_add_channel_id ( stream , " channel_id " , & payload - > channel_id ) ;
json_add_u64 ( stream , " commitnum " , payload - > commitnum ) ;
2020-05-07 10:24:26 +09:30
}
static void
commitment_revocation_hook_cb ( struct commitment_revocation_payload * p STEALS ) {
2021-09-03 16:24:46 +02:00
wallet_penalty_base_delete ( p - > wallet , p - > channel_dbid , p - > commitnum ) ;
2020-05-07 10:24:26 +09:30
}
static bool
commitment_revocation_hook_deserialize ( struct commitment_revocation_payload * p ,
const char * buffer ,
const jsmntok_t * toks )
{
return true ;
}
REGISTER_PLUGIN_HOOK ( commitment_revocation ,
commitment_revocation_hook_deserialize ,
commitment_revocation_hook_cb ,
commitment_revocation_hook_serialize ,
struct commitment_revocation_payload * ) ;
2018-02-12 20:43:04 +10:30
void peer_got_revoke ( struct channel * channel , const u8 * msg )
2017-06-20 15:20:03 +09:30
{
2017-06-20 15:32:03 +09:30
u64 revokenum ;
2018-07-09 20:47:58 +09:30
struct secret per_commitment_secret ;
2017-06-20 15:25:03 +09:30
struct pubkey next_per_commitment_point ;
2017-06-20 15:20:03 +09:30
struct changed_htlc * changed ;
2020-08-31 10:43:25 +09:30
enum onion_wire * badonions ;
2020-02-21 15:38:31 +10:30
u8 * * failmsgs ;
2017-06-20 15:20:03 +09:30
size_t i ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2019-12-13 03:48:25 +10:30
struct fee_states * fee_states ;
2021-06-22 16:47:33 -05:00
struct height_states * blockheight_states ;
2020-05-07 10:22:50 +09:30
struct penalty_base * pbase ;
2020-05-07 10:24:26 +09:30
struct commitment_revocation_payload * payload ;
struct bitcoin_tx * penalty_tx ;
2017-06-20 15:20:03 +09:30
2020-08-25 11:03:16 +09:30
if ( ! fromwire_channeld_got_revoke ( msg , msg ,
2017-06-20 15:20:03 +09:30
& revokenum , & per_commitment_secret ,
2017-06-20 15:25:03 +09:30
& next_per_commitment_point ,
2019-12-13 03:48:25 +10:30
& fee_states ,
2021-06-22 16:47:33 -05:00
& blockheight_states ,
2020-05-07 10:22:50 +09:30
& changed ,
2020-05-07 10:24:26 +09:30
& pbase ,
& penalty_tx )
2021-06-22 16:47:33 -05:00
| | ! fee_states_valid ( fee_states , channel - > opener )
| | ! height_states_valid ( blockheight_states , channel - > opener ) ) {
2020-08-25 11:03:16 +09:30
channel_internal_error ( channel , " bad fromwire_channeld_got_revoke %s " ,
2018-02-12 20:43:04 +10:30
tal_hex ( channel , msg ) ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:15:03 +09:30
}
2018-02-12 20:43:04 +10:30
log_debug ( channel - > log ,
2017-06-20 15:24:03 +09:30
" got revoke % " PRIu64 " : %zu changed " ,
revokenum , tal_count ( changed ) ) ;
2017-06-20 15:20:03 +09:30
/* Save any immediate failures for after we reply. */
2020-08-31 10:43:25 +09:30
badonions = tal_arrz ( msg , enum onion_wire , tal_count ( changed ) ) ;
2020-02-21 15:38:31 +10:30
failmsgs = tal_arrz ( msg , u8 * , tal_count ( changed ) ) ;
2017-06-20 15:20:03 +09:30
for ( i = 0 ; i < tal_count ( changed ) ; i + + ) {
2017-06-20 15:24:03 +09:30
/* If we're doing final accept, we need to forward */
if ( changed [ i ] . newstate = = RCVD_ADD_ACK_REVOCATION ) {
2020-02-21 15:38:31 +10:30
peer_accepted_htlc ( failmsgs ,
channel , changed [ i ] . id , false ,
& badonions [ i ] , & failmsgs [ i ] ) ;
2017-06-20 15:24:03 +09:30
} else {
2018-02-12 20:43:04 +10:30
if ( ! changed_htlc ( channel , & changed [ i ] ) ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel ,
2017-06-20 15:47:03 +09:30
" got_revoke: update failed " ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:24:03 +09:30
}
2017-06-20 15:20:03 +09:30
}
}
2017-06-20 15:21:03 +09:30
if ( revokenum > = ( 1ULL < < 48 ) ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel , " got_revoke: too many txs % " PRIu64 ,
2017-06-20 15:47:03 +09:30
revokenum ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:21:03 +09:30
}
2018-02-12 20:42:55 +10:30
if ( revokenum ! = revocations_received ( & channel - > their_shachain . chain ) ) {
2018-02-12 20:43:04 +10:30
channel_internal_error ( channel , " got_revoke: expected % " PRIu64
2017-06-20 15:47:03 +09:30
" got % " PRIu64 ,
2018-02-12 20:42:55 +10:30
revocations_received ( & channel - > their_shachain . chain ) , revokenum ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:21:03 +09:30
}
/* BOLT #2:
*
2018-06-17 19:43:44 +09:30
* - if the ` per_commitment_secret ` was not generated by the protocol
* in [ BOLT # 3 ] ( 03 - transactions . md # per - commitment - secret - requirements ) :
2022-03-31 19:40:50 +10:30
* - MAY send a ` warning ` and close the connection , or send an
* ` error ` and fail the channel .
2017-06-20 15:21:03 +09:30
*/
2018-02-12 20:43:04 +10:30
if ( ! wallet_shachain_add_hash ( ld - > wallet ,
2018-02-12 20:42:55 +10:30
& channel - > their_shachain ,
2017-07-19 16:55:47 +02:00
shachain_index ( revokenum ) ,
& per_commitment_secret ) ) {
2018-02-12 20:43:04 +10:30
channel_fail_permanent ( channel ,
feat: adds state change cause and message
This adds a `state_change` 'cause' to a channel.
A 'cause' is some initial 'reason' a channel was created or closed by:
/* Anything other than the reasons below. Should not happen. */
REASON_UNKNOWN,
/* Unconscious internal reasons, e.g. dev fail of a channel. */
REASON_LOCAL,
/* The operator or a plugin opened or closed a channel by intention. */
REASON_USER,
/* The remote closed or funded a channel with us by intention. */
REASON_REMOTE,
/* E.g. We need to close a channel because of bad signatures and such. */
REASON_PROTOCOL,
/* A channel was closed onchain, while we were offline. */
/* Note: This is very likely a conscious remote decision. */
REASON_ONCHAIN
If a 'cause' is known and a subsequent state change is made with
`REASON_UNKNOWN` the preceding cause will be used as reason, since a lot
(all `REASON_UNKNOWN`) state changes are a subsequent consequences of a prior
cause: local, user, remote, protocol or onchain.
Changelog-Added: Plugins: Channel closure resaon/cause to channel_state_changed notification
2020-10-28 11:46:12 +01:00
REASON_PROTOCOL ,
" Bad per_commitment_secret %s for % " PRIu64 ,
type_to_string ( msg , struct secret ,
& per_commitment_secret ) ,
revokenum ) ;
2017-10-12 17:05:04 +10:30
return ;
2017-06-20 15:21:03 +09:30
}
2020-09-17 11:28:59 +09:30
tal_free ( channel - > fee_states ) ;
channel - > fee_states = tal_steal ( channel , fee_states ) ;
2018-08-22 09:39:57 +09:30
2021-06-22 16:47:33 -05:00
tal_free ( channel - > blockheight_states ) ;
channel - > blockheight_states = tal_steal ( channel , blockheight_states ) ;
2017-06-20 15:25:03 +09:30
/* FIXME: Check per_commitment_secret -> per_commit_point */
2018-02-12 20:43:04 +10:30
update_per_commit_point ( channel , & next_per_commitment_point ) ;
2017-06-20 15:25:03 +09:30
2017-06-20 15:20:03 +09:30
/* Tell it we've committed, and to go ahead with revoke. */
2020-08-25 11:03:16 +09:30
msg = towire_channeld_got_revoke_reply ( msg ) ;
2018-02-12 20:42:55 +10:30
subd_send_msg ( channel - > owner , take ( msg ) ) ;
2017-06-20 15:15:03 +09:30
2017-06-20 15:20:03 +09:30
/* Now, any HTLCs we need to immediately fail? */
2017-06-20 15:24:03 +09:30
for ( i = 0 ; i < tal_count ( changed ) ; i + + ) {
2017-06-20 15:23:03 +09:30
struct htlc_in * hin ;
2017-06-20 15:20:03 +09:30
2020-02-21 15:38:31 +10:30
if ( badonions [ i ] ) {
2023-01-03 15:16:52 +10:30
hin = find_htlc_in ( ld - > htlcs_in , channel ,
2020-02-21 15:38:31 +10:30
changed [ i ] . id ) ;
local_fail_in_htlc_badonion ( hin , badonions [ i ] ) ;
} else if ( failmsgs [ i ] ) {
2023-01-03 15:16:52 +10:30
hin = find_htlc_in ( ld - > htlcs_in , channel ,
2020-02-21 15:38:31 +10:30
changed [ i ] . id ) ;
2020-02-21 15:40:02 +10:30
local_fail_in_htlc ( hin , failmsgs [ i ] ) ;
2020-02-21 15:38:31 +10:30
} else
2017-06-20 15:20:03 +09:30
continue ;
2019-04-15 22:27:22 +08:00
// in fact, now we don't know if this htlc is a forward or localpay!
wallet_forwarded_payment_add ( ld - > wallet ,
2022-03-31 13:44:27 +10:30
hin , FORWARD_STYLE_UNKNOWN , NULL , NULL ,
2019-04-15 22:27:22 +08:00
FORWARD_LOCAL_FAILED ,
2020-02-21 15:38:31 +10:30
badonions [ i ] ? badonions [ i ]
: fromwire_peektype ( failmsgs [ i ] ) ) ;
2017-06-20 15:20:03 +09:30
}
2018-02-12 20:43:04 +10:30
wallet_channel_save ( ld - > wallet , channel ) ;
2020-05-07 10:24:26 +09:30
if ( penalty_tx = = NULL )
return ;
payload = tal ( tmpctx , struct commitment_revocation_payload ) ;
payload - > commitment_txid = pbase - > txid ;
payload - > penalty_tx = tal_steal ( payload , penalty_tx ) ;
payload - > wallet = ld - > wallet ;
2021-09-03 16:24:46 +02:00
payload - > channel_dbid = channel - > dbid ;
2020-05-07 10:24:26 +09:30
payload - > commitnum = pbase - > commitment_num ;
2021-09-03 16:24:46 +02:00
payload - > channel_id = channel - > cid ;
2022-09-13 06:49:12 +09:30
plugin_hook_call_commitment_revocation ( ld , NULL , payload ) ;
2017-06-20 15:15:03 +09:30
}
2017-06-20 15:36:03 +09:30
2017-06-20 15:34:03 +09:30
/* FIXME: Load direct from db. */
2020-04-03 13:44:07 +10:30
const struct existing_htlc * * peer_htlcs ( const tal_t * ctx ,
const struct channel * channel )
2017-06-20 15:34:03 +09:30
{
2020-04-03 13:44:07 +10:30
struct existing_htlc * * htlcs ;
2017-06-20 15:34:03 +09:30
struct htlc_in_map_iter ini ;
struct htlc_out_map_iter outi ;
struct htlc_in * hin ;
struct htlc_out * hout ;
2018-02-12 20:43:04 +10:30
struct lightningd * ld = channel - > peer - > ld ;
2017-06-20 15:34:03 +09:30
2020-04-03 13:44:07 +10:30
htlcs = tal_arr ( ctx , struct existing_htlc * , 0 ) ;
2017-06-20 15:34:03 +09:30
2023-01-03 15:16:52 +10:30
for ( hin = htlc_in_map_first ( ld - > htlcs_in , & ini ) ;
2017-06-20 15:34:03 +09:30
hin ;
2023-01-03 15:16:52 +10:30
hin = htlc_in_map_next ( ld - > htlcs_in , & ini ) ) {
2020-04-03 13:44:07 +10:30
struct failed_htlc * f ;
struct existing_htlc * existing ;
2018-02-12 20:43:04 +10:30
if ( hin - > key . channel ! = channel )
2017-06-20 15:34:03 +09:30
continue ;
2020-02-21 15:40:44 +10:30
if ( hin - > badonion )
2020-04-03 13:44:07 +10:30
f = take ( mk_failed_htlc_badonion ( NULL , hin , hin - > badonion ) ) ;
else if ( hin - > failonion )
f = take ( mk_failed_htlc ( NULL , hin , hin - > failonion ) ) ;
else
f = NULL ;
existing = new_existing_htlc ( htlcs , hin - > key . id , hin - > hstate ,
hin - > msat , & hin - > payment_hash ,
hin - > cltv_expiry ,
hin - > onion_routing_packet ,
2020-04-11 12:52:40 +09:30
hin - > blinding ,
2020-04-03 13:44:07 +10:30
hin - > preimage ,
f ) ;
tal_arr_expand ( & htlcs , existing ) ;
2017-06-20 15:34:03 +09:30
}
2023-01-03 15:16:52 +10:30
for ( hout = htlc_out_map_first ( ld - > htlcs_out , & outi ) ;
2017-06-20 15:34:03 +09:30
hout ;
2023-01-03 15:16:52 +10:30
hout = htlc_out_map_next ( ld - > htlcs_out , & outi ) ) {
2020-04-03 13:44:07 +10:30
struct failed_htlc * f ;
struct existing_htlc * existing ;
2018-02-12 20:43:04 +10:30
if ( hout - > key . channel ! = channel )
2017-06-20 15:34:03 +09:30
continue ;
2020-04-03 13:44:07 +10:30
/* Note that channeld doesn't actually care *why* outgoing
* HTLCs failed , so just use a dummy here . */
if ( hout - > failonion | | hout - > failmsg ) {
f = take ( tal ( NULL , struct failed_htlc ) ) ;
f - > id = hout - > key . id ;
f - > sha256_of_onion = tal ( f , struct sha256 ) ;
memset ( f - > sha256_of_onion , 0 ,
sizeof ( * f - > sha256_of_onion ) ) ;
f - > badonion = BADONION ;
f - > onion = NULL ;
} else
f = NULL ;
2020-02-18 10:25:58 +10:30
2020-04-03 13:44:07 +10:30
existing = new_existing_htlc ( htlcs , hout - > key . id , hout - > hstate ,
hout - > msat , & hout - > payment_hash ,
hout - > cltv_expiry ,
hout - > onion_routing_packet ,
2020-04-11 12:52:40 +09:30
hout - > blinding ,
2020-04-03 13:44:07 +10:30
hout - > preimage ,
f ) ;
tal_arr_expand ( & htlcs , existing ) ;
2017-06-20 15:34:03 +09:30
}
2020-04-03 13:44:07 +10:30
return cast_const2 ( const struct existing_htlc * * , htlcs ) ;
2017-06-20 15:34:03 +09:30
}
2017-11-02 10:23:19 +10:30
2018-02-21 07:29:09 +10:30
/* If channel is NULL, free them all (for shutdown) */
void free_htlcs ( struct lightningd * ld , const struct channel * channel )
{
struct htlc_out_map_iter outi ;
struct htlc_out * hout ;
struct htlc_in_map_iter ini ;
struct htlc_in * hin ;
bool deleted ;
/* FIXME: Implement check_htlcs to ensure no dangling hout->in ptrs! */
do {
deleted = false ;
2023-01-03 15:16:52 +10:30
for ( hout = htlc_out_map_first ( ld - > htlcs_out , & outi ) ;
2018-02-21 07:29:09 +10:30
hout ;
2023-01-03 15:16:52 +10:30
hout = htlc_out_map_next ( ld - > htlcs_out , & outi ) ) {
2018-02-21 07:29:09 +10:30
if ( channel & & hout - > key . channel ! = channel )
continue ;
tal_free ( hout ) ;
deleted = true ;
}
2023-01-03 15:16:52 +10:30
for ( hin = htlc_in_map_first ( ld - > htlcs_in , & ini ) ;
2018-02-21 07:29:09 +10:30
hin ;
2023-01-03 15:16:52 +10:30
hin = htlc_in_map_next ( ld - > htlcs_in , & ini ) ) {
2018-02-21 07:29:09 +10:30
if ( channel & & hin - > key . channel ! = channel )
continue ;
tal_free ( hin ) ;
deleted = true ;
}
/* Can skip over elements due to iterating while deleting. */
} while ( deleted ) ;
}
2017-11-02 10:24:00 +10:30
/* BOLT #2:
*
2018-06-17 19:43:44 +09:30
* 2. the deadline for offered HTLCs : the deadline after which the channel has
* to be failed and timed out on - chain . This is ` G ` blocks after the HTLC ' s
2020-08-20 16:20:47 +09:30
* ` cltv_expiry ` : 1 or 2 blocks is reasonable .
2017-11-02 10:24:00 +10:30
*/
static u32 htlc_out_deadline ( const struct htlc_out * hout )
2017-11-02 10:23:19 +10:30
{
2017-11-02 10:24:00 +10:30
return hout - > cltv_expiry + 1 ;
2017-11-02 10:23:19 +10:30
}
2017-11-02 10:26:07 +10:30
/* BOLT #2:
*
2018-06-17 19:43:44 +09:30
* 3. the deadline for received HTLCs this node has fulfilled : the deadline
* after which the channel has to be failed and the HTLC fulfilled on - chain
* before its ` cltv_expiry ` . See steps 4 - 7 above , which imply a deadline of
2020-08-20 16:20:47 +09:30
* ` 2 R + G + S ` blocks before ` cltv_expiry ` : 18 blocks is reasonable .
2017-11-02 10:26:07 +10:30
*/
/* We approximate this, by using half the cltv_expiry_delta (3R+2G+2S),
* rounded up . */
static u32 htlc_in_deadline ( const struct lightningd * ld ,
const struct htlc_in * hin )
{
return hin - > cltv_expiry - ( ld - > config . cltv_expiry_delta + 1 ) / 2 ;
}
2023-07-24 12:38:50 +09:30
/* onchaind might fail to time out an HTLC: maybe fees spiked, or maybe
* it decided it wasn ' t worthwhile . This risks cascading failure if
* it was routed : the incoming peer will get upset with us , too .
*
* So , if we ' re within 3 blocks of this happening , we fail upstream .
* It ' s weird to do this by looking at hout , rather than hin , but
* there ' s a pointer from hout - > hin and not vice versa ( we don ' t
* normally need it ) . */
static void consider_failing_incoming ( struct lightningd * ld ,
u32 height ,
struct htlc_out * hout )
{
/* Already failed or succeeded? */
if ( hout - > failmsg | | hout - > failonion | | hout - > preimage )
return ;
/* Has no corresponding input we should be stressed about? */
if ( ! hout - > in )
return ;
/* Already done it once? */
if ( hout - > in - > failonion )
return ;
/* OK, if we're within 3 blocks of upstream getting upset, force it
* to fail without waiting for onchaind . */
if ( height + 3 < hout - > in - > cltv_expiry )
return ;
log_unusual ( hout - > key . channel - > log ,
" Abandoning unresolved onchain HTLC at block %u "
" (expired at %u) to avoid peer closing incoming HTLC at block %u " ,
height , hout - > cltv_expiry , hout - > in - > cltv_expiry ) ;
local_fail_in_htlc ( hout - > in , take ( towire_permanent_channel_failure ( NULL ) ) ) ;
}
2018-05-06 13:32:01 +00:00
void htlcs_notify_new_block ( struct lightningd * ld , u32 height )
2017-11-02 10:24:00 +10:30
{
bool removed ;
/* BOLT #2:
*
2018-06-17 19:43:44 +09:30
* - if an HTLC which it offered is in either node ' s current
* commitment transaction , AND is past this timeout deadline :
2022-03-31 19:40:50 +10:30
* - SHOULD send an ` error ` to the receiving peer ( if connected ) .
2018-06-17 19:43:44 +09:30
* - MUST fail the channel .
2017-11-02 10:24:00 +10:30
*/
/* FIXME: use db to look this up in one go (earliest deadline per-peer) */
do {
struct htlc_out * hout ;
struct htlc_out_map_iter outi ;
removed = false ;
2023-01-03 15:16:52 +10:30
for ( hout = htlc_out_map_first ( ld - > htlcs_out , & outi ) ;
2017-11-02 10:24:00 +10:30
hout ;
2023-01-03 15:16:52 +10:30
hout = htlc_out_map_next ( ld - > htlcs_out , & outi ) ) {
2017-11-02 10:24:00 +10:30
/* Not timed out yet? */
if ( height < htlc_out_deadline ( hout ) )
continue ;
2023-10-02 09:29:49 +10:30
/* Channel dying already? */
2023-10-02 09:29:51 +10:30
if ( ! channel_state_can_add_htlc ( hout - > key . channel - > state ) ) {
2023-07-24 12:38:50 +09:30
consider_failing_incoming ( ld , height , hout ) ;
2017-11-02 10:24:00 +10:30
continue ;
2023-07-24 12:38:50 +09:30
}
2017-11-02 10:24:00 +10:30
/* Peer already failed, or we hit it? */
2018-02-12 20:43:04 +10:30
if ( hout - > key . channel - > error )
2017-11-02 10:24:00 +10:30
continue ;
2018-02-12 20:43:04 +10:30
channel_fail_permanent ( hout - > key . channel ,
feat: adds state change cause and message
This adds a `state_change` 'cause' to a channel.
A 'cause' is some initial 'reason' a channel was created or closed by:
/* Anything other than the reasons below. Should not happen. */
REASON_UNKNOWN,
/* Unconscious internal reasons, e.g. dev fail of a channel. */
REASON_LOCAL,
/* The operator or a plugin opened or closed a channel by intention. */
REASON_USER,
/* The remote closed or funded a channel with us by intention. */
REASON_REMOTE,
/* E.g. We need to close a channel because of bad signatures and such. */
REASON_PROTOCOL,
/* A channel was closed onchain, while we were offline. */
/* Note: This is very likely a conscious remote decision. */
REASON_ONCHAIN
If a 'cause' is known and a subsequent state change is made with
`REASON_UNKNOWN` the preceding cause will be used as reason, since a lot
(all `REASON_UNKNOWN`) state changes are a subsequent consequences of a prior
cause: local, user, remote, protocol or onchain.
Changelog-Added: Plugins: Channel closure resaon/cause to channel_state_changed notification
2020-10-28 11:46:12 +01:00
REASON_PROTOCOL ,
" Offered HTLC % " PRIu64
" %s cltv %u hit deadline " ,
hout - > key . id ,
htlc_state_name ( hout - > hstate ) ,
hout - > cltv_expiry ) ;
2017-11-02 10:24:00 +10:30
removed = true ;
}
/* Iteration while removing is safe, but can skip entries! */
} while ( removed ) ;
2017-11-02 10:26:07 +10:30
/* BOLT #2:
*
2018-06-17 19:43:44 +09:30
* - for each HTLC it is attempting to fulfill :
* - MUST estimate a fulfillment deadline .
* . . .
* - if an HTLC it has fulfilled is in either node ' s current commitment
* transaction , AND is past this fulfillment deadline :
2022-03-31 19:40:50 +10:30
* - SHOULD send an ` error ` to the offering peer ( if connected ) .
2019-07-09 18:58:57 -05:00
* - MUST fail the channel .
2017-11-02 10:26:07 +10:30
*/
do {
struct htlc_in * hin ;
struct htlc_in_map_iter ini ;
removed = false ;
2023-01-03 15:16:52 +10:30
for ( hin = htlc_in_map_first ( ld - > htlcs_in , & ini ) ;
2017-11-02 10:26:07 +10:30
hin ;
2023-01-03 15:16:52 +10:30
hin = htlc_in_map_next ( ld - > htlcs_in , & ini ) ) {
2018-02-12 20:43:04 +10:30
struct channel * channel = hin - > key . channel ;
2018-02-12 20:43:04 +10:30
2017-11-02 10:26:07 +10:30
/* Not fulfilled? If overdue, that's their problem... */
if ( ! hin - > preimage )
continue ;
/* Not timed out yet? */
if ( height < htlc_in_deadline ( ld , hin ) )
continue ;
/* Peer on chain already? */
2023-10-02 09:29:49 +10:30
if ( channel_state_failing_onchain ( channel - > state ) )
2017-11-02 10:26:07 +10:30
continue ;
/* Peer already failed, or we hit it? */
2018-02-12 20:43:04 +10:30
if ( channel - > error )
2017-11-02 10:26:07 +10:30
continue ;
2018-02-12 20:43:04 +10:30
channel_fail_permanent ( channel ,
feat: adds state change cause and message
This adds a `state_change` 'cause' to a channel.
A 'cause' is some initial 'reason' a channel was created or closed by:
/* Anything other than the reasons below. Should not happen. */
REASON_UNKNOWN,
/* Unconscious internal reasons, e.g. dev fail of a channel. */
REASON_LOCAL,
/* The operator or a plugin opened or closed a channel by intention. */
REASON_USER,
/* The remote closed or funded a channel with us by intention. */
REASON_REMOTE,
/* E.g. We need to close a channel because of bad signatures and such. */
REASON_PROTOCOL,
/* A channel was closed onchain, while we were offline. */
/* Note: This is very likely a conscious remote decision. */
REASON_ONCHAIN
If a 'cause' is known and a subsequent state change is made with
`REASON_UNKNOWN` the preceding cause will be used as reason, since a lot
(all `REASON_UNKNOWN`) state changes are a subsequent consequences of a prior
cause: local, user, remote, protocol or onchain.
Changelog-Added: Plugins: Channel closure resaon/cause to channel_state_changed notification
2020-10-28 11:46:12 +01:00
REASON_PROTOCOL ,
" Fulfilled HTLC % " PRIu64
" %s cltv %u hit deadline " ,
hin - > key . id ,
htlc_state_name ( hin - > hstate ) ,
hin - > cltv_expiry ) ;
2017-11-02 10:26:07 +10:30
removed = true ;
}
/* Iteration while removing is safe, but can skip entries! */
} while ( removed ) ;
2017-11-02 10:24:00 +10:30
}
2017-11-21 14:04:36 +10:30
2018-10-09 19:26:52 +10:30
# ifdef COMPAT_V061
2018-10-09 19:24:52 +10:30
static void fixup_hout ( struct lightningd * ld , struct htlc_out * hout )
{
const char * fix ;
/* We didn't save HTLC failure information to the database. So when
* busy nodes restarted ( y ' know , our most important users ! ) they would
* find themselves with missing fields .
*
* Fortunately , most of the network is honest : re - sending an old HTLC
* just causes failure ( though we assert ( ) when we try to push the
* failure to the incoming HTLC which has already succeeded ! ) .
*/
/* We care about HTLCs being removed only, not those being added. */
if ( hout - > hstate < RCVD_REMOVE_HTLC )
return ;
/* Successful ones are fine. */
if ( hout - > preimage )
return ;
/* Failed ones (only happens after db fixed!) OK. */
2020-02-21 15:36:58 +10:30
if ( hout - > failmsg | | hout - > failonion )
2018-10-09 19:24:52 +10:30
return ;
/* payment_preimage for HTLC in *was* stored, so look for that. */
if ( hout - > in & & hout - > in - > preimage ) {
hout - > preimage = tal_dup ( hout , struct preimage ,
hout - > in - > preimage ) ;
fix = " restoring preimage from incoming HTLC " ;
} else {
2020-02-21 15:36:58 +10:30
hout - > failmsg = towire_temporary_node_failure ( hout ) ;
fix = " subsituting temporary node failure " ;
2018-10-09 19:24:52 +10:30
}
log_broken ( ld - > log , " HTLC #% " PRIu64 " (%s) "
2019-02-21 14:15:55 +10:30
" for amount %s "
2018-10-09 19:24:52 +10:30
" to %s "
" is missing a resolution: %s. " ,
hout - > key . id , htlc_state_name ( hout - > hstate ) ,
2019-02-21 14:15:55 +10:30
type_to_string ( tmpctx , struct amount_msat , & hout - > msat ) ,
2019-04-08 19:28:32 +09:30
type_to_string ( tmpctx , struct node_id ,
2018-10-09 19:24:52 +10:30
& hout - > key . channel - > peer - > id ) ,
fix ) ;
}
2019-12-12 10:09:10 +10:30
void fixup_htlcs_out ( struct lightningd * ld )
2018-09-03 10:38:53 +09:30
{
struct htlc_out_map_iter outi ;
struct htlc_out * hout ;
2023-01-03 15:16:52 +10:30
for ( hout = htlc_out_map_first ( ld - > htlcs_out , & outi ) ;
2019-12-12 10:09:10 +10:30
hout ;
2023-01-03 15:16:52 +10:30
hout = htlc_out_map_next ( ld - > htlcs_out , & outi ) ) {
2019-12-12 10:09:10 +10:30
if ( ! hout - > am_origin )
fixup_hout ( ld , hout ) ;
2018-09-03 10:38:53 +09:30
}
2019-08-10 14:54:57 +09:30
}
2019-12-12 10:09:10 +10:30
# endif /* COMPAT_V061 */
2019-08-10 14:54:57 +09:30
2019-12-12 10:09:10 +10:30
void htlcs_resubmit ( struct lightningd * ld ,
2023-01-17 11:17:12 +10:30
struct htlc_in_map * unconnected_htlcs_in STEALS )
2019-08-10 14:54:57 +09:30
{
struct htlc_in * hin ;
struct htlc_in_map_iter ini ;
2020-08-31 10:43:25 +09:30
enum onion_wire badonion COMPILER_WANTS_INIT ( " gcc7.4.0 bad, 8.3 OK " ) ;
2020-02-21 15:38:31 +10:30
u8 * failmsg ;
2019-08-10 14:54:57 +09:30
2019-12-12 10:09:10 +10:30
/* Now retry any which were stuck. */
for ( hin = htlc_in_map_first ( unconnected_htlcs_in , & ini ) ;
2019-08-10 14:54:57 +09:30
hin ;
2019-12-12 10:09:10 +10:30
hin = htlc_in_map_next ( unconnected_htlcs_in , & ini ) ) {
if ( hin - > hstate ! = RCVD_ADD_ACK_REVOCATION )
continue ;
2018-10-10 17:02:46 +10:30
log_unusual ( hin - > key . channel - > log ,
2019-05-21 14:10:34 +02:00
" Replaying old unprocessed HTLC #% " PRIu64 ,
2018-10-10 17:02:46 +10:30
hin - > key . id ) ;
2020-02-21 15:38:31 +10:30
if ( ! peer_accepted_htlc ( tmpctx , hin - > key . channel , hin - > key . id ,
true , & badonion , & failmsg ) ) {
if ( failmsg )
2020-02-21 15:40:02 +10:30
local_fail_in_htlc ( hin , failmsg ) ;
2020-02-21 15:38:31 +10:30
else
local_fail_in_htlc_badonion ( hin , badonion ) ;
2019-05-21 14:10:34 +02:00
}
2018-10-10 17:02:46 +10:30
}
/* Don't leak memory! */
2019-12-12 10:09:10 +10:30
tal_free ( unconnected_htlcs_in ) ;
2018-09-03 10:38:53 +09:30
}
2018-12-16 15:22:06 +10:30
static struct command_result * json_dev_ignore_htlcs ( struct command * cmd ,
const char * buffer ,
const jsmntok_t * obj UNNEEDED ,
const jsmntok_t * params )
2018-04-03 16:49:42 +09:30
{
2019-04-08 19:28:32 +09:30
struct node_id * peerid ;
2018-04-03 16:49:42 +09:30
struct peer * peer ;
2018-08-13 15:31:40 -05:00
bool * ignore ;
2018-04-03 16:49:42 +09:30
2023-10-25 07:39:04 +10:30
if ( ! param_check ( cmd , buffer , params ,
p_req ( " id " , param_node_id , & peerid ) ,
p_req ( " ignore " , param_bool , & ignore ) ,
NULL ) )
2018-12-16 15:22:06 +10:30
return command_param_failed ( ) ;
2018-04-03 16:49:42 +09:30
2018-08-14 16:19:31 -05:00
peer = peer_by_id ( cmd - > ld , peerid ) ;
2018-04-03 16:49:42 +09:30
if ( ! peer ) {
2018-12-16 15:22:06 +10:30
return command_fail ( cmd , LIGHTNINGD ,
" Could not find channel with that peer " ) ;
2018-04-03 16:49:42 +09:30
}
2023-10-25 07:39:04 +10:30
if ( command_check_only ( cmd ) )
return command_check_done ( cmd ) ;
2023-09-21 15:06:28 +09:30
peer - > dev_ignore_htlcs = * ignore ;
2018-04-03 16:49:42 +09:30
2019-06-12 10:08:54 +09:30
return command_success ( cmd , json_stream_success ( cmd ) ) ;
2018-04-03 16:49:42 +09:30
}
static const struct json_command dev_ignore_htlcs = {
2019-05-22 16:08:16 +02:00
" dev-ignore-htlcs " ,
" developer " ,
json_dev_ignore_htlcs ,
2023-09-21 15:06:27 +09:30
" Set ignoring incoming HTLCs for peer {id} to {ignore} " ,
. dev_only = true ,
2018-04-03 16:49:42 +09:30
} ;
2020-02-18 10:26:58 +10:30
2018-04-03 16:49:42 +09:30
AUTODATA ( json_command , & dev_ignore_htlcs ) ;
2018-10-17 20:11:04 +02:00
2022-09-19 10:19:53 +09:30
static struct command_result * param_channel ( struct command * cmd ,
const char * name ,
const char * buffer ,
const jsmntok_t * tok ,
struct channel * * chan )
{
struct channel_id cid ;
struct short_channel_id scid ;
if ( json_tok_channel_id ( buffer , tok , & cid ) ) {
* chan = channel_by_cid ( cmd - > ld , & cid ) ;
if ( ! * chan )
return command_fail_badparam ( cmd , name , buffer , tok ,
" unknown channel " ) ;
return NULL ;
} else if ( json_to_short_channel_id ( buffer , tok , & scid ) ) {
* chan = any_channel_by_scid ( cmd - > ld , & scid , true ) ;
if ( ! * chan )
return command_fail_badparam ( cmd , name , buffer , tok ,
" unknown channel " ) ;
return NULL ;
}
return command_fail_badparam ( cmd , name , buffer , tok ,
" must be channel id or short channel id " ) ;
}
static struct command_result * json_listhtlcs ( struct command * cmd ,
const char * buffer ,
const jsmntok_t * obj UNNEEDED ,
const jsmntok_t * params )
{
struct json_stream * response ;
struct channel * chan ;
struct wallet_htlc_iter * i ;
struct short_channel_id scid ;
u64 htlc_id ;
int cltv_expiry ;
enum side owner ;
struct amount_msat msat ;
struct sha256 payment_hash ;
enum htlc_state hstate ;
if ( ! param ( cmd , buffer , params ,
p_opt ( " id " , param_channel , & chan ) ,
NULL ) )
return command_param_failed ( ) ;
response = json_stream_success ( cmd ) ;
json_array_start ( response , " htlcs " ) ;
for ( i = wallet_htlcs_first ( cmd , cmd - > ld - > wallet , chan ,
& scid , & htlc_id , & cltv_expiry , & owner , & msat ,
& payment_hash , & hstate ) ;
i ;
i = wallet_htlcs_next ( cmd - > ld - > wallet , i ,
& scid , & htlc_id , & cltv_expiry , & owner , & msat ,
& payment_hash , & hstate ) ) {
json_object_start ( response , NULL ) ;
json_add_short_channel_id ( response , " short_channel_id " , & scid ) ;
json_add_u64 ( response , " id " , htlc_id ) ;
json_add_u32 ( response , " expiry " , cltv_expiry ) ;
json_add_string ( response , " direction " ,
owner = = LOCAL ? " out " : " in " ) ;
2023-03-14 15:51:50 +10:30
json_add_amount_msat ( response , " amount_msat " , msat ) ;
2022-09-19 10:19:53 +09:30
json_add_sha256 ( response , " payment_hash " , & payment_hash ) ;
json_add_string ( response , " state " , htlc_state_name ( hstate ) ) ;
json_object_end ( response ) ;
}
json_array_end ( response ) ;
return command_success ( cmd , response ) ;
}
static const struct json_command listhtlcs_command = {
" listhtlcs " ,
" channels " ,
json_listhtlcs ,
" List all known HTLCS (optionally, just for [id] (scid or channel id)) "
} ;
AUTODATA ( json_command , & listhtlcs_command ) ;