@@ -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 ;
@@ -559,6 +569,19 @@ static void add_mpp(struct info *info,
559569 tal_free (mp );
560570}
561571
572+ /* Mutual recursion via timer */
573+ struct delayed_forward {
574+ struct info * info ;
575+ struct fake_htlc * htlc ;
576+ struct amount_msat amount ;
577+ u32 cltv_expiry ;
578+ const u8 * onion_routing_packet ;
579+ const struct pubkey * path_key ;
580+ struct node_id expected ;
581+ };
582+
583+ static void delayed_forward (struct delayed_forward * dfwd );
584+
562585static void forward_htlc (struct info * info ,
563586 struct fake_htlc * htlc ,
564587 struct amount_msat amount ,
@@ -576,6 +599,9 @@ static void forward_htlc(struct info *info,
576599 struct short_channel_id_dir scidd ;
577600 struct amount_msat amt_expected , htlc_min , htlc_max ;
578601 struct pubkey * next_path_key ;
602+ struct oneshot * timer ;
603+ struct delayed_forward * dfwd ;
604+ unsigned int msec_delay ;
579605
580606 /* Decode, and figure out who I am */
581607 payload = decode_onion (tmpctx ,
@@ -685,14 +711,38 @@ static void forward_htlc(struct info *info,
685711 } else
686712 next_path_key = NULL ;
687713
688- /* Limited recursion for the "next node" */
689- forward_htlc (info ,
690- htlc ,
691- payload -> amt_to_forward ,
692- payload -> outgoing_cltv ,
693- next_onion_packet ,
694- next_path_key ,
695- & next );
714+ dfwd = tal (NULL , struct delayed_forward );
715+ dfwd -> info = info ;
716+ dfwd -> htlc = htlc ;
717+ dfwd -> amount = payload -> amt_to_forward ;
718+ dfwd -> cltv_expiry = payload -> outgoing_cltv ;
719+ dfwd -> onion_routing_packet = tal_steal (dfwd , next_onion_packet );
720+ dfwd -> path_key = tal_steal (dfwd , next_path_key );
721+ dfwd -> expected = next ;
722+
723+ /* Delay 0.1 - 1 seconds, but skewed lower */
724+ msec_delay = channel_range (info , & scidd , 0 , 900 );
725+ msec_delay = 100 + channel_range (info , & scidd , 0 , msec_delay );
726+
727+ status_debug ("Delaying %u msec for %s" ,
728+ msec_delay , fmt_short_channel_id_dir (tmpctx , & scidd ));
729+ timer = new_reltimer (& info -> timers ,
730+ info ,
731+ time_from_msec (msec_delay ),
732+ delayed_forward , dfwd );
733+ /* Free dfwd after timer expires */
734+ tal_steal (timer , dfwd );
735+ }
736+
737+ static void delayed_forward (struct delayed_forward * dfwd )
738+ {
739+ forward_htlc (dfwd -> info ,
740+ dfwd -> htlc ,
741+ dfwd -> amount ,
742+ dfwd -> cltv_expiry ,
743+ dfwd -> onion_routing_packet ,
744+ dfwd -> path_key ,
745+ & dfwd -> expected );
696746}
697747
698748static void handle_offer_htlc (struct info * info , const u8 * inmsg )
@@ -1122,8 +1172,12 @@ int main(int argc, char *argv[])
11221172 info -> commit_num = 1 ;
11231173 info -> fakesig .sighash_type = SIGHASH_ALL ;
11241174 memset (& info -> fakesig .s , 0 , sizeof (info -> fakesig .s ));
1175+ memset (& info -> seed , 0 , sizeof (info -> seed ));
1176+
1177+ if (getenv ("CHANNELD_FAKENET_SEED" ))
1178+ info -> seed .u .u64 [0 ] = atol (getenv ("CHANNELD_FAKENET_SEED" ));
11251179
1126- status_debug ("Waiting for init..." );
1180+ status_debug ("channeld_fakenet seed is %" PRIu64 , info -> seed . u . u64 [ 0 ] );
11271181
11281182 /* This loop never exits. io_loop() only returns if a timer has
11291183 * expired, or io_break() is called, or all fds are closed. We don't
0 commit comments