@@ -56,8 +56,10 @@ struct info {
5656 size_t commit_num ;
5757 /* MPP parts we've gathered */
5858 struct multi_payment * * multi_payments ;
59- /* For MPP timers */
59+ /* For MPP timers, delay timers */
6060 struct timers timers ;
61+ /* Seed for channel feature determination (e.g. delay time) */
62+ struct siphash_seed seed ;
6163
6264 /* Fake stuff we feed into lightningd */
6365 struct fee_states * fee_states ;
@@ -130,6 +132,14 @@ static const char *fmt_nodeidx(const tal_t *ctx, size_t idx)
130132 return tal_fmt (ctx , "gossmap-node-%zu" , idx >> 1 );
131133}
132134
135+ /* Return deterministic value >= min < max for this channel */
136+ static u64 channel_range (const struct info * info ,
137+ const struct short_channel_id_dir * scidd ,
138+ u64 min , u64 max )
139+ {
140+ return min + (siphash24 (& info -> seed , scidd , sizeof (scidd )) % max );
141+ }
142+
133143void ecdh (const struct pubkey * point , struct secret * ss )
134144{
135145 struct privkey pk ;
@@ -563,6 +573,19 @@ static void add_mpp(struct info *info,
563573 tal_free (mp );
564574}
565575
576+ /* Mutual recursion via timer */
577+ struct delayed_forward {
578+ struct info * info ;
579+ struct fake_htlc * htlc ;
580+ struct amount_msat amount ;
581+ u32 cltv_expiry ;
582+ const u8 * onion_routing_packet ;
583+ const struct pubkey * path_key ;
584+ struct node_id expected ;
585+ };
586+
587+ static void delayed_forward (struct delayed_forward * dfwd );
588+
566589static void forward_htlc (struct info * info ,
567590 struct fake_htlc * htlc ,
568591 struct amount_msat amount ,
@@ -580,6 +603,9 @@ static void forward_htlc(struct info *info,
580603 struct short_channel_id_dir scidd ;
581604 struct amount_msat amt_expected , htlc_min , htlc_max ;
582605 struct pubkey * next_path_key ;
606+ struct oneshot * timer ;
607+ struct delayed_forward * dfwd ;
608+ unsigned int msec_delay ;
583609
584610 /* Decode, and figure out who I am */
585611 payload = decode_onion (tmpctx ,
@@ -689,14 +715,38 @@ static void forward_htlc(struct info *info,
689715 } else
690716 next_path_key = NULL ;
691717
692- /* Limited recursion for the "next node" */
693- forward_htlc (info ,
694- htlc ,
695- payload -> amt_to_forward ,
696- payload -> outgoing_cltv ,
697- next_onion_packet ,
698- next_path_key ,
699- & next );
718+ dfwd = tal (NULL , struct delayed_forward );
719+ dfwd -> info = info ;
720+ dfwd -> htlc = htlc ;
721+ dfwd -> amount = payload -> amt_to_forward ;
722+ dfwd -> cltv_expiry = payload -> outgoing_cltv ;
723+ dfwd -> onion_routing_packet = tal_steal (dfwd , next_onion_packet );
724+ dfwd -> path_key = tal_steal (dfwd , next_path_key );
725+ dfwd -> expected = next ;
726+
727+ /* Delay 0.1 - 1 seconds, but skewed lower */
728+ msec_delay = channel_range (info , & scidd , 0 , 900 );
729+ msec_delay = 100 + channel_range (info , & scidd , 0 , msec_delay );
730+
731+ status_debug ("Delaying %u msec for %s" ,
732+ msec_delay , fmt_short_channel_id_dir (tmpctx , & scidd ));
733+ timer = new_reltimer (& info -> timers ,
734+ info ,
735+ time_from_msec (msec_delay ),
736+ delayed_forward , dfwd );
737+ /* Free dfwd after timer expires */
738+ tal_steal (timer , dfwd );
739+ }
740+
741+ static void delayed_forward (struct delayed_forward * dfwd )
742+ {
743+ forward_htlc (dfwd -> info ,
744+ dfwd -> htlc ,
745+ dfwd -> amount ,
746+ dfwd -> cltv_expiry ,
747+ dfwd -> onion_routing_packet ,
748+ dfwd -> path_key ,
749+ & dfwd -> expected );
700750}
701751
702752static void handle_offer_htlc (struct info * info , const u8 * inmsg )
@@ -1126,8 +1176,12 @@ int main(int argc, char *argv[])
11261176 info -> commit_num = 1 ;
11271177 info -> fakesig .sighash_type = SIGHASH_ALL ;
11281178 memset (& info -> fakesig .s , 0 , sizeof (info -> fakesig .s ));
1179+ memset (& info -> seed , 0 , sizeof (info -> seed ));
1180+
1181+ if (getenv ("CHANNELD_FAKENET_SEED" ))
1182+ info -> seed .u .u64 [0 ] = atol (getenv ("CHANNELD_FAKENET_SEED" ));
11291183
1130- status_debug ("Waiting for init..." );
1184+ status_debug ("channeld_fakenet seed is %" PRIu64 , info -> seed . u . u64 [ 0 ] );
11311185
11321186 /* This loop never exits. io_loop() only returns if a timer has
11331187 * expired, or io_break() is called, or all fds are closed. We don't
0 commit comments