Fix LatestBeaconRound in Drand

This commit is contained in:
ChronosX88 2021-06-05 00:14:24 +03:00
parent 2eae45ca38
commit 34c88a8d01
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A

View File

@ -29,25 +29,14 @@ var log = logrus.WithFields(logrus.Fields{
"subsystem": "drand", "subsystem": "drand",
}) })
// DrandResponse structure representing response from drand network
type DrandResponse struct {
// PreviousSig is the previous signature generated
PreviousSig []byte
// Round is the round number this beacon is tied to
Round uint64
// Signature is the BLS deterministic signature over Round || PreviousRand
Signature []byte
// Randomness for specific round generated by Drand
Randomness []byte
}
type DrandBeacon struct { type DrandBeacon struct {
DrandClient client.Client DrandClient client.Client
PublicKey kyber.Point PublicKey kyber.Point
drandResultChannel <-chan client.Result drandResultChannel <-chan client.Result
cacheLock sync.Mutex cacheLock sync.Mutex
localCache map[uint64]types.BeaconEntry localCache map[uint64]types.BeaconEntry
latestDrandRound uint64
} }
func NewDrandBeacon(ps *pubsub.PubSub) (*DrandBeacon, error) { func NewDrandBeacon(ps *pubsub.PubSub) (*DrandBeacon, error) {
@ -96,12 +85,26 @@ func NewDrandBeacon(ps *pubsub.PubSub) (*DrandBeacon, error) {
db.PublicKey = drandChain.PublicKey db.PublicKey = drandChain.PublicKey
db.drandResultChannel = db.DrandClient.Watch(context.TODO()) db.drandResultChannel = db.DrandClient.Watch(context.TODO())
err = db.getLatestDrandResult()
if err != nil {
return nil, err
}
go db.loop(context.TODO()) go db.loop(context.TODO())
return db, nil return db, nil
} }
func (db *DrandBeacon) getLatestDrandResult() error {
latestDround, err := db.DrandClient.Get(context.TODO(), 0)
if err != nil {
log.Errorf("failed to get latest drand round: %v", err)
return err
}
db.cacheValue(newBeaconResultFromDrandResult(latestDround))
db.updateLatestDrandRound(latestDround.Round())
return nil
}
func (db *DrandBeacon) loop(ctx context.Context) { func (db *DrandBeacon) loop(ctx context.Context) {
for { for {
select { select {
@ -111,7 +114,8 @@ func (db *DrandBeacon) loop(ctx context.Context) {
} }
case res := <-db.drandResultChannel: case res := <-db.drandResultChannel:
{ {
db.cacheValue(types.NewBeaconEntry(res.Round(), res.Randomness(), map[string]interface{}{"signature": res.Signature()})) db.cacheValue(newBeaconResultFromDrandResult(res))
db.updateLatestDrandRound(res.Round())
} }
} }
} }
@ -163,6 +167,12 @@ func (db *DrandBeacon) getCachedValue(round uint64) *types.BeaconEntry {
return &v return &v
} }
func (db *DrandBeacon) updateLatestDrandRound(round uint64) {
db.cacheLock.Lock()
defer db.cacheLock.Unlock()
db.latestDrandRound = round
}
func (db *DrandBeacon) VerifyEntry(curr, prev types.BeaconEntry) error { func (db *DrandBeacon) VerifyEntry(curr, prev types.BeaconEntry) error {
if prev.Round == 0 { if prev.Round == 0 {
return nil return nil
@ -179,11 +189,13 @@ func (db *DrandBeacon) VerifyEntry(curr, prev types.BeaconEntry) error {
} }
func (db *DrandBeacon) LatestBeaconRound() uint64 { func (db *DrandBeacon) LatestBeaconRound() uint64 {
latestDround, err := db.DrandClient.Get(context.TODO(), 0) db.cacheLock.Lock()
if err != nil { defer db.cacheLock.Unlock()
log.Errorf("failed to get latest drand round: %w", err) return db.latestDrandRound
} }
return latestDround.Round()
func newBeaconResultFromDrandResult(res client.Result) types.BeaconEntry {
return types.NewBeaconEntry(res.Round(), res.Randomness(), map[string]interface{}{"signature": res.Signature()})
} }
var _ beacon.BeaconAPI = (*DrandBeacon)(nil) var _ beacon.BeaconAPI = (*DrandBeacon)(nil)