Skip to content

Commit

Permalink
fix(drand): add null HistoricalBeaconClient for old beacons
Browse files Browse the repository at this point in the history
  • Loading branch information
rvagg committed Jan 21, 2025
1 parent b83bf69 commit cf963a5
Showing 1 changed file with 43 additions and 3 deletions.
46 changes: 43 additions & 3 deletions chain/beacon/drand/drand.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,6 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
}
hc.(DrandHTTPClient).SetUserAgent("drand-client-lotus/" + build.NodeBuildVersion)
clients = append(clients, hc)

}

opts := []dclient.Option{
Expand All @@ -113,6 +112,19 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub, config dtypes
opts = append(opts, gclient.WithPubsub(ps))
} else {
log.Info("drand beacon without pubsub")
if len(clients) == 0 {
// This hack is necessary to convince a drand beacon to start without any clients. For
// historical becaons we need them to be able to verify old entries but we don't need to fetch
// new ones. With pubsub enabled, it acts as a client so drand is happy, but if we don't have
// pubsub then drand will complain about old beacons withotu clients. So we make one that
// it'll think is a valid client and that it won't speed test (hence the need to mark it as
// as "watcher").
historicalClient := &historicalBeaconClient{}
clients = append(clients, historicalClient)
opts = append(opts, dclient.WithWatcher(func(chainInfo *dchain.Info, cache dclient.Cache) (dclient.Watcher, error) {
return historicalClient, nil
}))
}
}

client, err := dclient.Wrap(clients, opts...)
Expand Down Expand Up @@ -239,13 +251,41 @@ var _ beacon.RandomBeacon = (*DrandBeacon)(nil)

func BeaconScheduleFromDrandSchedule(dcs dtypes.DrandSchedule, genesisTime uint64, ps *pubsub.PubSub) (beacon.Schedule, error) {
shd := beacon.Schedule{}
for _, dc := range dcs {
for i, dc := range dcs {
bc, err := NewDrandBeacon(genesisTime, buildconstants.BlockDelaySecs, ps, dc.Config)
if err != nil {
return nil, xerrors.Errorf("creating drand beacon: %w", err)
return nil, xerrors.Errorf("%d creating drand beacon: %w", i, err)
}
shd = append(shd, beacon.BeaconPoint{Start: dc.Start, Beacon: bc})
}

return shd, nil
}

var _ dclient.Client = historicalBeaconClient{}

// historicalBeaconClient is a drand client that doesn't actually do anything. It's used when
// we don't have a drand network to connect to but still need to provide a beacon client.
// We don't expect calls through to the client to be made since we should only be verifying old
// randomness, not fetching it.
type historicalBeaconClient struct{}

func (h historicalBeaconClient) Get(ctx context.Context, round uint64) (dclient.Result, error) {
return nil, xerrors.Errorf("no historical randomness available")
}

func (h historicalBeaconClient) Watch(ctx context.Context) <-chan dclient.Result {
return nil
}

func (h historicalBeaconClient) Info(ctx context.Context) (*dchain.Info, error) {
return nil, xerrors.Errorf("no historical randomness available")
}

func (h historicalBeaconClient) RoundAt(time.Time) uint64 {
return 0
}

func (h historicalBeaconClient) Close() error {
return nil
}

0 comments on commit cf963a5

Please sign in to comment.