@ -715,84 +715,29 @@ static enum onion_type send_onion(struct lightningd *ld,
payment_hash , partid , onion , NULL , hout ) ;
}
/* Returns command_result if cmd was resolved, NULL if not yet called. */
/* destination/route_channels/route_nodes are NULL (and path_secrets may be NULL)
* if we ' re sending a raw onion . */
static struct command_result *
send_payment ( struct lightningd * ld ,
struct command * cmd ,
const struct sha256 * rhash ,
u64 partid ,
const struct route_hop * route ,
struct amount_msat msat ,
struct amount_msat total_msat ,
const char * label TAKES ,
const char * b11str TAKES ,
const struct secret * payment_secret )
send_payment_core ( struct lightningd * ld ,
struct command * cmd ,
const struct sha256 * rhash ,
u64 partid ,
const struct route_hop * first_hop ,
struct amount_msat msat ,
struct amount_msat total_msat ,
const char * label TAKES ,
const char * b11str TAKES ,
const struct onionpacket * packet ,
const struct node_id * destination ,
struct node_id * route_nodes TAKES ,
struct short_channel_id * route_channels TAKES ,
struct secret * path_secrets )
{
unsigned int base_expiry ;
struct onionpacket * packet ;
struct secret * path_secrets ;
struct wallet_payment * payment ;
struct channel * channel ;
enum onion_type failcode ;
size_t i , n_hops = tal_count ( route ) ;
struct node_id * ids = tal_arr ( tmpctx , struct node_id , n_hops ) ;
struct wallet_payment * payment = NULL ;
struct htlc_out * hout ;
struct short_channel_id * channels ;
struct routing_failure * fail ;
struct channel * channel ;
struct sphinx_path * path ;
struct pubkey pubkey ;
bool final_tlv , ret ;
u8 * onion ;
/* Expiry for HTLCs is absolute. And add one to give some margin. */
base_expiry = get_block_height ( ld - > topology ) + 1 ;
path = sphinx_path_new ( tmpctx , rhash - > u . u8 ) ;
/* Extract IDs for each hop: create_onionpacket wants array. */
for ( i = 0 ; i < n_hops ; i + + )
ids [ i ] = route [ i ] . nodeid ;
/* Create sphinx path */
for ( i = 0 ; i < n_hops - 1 ; i + + ) {
ret = pubkey_from_node_id ( & pubkey , & ids [ i ] ) ;
assert ( ret ) ;
sphinx_add_hop ( path , & pubkey ,
take ( onion_nonfinal_hop ( NULL ,
should_use_tlv ( route [ i ] . style ) ,
& route [ i + 1 ] . channel_id ,
route [ i + 1 ] . amount ,
base_expiry + route [ i + 1 ] . delay ) ) ) ;
}
/* And finally set the final hop to the special values in
* BOLT04 */
ret = pubkey_from_node_id ( & pubkey , & ids [ i ] ) ;
assert ( ret ) ;
final_tlv = should_use_tlv ( route [ i ] . style ) ;
/* BOLT-3a09bc54f8443c4757b47541a5310aff6377ee21 #4:
* - Unless ` node_announcement ` , ` init ` message or the
* [ BOLT # 11 ] ( 11 - payment - encoding . md # tagged - fields ) offers feature
* ` var_onion_optin ` :
* - MUST use the legacy payload format instead .
*/
/* In our case, we don't use it unless we also have a payment_secret;
* everyone should support this eventually */
if ( ! final_tlv & & payment_secret )
final_tlv = true ;
onion = onion_final_hop ( cmd ,
final_tlv ,
route [ i ] . amount ,
base_expiry + route [ i ] . delay ,
route [ i ] . amount , payment_secret ) ;
if ( ! onion ) {
return command_fail ( cmd , PAY_DESTINATION_PERM_FAIL ,
" Destination does not support "
" payment_secret " ) ;
}
sphinx_add_hop ( path , & pubkey , onion ) ;
/* Now, do we already have a payment? */
payment = wallet_payment_by_hash ( tmpctx , ld - > wallet , rhash , partid ) ;
@ -813,9 +758,8 @@ send_payment(struct lightningd *ld,
struct amount_msat ,
& payment - > msatoshi ) ) ;
}
if ( payment - > destination & &
! node_id_eq ( payment - > destination ,
& ids [ n_hops - 1 ] ) ) {
if ( payment - > destination & & destination
& & ! node_id_eq ( payment - > destination , destination ) ) {
return command_fail ( cmd , PAY_RHASH_ALREADY_USED ,
" Already succeeded to %s " ,
type_to_string ( tmpctx ,
@ -827,7 +771,7 @@ send_payment(struct lightningd *ld,
log_debug ( ld - > log , " send_payment: found previous, retrying " ) ;
}
channel = active_channel_by_id ( ld , & ids [ 0 ] , NULL ) ;
channel = active_channel_by_id ( ld , & first_hop - > nodeid , NULL ) ;
if ( ! channel ) {
struct json_stream * data
= json_stream_fail ( cmd , PAY_TRY_OTHER_ROUTE ,
@ -835,35 +779,26 @@ send_payment(struct lightningd *ld,
" peer found " ) ;
json_add_routefail_info ( data , 0 , WIRE_UNKNOWN_NEXT_PEER ,
& ld - > id , & route [ 0 ] . channel_id ,
node_id_idx ( & ld - > id , & route [ 0 ] . nodeid ) ,
& ld - > id , & first_hop - > channel_id ,
node_id_idx ( & ld - > id , & first_hop - > nodeid ) ,
NULL ) ;
json_object_end ( data ) ;
return command_failed ( cmd , data ) ;
}
packet = create_onionpacket ( tmpctx , path , & path_secrets ) ;
failcode = send_onion ( ld , packet , & route [ 0 ] , rhash , partid ,
failcode = send_onion ( ld , packet , first_hop , rhash , partid ,
channel , & hout ) ;
log_info ( ld - > log , " Sending %s over %zu hops to deliver %s " ,
type_to_string ( tmpctx , struct amount_msat , & route [ 0 ] . amount ) ,
n_hops , type_to_string ( tmpctx , struct amount_msat , & msat ) ) ;
if ( failcode ) {
fail = immediate_routing_failure ( cmd , ld ,
failcode ,
& route [ 0 ] . channel_id ,
& first_hop - > channel_id ,
& channel - > peer - > id ) ;
return sendpay_fail ( cmd , payment , PAY_TRY_OTHER_ROUTE ,
NULL , fail , " First peer not ready " ) ;
}
/* Copy channels used along the route. */
channels = tal_arr ( tmpctx , struct short_channel_id , n_hops ) ;
for ( i = 0 ; i < n_hops ; + + i )
channels [ i ] = route [ i ] . channel_id ;
/* If we're retrying, delete all trace of previous one. We delete
* outgoing HTLC , too , otherwise it gets reported to onchaind as
* a possibility , and we end up in handle_missing_htlc_output - >
@ -880,16 +815,25 @@ send_payment(struct lightningd *ld,
payment - > id = 0 ;
payment - > payment_hash = * rhash ;
payment - > partid = partid ;
payment - > destination = tal_dup ( payment , struct node_id , & ids [ n_hops - 1 ] ) ;
if ( destination )
payment - > destination = tal_dup ( payment , struct node_id , destination ) ;
else
payment - > destination = NULL ;
payment - > status = PAYMENT_PENDING ;
payment - > msatoshi = msat ;
payment - > msatoshi_sent = route [ 0 ] . amount ;
payment - > msatoshi_sent = first_hop - > amount ;
payment - > total_msat = total_msat ;
payment - > timestamp = time_now ( ) . ts . tv_sec ;
payment - > payment_preimage = NULL ;
payment - > path_secrets = tal_steal ( payment , path_secrets ) ;
payment - > route_nodes = tal_steal ( payment , ids ) ;
payment - > route_channels = tal_steal ( payment , channels ) ;
if ( route_nodes )
payment - > route_nodes = tal_steal ( payment , route_nodes ) ;
else
payment - > route_nodes = NULL ;
if ( route_channels )
payment - > route_channels = tal_steal ( payment , route_channels ) ;
else
payment - > route_channels = NULL ;
payment - > failonion = NULL ;
if ( label ! = NULL )
payment - > label = tal_strdup ( payment , label ) ;
@ -904,7 +848,95 @@ send_payment(struct lightningd *ld,
wallet_payment_setup ( ld - > wallet , payment ) ;
add_sendpay_waiter ( ld , cmd , rhash ) ;
return NULL ;
return command_still_pending ( cmd ) ;
}
static struct command_result *
send_payment ( struct lightningd * ld ,
struct command * cmd ,
const struct sha256 * rhash ,
u64 partid ,
const struct route_hop * route ,
struct amount_msat msat ,
struct amount_msat total_msat ,
const char * label TAKES ,
const char * b11str TAKES ,
const struct secret * payment_secret )
{
unsigned int base_expiry ;
struct onionpacket * packet ;
struct secret * path_secrets ;
size_t i , n_hops = tal_count ( route ) ;
struct node_id * ids = tal_arr ( tmpctx , struct node_id , n_hops ) ;
struct short_channel_id * channels ;
struct sphinx_path * path ;
struct pubkey pubkey ;
bool final_tlv , ret ;
u8 * onion ;
/* Expiry for HTLCs is absolute. And add one to give some margin. */
base_expiry = get_block_height ( ld - > topology ) + 1 ;
path = sphinx_path_new ( tmpctx , rhash - > u . u8 ) ;
/* Extract IDs for each hop: create_onionpacket wants array. */
for ( i = 0 ; i < n_hops ; i + + )
ids [ i ] = route [ i ] . nodeid ;
/* Create sphinx path */
for ( i = 0 ; i < n_hops - 1 ; i + + ) {
ret = pubkey_from_node_id ( & pubkey , & ids [ i ] ) ;
assert ( ret ) ;
sphinx_add_hop ( path , & pubkey ,
take ( onion_nonfinal_hop ( NULL ,
should_use_tlv ( route [ i ] . style ) ,
& route [ i + 1 ] . channel_id ,
route [ i + 1 ] . amount ,
base_expiry + route [ i + 1 ] . delay ) ) ) ;
}
/* And finally set the final hop to the special values in
* BOLT04 */
ret = pubkey_from_node_id ( & pubkey , & ids [ i ] ) ;
assert ( ret ) ;
final_tlv = should_use_tlv ( route [ i ] . style ) ;
/* BOLT-3a09bc54f8443c4757b47541a5310aff6377ee21 #4:
* - Unless ` node_announcement ` , ` init ` message or the
* [ BOLT # 11 ] ( 11 - payment - encoding . md # tagged - fields ) offers feature
* ` var_onion_optin ` :
* - MUST use the legacy payload format instead .
*/
/* In our case, we don't use it unless we also have a payment_secret;
* everyone should support this eventually */
if ( ! final_tlv & & payment_secret )
final_tlv = true ;
onion = onion_final_hop ( cmd ,
final_tlv ,
route [ i ] . amount ,
base_expiry + route [ i ] . delay ,
route [ i ] . amount , payment_secret ) ;
if ( ! onion ) {
return command_fail ( cmd , PAY_DESTINATION_PERM_FAIL ,
" Destination does not support "
" payment_secret " ) ;
}
sphinx_add_hop ( path , & pubkey , onion ) ;
/* Copy channels used along the route. */
channels = tal_arr ( tmpctx , struct short_channel_id , n_hops ) ;
for ( i = 0 ; i < n_hops ; + + i )
channels [ i ] = route [ i ] . channel_id ;
log_info ( ld - > log , " Sending %s over %zu hops to deliver %s " ,
type_to_string ( tmpctx , struct amount_msat , & route [ 0 ] . amount ) ,
n_hops , type_to_string ( tmpctx , struct amount_msat , & msat ) ) ;
packet = create_onionpacket ( tmpctx , path , & path_secrets ) ;
return send_payment_core ( ld , cmd , rhash , partid , & route [ 0 ] ,
msat , total_msat , label , b11str ,
packet , & ids [ n_hops - 1 ] , ids ,
channels , path_secrets ) ;
}
static struct command_result *
@ -991,12 +1023,9 @@ static struct command_result *json_sendonion(struct command *cmd,
u8 * onion ;
struct onionpacket packet ;
enum onion_type failcode ;
struct htlc_out * hout ;
struct route_hop * first_hop ;
struct sha256 * payment_hash ;
struct channel * channel ;
struct lightningd * ld = cmd - > ld ;
struct wallet_payment * payment ;
const char * label ;
struct secret * path_secrets ;
@ -1017,74 +1046,12 @@ static struct command_result *json_sendonion(struct command *cmd,
" with failcode=%d " ,
failcode ) ;
/* Now, do we already have a payment? */
payment = wallet_payment_by_hash ( tmpctx , ld - > wallet , payment_hash , /* FIXME: Set partid! */ 0 ) ;
if ( payment ) {
if ( payment - > status = = PAYMENT_PENDING ) {
log_debug ( ld - > log , " send_payment: previous still in progress " ) ;
return json_sendpay_in_progress ( cmd , payment ) ;
}
if ( payment - > status = = PAYMENT_COMPLETE ) {
log_debug ( ld - > log , " send_payment: previous succeeded " ) ;
return sendpay_success ( cmd , payment ) ;
}
log_debug ( ld - > log , " send_payment: found previous, retrying " ) ;
}
channel = active_channel_by_id ( ld , & first_hop - > nodeid , NULL ) ;
if ( ! channel ) {
struct json_stream * data
= json_stream_fail ( cmd , PAY_TRY_OTHER_ROUTE ,
" No connection to first "
" peer found " ) ;
json_add_routefail_info ( data , 0 , WIRE_UNKNOWN_NEXT_PEER ,
& ld - > id , & first_hop - > channel_id ,
node_id_idx ( & ld - > id , & first_hop - > nodeid ) ,
NULL ) ;
json_object_end ( data ) ;
return command_failed ( cmd , data ) ;
}
/* Cleanup any prior payment. We're about to retry. */
if ( payment ) {
wallet_payment_delete ( ld - > wallet , payment_hash , /* FIXME: Set partid! */ 0 ) ;
wallet_local_htlc_out_delete ( ld - > wallet , channel , payment_hash , /* FIXME: Set partid! */ 0 ) ;
}
failcode = send_onion ( cmd - > ld , & packet , first_hop , payment_hash , /* FIXME: Set partid! */ 0 , channel ,
& hout ) ;
payment = tal ( hout , struct wallet_payment ) ;
payment - > id = 0 ;
payment - > payment_hash = * payment_hash ;
payment - > status = PAYMENT_PENDING ;
payment - > msatoshi = AMOUNT_MSAT ( 0 ) ;
payment - > msatoshi_sent = first_hop - > amount ;
payment - > timestamp = time_now ( ) . ts . tv_sec ;
/* These are not available for sendonion payments since the onion is
* opaque and we can ' t extract them . Errors have to be handled
* externally , since we can ' t decrypt them . */
payment - > destination = NULL ;
payment - > payment_preimage = NULL ;
payment - > route_nodes = NULL ;
payment - > route_channels = NULL ;
payment - > bolt11 = NULL ;
payment - > failonion = NULL ;
payment - > path_secrets = tal_steal ( payment , path_secrets ) ;
if ( label ! = NULL )
payment - > label = tal_strdup ( payment , label ) ;
else
payment - > label = NULL ;
/* We write this into db when HTLC is actually sent. */
wallet_payment_setup ( ld - > wallet , payment ) ;
add_sendpay_waiter ( ld , cmd , payment_hash ) ;
return command_still_pending ( cmd ) ;
return send_payment_core ( ld , cmd , payment_hash , /* FIXME: Set partid! */ 0 ,
first_hop , AMOUNT_MSAT ( 0 ) , AMOUNT_MSAT ( 0 ) ,
label , NULL , & packet , NULL , NULL , NULL ,
path_secrets ) ;
}
static const struct json_command sendonion_command = {
" sendonion " ,
" payment " ,
@ -1130,7 +1097,6 @@ static struct command_result *json_sendpay(struct command *cmd,
struct route_hop * route ;
struct amount_msat * msat ;
const char * b11str , * label = NULL ;
struct command_result * res ;
struct secret * payment_secret ;
/* For generating help, give new-style. */
@ -1267,15 +1233,12 @@ static struct command_result *json_sendpay(struct command *cmd,
}
# endif
res = send_payment ( cmd - > ld , cmd , rhash , /* FIXME: Set partid! */ 0 ,
route ,
msat ? * msat : route [ routetok - > size - 1 ] . amount ,
/* FIXME: Set total_msat! */
msat ? * msat : route [ routetok - > size - 1 ] . amount ,
label , b11str , payment_secret ) ;
if ( res )
return res ;
return command_still_pending ( cmd ) ;
return send_payment ( cmd - > ld , cmd , rhash , /* FIXME: Set partid! */ 0 ,
route ,
msat ? * msat : route [ routetok - > size - 1 ] . amount ,
/* FIXME: Set total_msat! */
msat ? * msat : route [ routetok - > size - 1 ] . amount ,
label , b11str , payment_secret ) ;
}
static const struct json_command sendpay_command = {