@@ -138,13 +138,26 @@ var _ NetworkPeerBootstrapper = (*ChannelGraphBootstrapper)(nil)
138138// backed by an active autopilot.ChannelGraph instance. This type of network
139139// peer bootstrapper will use the authenticated nodes within the known channel
140140// graph to bootstrap connections.
141- func NewGraphBootstrapper (cg autopilot.ChannelGraph ) ( NetworkPeerBootstrapper ,
142- error ) {
141+ func NewGraphBootstrapper (cg autopilot.ChannelGraph ,
142+ deterministicSampling bool ) ( NetworkPeerBootstrapper , error ) {
143143
144- hashAccumulator , err := newRandomHashAccumulator ()
145- if err != nil {
146- return nil , fmt .Errorf ("unable to create hash accumulator: %w" ,
147- err )
144+ var (
145+ hashAccumulator hashAccumulator
146+ err error
147+ )
148+ if deterministicSampling {
149+ // If we're using deterministic sampling, then we'll use a
150+ // no-op hash accumulator that will always return false for
151+ // skipNode.
152+ hashAccumulator = newNoOpHashAccumulator ()
153+ } else {
154+ // Otherwise, we'll use a random hash accumulator to sample
155+ // nodes from the channel graph.
156+ hashAccumulator , err = newRandomHashAccumulator ()
157+ if err != nil {
158+ return nil , fmt .Errorf ("unable to create hash " +
159+ "accumulator: %w" , err )
160+ }
148161 }
149162
150163 return & ChannelGraphBootstrapper {
@@ -602,3 +615,29 @@ func (r *randomHashAccumulator) rotate() {
602615func (r * randomHashAccumulator ) skipNode (pub route.Vertex ) bool {
603616 return bytes .Compare (r .hash [:], pub [1 :]) > 0
604617}
618+
619+ // noOpHashAccumulator is a no-op implementation of the hashAccumulator
620+ // interface. This is used when we want deterministic behavior and don't
621+ // want to sample nodes randomly from the channel graph.
622+ type noOpHashAccumulator struct {}
623+
624+ // newNoOpHashAccumulator returns a new instance of a noOpHashAccumulator.
625+ func newNoOpHashAccumulator () * noOpHashAccumulator {
626+ return & noOpHashAccumulator {}
627+ }
628+
629+ // rotate is a no-op for the noOpHashAccumulator.
630+ //
631+ // NOTE: this is part of the hashAccumulator interface.
632+ func (* noOpHashAccumulator ) rotate () {}
633+
634+ // skipNode always returns false, meaning that no nodes will be skipped.
635+ //
636+ // NOTE: this is part of the hashAccumulator interface.
637+ func (* noOpHashAccumulator ) skipNode (route.Vertex ) bool {
638+ return false
639+ }
640+
641+ // A compile-time assertion to ensure that noOpHashAccumulator meets the
642+ // hashAccumulator interface.
643+ var _ hashAccumulator = (* noOpHashAccumulator )(nil )
0 commit comments