@@ -763,6 +763,131 @@ static struct command_result *send_routes_cb(struct payment *payment)
763763
764764REGISTER_PAYMENT_MODIFIER (send_routes , send_routes_cb );
765765
766+ /*****************************************************************************
767+ * reserve_routes
768+ *
769+ * Reserves liquidity in the uncertainty network corresponding to the routes
770+ * that we send by calling askrene-reserve.
771+ */
772+
773+ static struct command_result *
774+ askrene_disable_channel_done (struct command * cmd , const char * buf UNUSED ,
775+ const jsmntok_t * result UNUSED ,
776+ struct payment * payment );
777+
778+ static struct command_result *
779+ askrene_disable_channel_fail (struct command * cmd , const char * buf ,
780+ const jsmntok_t * result , struct payment * payment );
781+
782+ static struct command_result *
783+ askrene_reserve_done (struct command * cmd , const char * buf UNUSED ,
784+ const jsmntok_t * result UNUSED , struct payment * payment )
785+ {
786+ assert (payment -> pending_rpcs > 0 );
787+ payment -> pending_rpcs -- ;
788+ return payment_continue (payment );
789+ }
790+
791+ static struct command_result *
792+ askrene_reserve_fail (struct command * cmd , const char * buf ,
793+ const jsmntok_t * result , struct payment * payment )
794+ {
795+ plugin_log (cmd -> plugin , LOG_UNUSUAL ,
796+ "failed to reserve liquidity with askrene-reserve: %.*s" ,
797+ json_tok_full_len (result ), json_tok_full (buf , result ));
798+ return askrene_reserve_done (cmd , buf , result , payment );
799+ }
800+
801+ static struct command_result * reserve_routes_cb (struct payment * payment )
802+ {
803+ assert (payment );
804+ struct routetracker * routetracker = payment -> routetracker ;
805+ assert (routetracker );
806+ if (!routetracker -> computed_routes ||
807+ tal_count (routetracker -> computed_routes ) == 0 ) {
808+ plugin_log (pay_plugin -> plugin , LOG_UNUSUAL ,
809+ "%s: there are no new routes, skipping." , __func__ );
810+ return payment_continue (payment );
811+ }
812+ struct command * cmd = payment_command (payment );
813+ assert (cmd );
814+ for (size_t i = 0 ; i < tal_count (routetracker -> computed_routes ); i ++ ) {
815+ struct route * route = routetracker -> computed_routes [i ];
816+ assert (route -> hops );
817+ assert (tal_count (route -> hops ));
818+
819+ // FIXME: assuming jsonrpc_errcode == 0 means no error
820+ if (route -> final_error ) {
821+
822+ /* Disable the first channel in the route */
823+ const struct short_channel_id_dir scidd = {
824+ .scid = route -> hops [0 ].scid ,
825+ .dir = route -> hops [0 ].direction };
826+
827+ plugin_log (cmd -> plugin , LOG_DBG ,
828+ "route(partid=%" PRIu64
829+ ") failed at sendpay with error %s, "
830+ "disabling the first "
831+ "channel %s" ,
832+ route -> key .partid , route -> final_msg ,
833+ fmt_short_channel_id_dir (tmpctx , & scidd ));
834+
835+ /* FIXME: there is no askrene-disable-channel,
836+ * we will fake its disabling by setting its
837+ * liquidity to 0 */
838+ struct out_req * req = jsonrpc_request_start (
839+ cmd -> plugin , cmd , "askrene-inform-channel" ,
840+ askrene_disable_channel_done ,
841+ askrene_disable_channel_fail , payment );
842+
843+ /* This constraint only applies to this payment */
844+ json_add_string (req -> js , "layer" ,
845+ payment -> private_layer );
846+ json_add_short_channel_id (req -> js , "short_channel_id" ,
847+ scidd .scid );
848+ json_add_num (req -> js , "direction" , scidd .dir );
849+ json_add_amount_msat (req -> js , "maximum_msat" ,
850+ AMOUNT_MSAT (0 ));
851+ send_outreq (cmd -> plugin , req );
852+
853+ payment -> pending_rpcs ++ ;
854+ tal_free (route );
855+ } else {
856+ // FIXME: don't forget to unreserve, maybe add a
857+ // destructor to the route that calls unreserve
858+ struct out_req * req = jsonrpc_request_start (
859+ cmd -> plugin , cmd , "askrene-reserve" ,
860+ askrene_reserve_done , askrene_reserve_fail ,
861+ payment );
862+
863+ json_array_start (req -> js , "path" );
864+ for (size_t j = 0 ; j < tal_count (route -> hops ); j ++ ) {
865+ json_object_start (req -> js , NULL );
866+ json_add_short_channel_id (req -> js ,
867+ "short_channel_id" ,
868+ route -> hops [j ].scid );
869+ json_add_num (req -> js , "direction" ,
870+ route -> hops [j ].direction );
871+ json_add_amount_msat (req -> js , "amount_msat" ,
872+ route -> hops [j ].amount );
873+ json_object_end (req -> js );
874+ }
875+ json_array_end (req -> js );
876+
877+ send_outreq (cmd -> plugin , req );
878+
879+ payment -> pending_rpcs ++ ;
880+ // TODO: check this
881+ route_pending_register (payment -> routetracker ,
882+ take (route ));
883+ }
884+ }
885+ tal_resize (& routetracker -> computed_routes , 0 );
886+ return payment_continue (payment );
887+ }
888+
889+ REGISTER_PAYMENT_MODIFIER (reserve_routes , reserve_routes_cb );
890+
766891/*****************************************************************************
767892 * sleep
768893 *
@@ -1129,23 +1254,24 @@ REGISTER_PAYMENT_MODIFIER(knowledgerelax, knowledgerelax_cb);
11291254 */
11301255
11311256static struct command_result *
1132- askrene_filter_done (struct command * cmd , const char * buf UNUSED ,
1133- const jsmntok_t * result UNUSED , struct payment * payment )
1257+ askrene_disable_channel_done (struct command * cmd , const char * buf UNUSED ,
1258+ const jsmntok_t * result UNUSED ,
1259+ struct payment * payment )
11341260{
11351261 assert (payment -> pending_rpcs > 0 );
11361262 payment -> pending_rpcs -- ;
11371263 return payment_continue (payment );
11381264}
11391265
1140- static struct command_result * askrene_filter_fail (struct command * cmd ,
1141- const char * buf ,
1142- const jsmntok_t * result ,
1143- struct payment * payment )
1266+ static struct command_result *
1267+ askrene_disable_channel_fail (struct command * cmd , const char * buf ,
1268+ const jsmntok_t * result , struct payment * payment )
11441269{
1145- plugin_log (cmd -> plugin , LOG_UNUSUAL ,
1146- "failed to filter channel with askrene-inform-channel: %.*s" ,
1147- json_tok_full_len (result ), json_tok_full (buf , result ));
1148- return askrene_filter_done (cmd , buf , result , payment );
1270+ plugin_log (
1271+ cmd -> plugin , LOG_UNUSUAL ,
1272+ "failed to disable channel with askrene-inform-channel: %.*s" ,
1273+ json_tok_full_len (result ), json_tok_full (buf , result ));
1274+ return askrene_disable_channel_done (cmd , buf , result , payment );
11491275}
11501276
11511277static struct command_result * channelfilter_cb (struct payment * payment )
@@ -1190,8 +1316,8 @@ static struct command_result *channelfilter_cb(struct payment *payment)
11901316 * liquidity to 0 */
11911317 struct out_req * req = jsonrpc_request_start (
11921318 cmd -> plugin , cmd , "askrene-inform-channel" ,
1193- askrene_filter_done , askrene_filter_fail ,
1194- payment );
1319+ askrene_disable_channel_done ,
1320+ askrene_disable_channel_fail , payment );
11951321
11961322 /* This constraint only applies to this payment
11971323 */
@@ -1282,12 +1408,13 @@ void *payment_virtual_program[] = {
12821408 /*14*/ OP_CALL , & checktimeout_pay_mod ,
12831409 /*16*/ OP_CALL , & compute_routes_pay_mod ,
12841410 /*18*/ OP_CALL , & send_routes_pay_mod ,
1411+ /*20*/ OP_CALL , & reserve_routes_pay_mod ,
12851412 /*do*/
1286- /*20 */ OP_CALL , & sleep_pay_mod ,
1287- /*22 */ OP_CALL , & collect_results_pay_mod ,
1413+ /*22 */ OP_CALL , & sleep_pay_mod ,
1414+ /*24 */ OP_CALL , & collect_results_pay_mod ,
12881415 /*while*/
1289- /*24 */ OP_IF , & nothaveresults_pay_cond , (void * )20 ,
1416+ /*26 */ OP_IF , & nothaveresults_pay_cond , (void * )22 ,
12901417 /* while */
1291- /*27 */ OP_IF , & retry_pay_cond , (void * )12 ,
1292- /*30 */ OP_CALL , & end_pay_mod , /* safety net, default failure if reached */
1418+ /*29 */ OP_IF , & retry_pay_cond , (void * )12 ,
1419+ /*32 */ OP_CALL , & end_pay_mod , /* safety net, default failure if reached */
12931420 /*32*/ NULL };
0 commit comments