@@ -350,19 +350,15 @@ static void send_reply_channel_range(struct peer *peer,
350350 const struct short_channel_id * scids ,
351351 const struct channel_update_timestamps * tstamps ,
352352 const struct channel_update_checksums * csums ,
353- size_t num_scids )
353+ size_t num_scids ,
354+ bool final )
354355{
355356 /* BOLT #7:
356357 *
357358 * - MUST respond with one or more `reply_channel_range`:
358359 * - MUST set with `chain_hash` equal to that of `query_channel_range`,
359360 * - MUST limit `number_of_blocks` to the maximum number of blocks
360361 * whose results could fit in `encoded_short_ids`
361- * - if does not maintain up-to-date channel information for
362- * `chain_hash`:
363- * - MUST set `full_information` to 0.
364- * - otherwise:
365- * - SHOULD set `full_information` to 1.
366362 */
367363 u8 * encoded_scids = encoding_start (tmpctx );
368364 u8 * encoded_timestamps = encoding_start (tmpctx );
@@ -392,11 +388,16 @@ static void send_reply_channel_range(struct peer *peer,
392388 struct channel_update_checksums ,
393389 csums , num_scids , 0 );
394390
391+ /* BOLT #7:
392+ *
393+ * - MUST set `sync_complete` to `false` if this is not the final
394+ * `reply_channel_range`.
395+ */
395396 u8 * msg = towire_reply_channel_range (NULL ,
396397 & chainparams -> genesis_blockhash ,
397398 first_blocknum ,
398399 number_of_blocks ,
399- 1 , encoded_scids , tlvs );
400+ final , encoded_scids , tlvs );
400401 queue_peer_msg (peer , take (msg ));
401402}
402403
@@ -453,7 +454,7 @@ static size_t max_entries(enum query_option_flags query_option_flags)
453454 * * [`chain_hash`:`chain_hash`]
454455 * * [`u32`:`first_blocknum`]
455456 * * [`u32`:`number_of_blocks`]
456- * * [`byte`:`full_information `]
457+ * * [`byte`:`sync_complete `]
457458 * * [`u16`:`len`]
458459 * * [`len*byte`:`encoded_short_ids`]
459460 */
@@ -632,7 +633,8 @@ static void queue_channel_ranges(struct peer *peer,
632633 ? tstamps + off : NULL ,
633634 query_option_flags & QUERY_ADD_CHECKSUMS
634635 ? csums + off : NULL ,
635- n );
636+ n ,
637+ this_num_blocks == number_of_blocks );
636638 first_blocknum += this_num_blocks ;
637639 number_of_blocks -= this_num_blocks ;
638640 off += n ;
@@ -733,21 +735,20 @@ static u8 *append_range_reply(struct peer *peer,
733735const u8 * handle_reply_channel_range (struct peer * peer , const u8 * msg )
734736{
735737 struct bitcoin_blkid chain ;
736- u8 complete ;
738+ u8 sync_complete ;
737739 u32 first_blocknum , number_of_blocks , start , end ;
738740 u8 * encoded ;
739741 struct short_channel_id * scids ;
740742 const struct range_query_reply * replies ;
741743 const u8 * err ;
742744 void (* cb )(struct peer * peer ,
743745 u32 first_blocknum , u32 number_of_blocks ,
744- const struct range_query_reply * replies ,
745- bool complete );
746+ const struct range_query_reply * replies );
746747 struct tlv_reply_channel_range_tlvs * tlvs
747748 = tlv_reply_channel_range_tlvs_new (tmpctx );
748749
749750 if (!fromwire_reply_channel_range (tmpctx , msg , & chain , & first_blocknum ,
750- & number_of_blocks , & complete ,
751+ & number_of_blocks , & sync_complete ,
751752 & encoded , tlvs )) {
752753 return towire_warningfmt (peer , NULL ,
753754 "Bad reply_channel_range w/tlvs %s" ,
@@ -788,7 +789,6 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
788789 tal_count (scids ));
789790
790791 /* BOLT #7:
791- *
792792 * The receiver of `query_channel_range`:
793793 *...
794794 * - the first `reply_channel_range` message:
@@ -797,12 +797,14 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
797797 * - MUST set `first_blocknum` plus `number_of_blocks` greater than
798798 * `first_blocknum` in `query_channel_range`.
799799 * - successive `reply_channel_range` message:
800- * - MUST set `first_blocknum` to the previous `first_blocknum`
801- * plus `number_of_blocks`.
800+ * - MUST have `first_blocknum` equal or greater than the previous
801+ * `first_blocknum`.
802+ * - MUST set `sync_complete` to `false` if this is not the final `reply_channel_range`.
802803 * - the final `reply_channel_range` message:
803804 * - MUST have `first_blocknum` plus `number_of_blocks` equal or
804805 * greater than the `query_channel_range` `first_blocknum` plus
805806 * `number_of_blocks`.
807+ * - MUST set `sync_complete` to `true`.
806808 */
807809 /* ie. They can be outside range we asked, but they must overlap! */
808810 if (first_blocknum + number_of_blocks <= peer -> range_first_blocknum
@@ -823,28 +825,58 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
823825 if (end > peer -> range_end_blocknum )
824826 end = peer -> range_end_blocknum ;
825827
826- /* LND mis-implemented the spec. If they have multiple replies, set
827- * each one to the *whole* range, with complete=0 except the last.
828- * Try to accomodate that (pretend we make no progress until the
829- * end)! */
828+ /* Have a seat. It's time for a history lesson in Rusty Screws Up.
829+ *
830+ * Part 1
831+ * ------
832+ * The original spec had a field called "complete" which meant
833+ * "I believe I have complete knowledge of gossip", with the idea
834+ * that lite nodes in future would not set this.
835+ *
836+ * But I chose a terrible name, and LND mis-implemented the spec,
837+ * thinking this was an "end of replies". If they have multiple
838+ * replies, set each one to the *whole* range, with complete=0 except
839+ * the last.
840+ *
841+ * Here we try to accomodate that (pretend we make no progress
842+ * until the end)! */
830843 if (first_blocknum == peer -> range_first_blocknum
831844 && first_blocknum + number_of_blocks == peer -> range_end_blocknum
832- && !complete
845+ && !sync_complete
833846 && tal_bytelen (msg ) == 64046 ) {
834847 status_unusual ("Old LND reply_channel_range detected: result will be truncated!" );
835848 }
836849
837- /* They're supposed to send them in order, but LND actually
838- * can overlap. */
839- if (first_blocknum != peer -> range_prev_end_blocknum + 1
840- && first_blocknum != peer -> range_prev_end_blocknum ) {
841- return towire_warningfmt (peer , NULL ,
842- "reply_channel_range %u+%u previous end was block %u" ,
843- first_blocknum , number_of_blocks ,
844- peer -> range_prev_end_blocknum );
845- }
846- peer -> range_prev_end_blocknum = end ;
847-
850+ /*
851+ * Part 2
852+ * ------
853+ * You were supposed to use the first_blocknum + number_of_blocks
854+ * to tell when gossip was finished, with the rule being no replies
855+ * could overlap, so you could say "I asked for blocks 100-199" and if
856+ * you got a reply saying it covered blocks 50-150, you knew that you
857+ * still had 49 blocks to receive.
858+ *
859+ * The field was renamed to `full_information`, and since everyone
860+ * did it this way anyway, we insisted the replies be in
861+ * non-overlapping ascending order.
862+ *
863+ * But LND didn't do this, and can actually overlap, since they just
864+ * chop them up when they reach length, not by block boundary, so
865+ * we had to allow that.
866+ *
867+ * Reading this implementation gave me envy: it was much simpler than
868+ * backing out to a block boundary!
869+ *
870+ * And what if a single block had so many channel openings that you
871+ * couldn't fit it in a single reply? (This was originally
872+ * inconceivable, but with the addition of timestamps and checksums,
873+ * is now possible).
874+ *
875+ * So we decided to make the lie into a truth. `full_information`
876+ * was re-renamed to `sync_complete`, and once everyone has upgraded
877+ * we can use that, rather than tallying the block numbers, to
878+ * tell if replies are finished.
879+ */
848880 err = append_range_reply (peer , scids , tlvs -> timestamps_tlv );
849881 if (err )
850882 return err ;
@@ -853,9 +885,20 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
853885 * since scids are only 8 bytes, use a discount over normal gossip. */
854886 peer_supplied_good_gossip (peer , tal_count (scids ) / 20 );
855887
856- /* Still more to go? */
857- if (peer -> range_prev_end_blocknum < peer -> range_end_blocknum )
888+ /* Old code used to set this to 1 all the time; not setting it implies
889+ * we're talking to an upgraded node. */
890+ if (!sync_complete ) {
891+ /* We no longer need old heuristic counter. */
892+ peer -> range_blocks_outstanding = 0 ;
858893 return NULL ;
894+ }
895+
896+ /* FIXME: This "how many blocks do we have answers for?" heuristic
897+ * can go away once everyone uses sync_complete properly. */
898+ if (end - start < peer -> range_blocks_outstanding ) {
899+ peer -> range_blocks_outstanding -= end - start ;
900+ return NULL ;
901+ }
859902
860903 /* Clear these immediately in case cb want to queue more */
861904 replies = tal_steal (tmpctx , peer -> range_replies );
@@ -864,7 +907,7 @@ const u8 *handle_reply_channel_range(struct peer *peer, const u8 *msg)
864907 peer -> range_replies = NULL ;
865908 peer -> query_channel_range_cb = NULL ;
866909
867- cb (peer , first_blocknum , number_of_blocks , replies , complete );
910+ cb (peer , first_blocknum , number_of_blocks , replies );
868911 return NULL ;
869912}
870913
@@ -1087,8 +1130,7 @@ bool query_channel_range(struct daemon *daemon,
10871130 enum query_option_flags qflags ,
10881131 void (* cb )(struct peer * peer ,
10891132 u32 first_blocknum , u32 number_of_blocks ,
1090- const struct range_query_reply * replies ,
1091- bool complete ))
1133+ const struct range_query_reply * replies ))
10921134{
10931135 u8 * msg ;
10941136 struct tlv_query_channel_range_tlvs * tlvs ;
@@ -1114,7 +1156,7 @@ bool query_channel_range(struct daemon *daemon,
11141156 queue_peer_msg (peer , take (msg ));
11151157 peer -> range_first_blocknum = first_blocknum ;
11161158 peer -> range_end_blocknum = first_blocknum + number_of_blocks ;
1117- peer -> range_prev_end_blocknum = first_blocknum - 1 ;
1159+ peer -> range_blocks_outstanding = number_of_blocks ;
11181160 peer -> range_replies = tal_arr (peer , struct range_query_reply , 0 );
11191161 peer -> query_channel_range_cb = cb ;
11201162
0 commit comments