@@ -100,7 +100,6 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
100
100
}
101
101
hc .(DrandHTTPClient ).SetUserAgent ("drand-client-lotus/" + build .NodeBuildVersion )
102
102
clients = append (clients , hc )
103
-
104
103
}
105
104
106
105
opts := []dclient.Option {
@@ -113,6 +112,18 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
113
112
opts = append (opts , gclient .WithPubsub (ps ))
114
113
} else {
115
114
log .Info ("drand beacon without pubsub" )
115
+ if len (clients ) == 0 {
116
+ // This hack is necessary to convince a drand beacon to start without any clients. For
117
+ // historical becaons we need them to be able to verify old entries but we don't need to fetch
118
+ // new ones. With pubsub enabled, it acts as a client so drand is happy, but if we don't have
119
+ // pubsub then drand will complain about old beacons withotu clients. So we make one that
120
+ // it'll think is a valid client and that it won't speed test (hence the need to mark it as
121
+ // as "watcher").
122
+ historicalClient := & historicalBeaconClient {}
123
+ opts = append (opts , dclient .WithWatcher (func (chainInfo * dchain.Info , cache dclient.Cache ) (dclient.Watcher , error ) {
124
+ return historicalClient , nil
125
+ }))
126
+ }
116
127
}
117
128
118
129
client , err := dclient .Wrap (clients , opts ... )
@@ -239,13 +250,41 @@ var _ beacon.RandomBeacon = (*DrandBeacon)(nil)
239
250
240
251
func BeaconScheduleFromDrandSchedule (dcs dtypes.DrandSchedule , genesisTime uint64 , ps * pubsub.PubSub ) (beacon.Schedule , error ) {
241
252
shd := beacon.Schedule {}
242
- for _ , dc := range dcs {
253
+ for i , dc := range dcs {
243
254
bc , err := NewDrandBeacon (genesisTime , buildconstants .BlockDelaySecs , ps , dc .Config )
244
255
if err != nil {
245
- return nil , xerrors .Errorf ("creating drand beacon: %w" , err )
256
+ return nil , xerrors .Errorf ("%d creating drand beacon: %w" , i , err )
246
257
}
247
258
shd = append (shd , beacon.BeaconPoint {Start : dc .Start , Beacon : bc })
248
259
}
249
260
250
261
return shd , nil
251
262
}
263
+
264
+ var _ dclient.Client = historicalBeaconClient {}
265
+
266
+ // historicalBeaconClient is a drand client that doesn't actually do anything. It's used when
267
+ // we don't have a drand network to connect to but still need to provide a beacon client.
268
+ // We don't expect calls through to the client to be made since we should only be verifying old
269
+ // randomness, not fetching it.
270
+ type historicalBeaconClient struct {}
271
+
272
+ func (h historicalBeaconClient ) Get (ctx context.Context , round uint64 ) (dclient.Result , error ) {
273
+ return nil , xerrors .Errorf ("no historical randomness available" )
274
+ }
275
+
276
+ func (h historicalBeaconClient ) Watch (ctx context.Context ) <- chan dclient.Result {
277
+ return nil
278
+ }
279
+
280
+ func (h historicalBeaconClient ) Info (ctx context.Context ) (* dchain.Info , error ) {
281
+ return nil , xerrors .Errorf ("no historical randomness available" )
282
+ }
283
+
284
+ func (h historicalBeaconClient ) RoundAt (time.Time ) uint64 {
285
+ return 0
286
+ }
287
+
288
+ func (h historicalBeaconClient ) Close () error {
289
+ return nil
290
+ }
0 commit comments