Add watching new DRAND entries and fix drand entry validation

This commit is contained in:
ChronosX88 2021-06-05 00:07:04 +03:00
parent 8445baafdb
commit 2eae45ca38
Signed by: ChronosXYZ
GPG Key ID: 085A69A82C8C511A
6 changed files with 45 additions and 96 deletions

View File

@ -42,8 +42,9 @@ type BeaconAPI interface {
LatestBeaconRound() uint64
}
func ValidateTaskBeacons(beaconNetworks BeaconNetworks, t *types.DioneTask, prevEpoch types.DrandRound, prevEntry types.BeaconEntry) error {
parentBeacon := beaconNetworks.BeaconNetworkForRound(prevEpoch)
// ValidateTaskBeacons is a function that verifies dione task randomness
func ValidateTaskBeacons(beaconNetworks BeaconNetworks, t *types.DioneTask, prevEntry types.BeaconEntry) error {
parentBeacon := beaconNetworks.BeaconNetworkForRound(t.DrandRound - 1)
currBeacon := beaconNetworks.BeaconNetworkForRound(t.DrandRound)
if parentBeacon != currBeacon {
if len(t.BeaconEntries) != 2 {
@ -89,59 +90,22 @@ func BeaconEntriesForTask(ctx context.Context, beaconNetworks BeaconNetworks) ([
beacon := beaconNetworks.BeaconNetworkForRound(0)
round := beacon.LatestBeaconRound()
//prevBeacon := beaconNetworks.BeaconNetworkForRound(prevRound)
//currBeacon := beaconNetworks.BeaconNetworkForRound(round)
//if prevBeacon != currBeacon {
// // Fork logic
// round := currBeacon.LatestBeaconRound()
// out := make([]types.BeaconEntry, 2)
// rch := currBeacon.Entry(ctx, round-1)
// res := <-rch
// if res.Err != nil {
// return nil, fmt.Errorf("getting entry %d returned error: %w", round-1, res.Err)
// }
// out[0] = res.Entry
// rch = currBeacon.Entry(ctx, round)
// res = <-rch
// if res.Err != nil {
// return nil, fmt.Errorf("getting entry %d returned error: %w", round, res.Err)
// }
// out[1] = res.Entry
// return out, nil
//}
start := lib.Clock.Now()
//if round == prev.Round {
// return nil, nil
//}
//
//// TODO: this is a sketchy way to handle the genesis block not having a beacon entry
//if prev.Round == 0 {
// prev.Round = round - 1
//}
out := make([]types.BeaconEntry, 2)
rch := beacon.Entry(ctx, round-1)
res := <-rch
prevBeaconEntry := beacon.Entry(ctx, round-1)
res := <-prevBeaconEntry
if res.Err != nil {
return nil, fmt.Errorf("getting entry %d returned error: %w", round-1, res.Err)
}
out[0] = res.Entry
rch = beacon.Entry(ctx, round)
res = <-rch
curBeaconEntry := beacon.Entry(ctx, round)
res = <-curBeaconEntry
if res.Err != nil {
return nil, fmt.Errorf("getting entry %d returned error: %w", round, res.Err)
}
out[1] = res.Entry
logrus.Debugf("fetching beacon entries: took %v, count of entries: %v", lib.Clock.Since(start), len(out))
//reverse(out)
return out, nil
}
func reverse(arr []types.BeaconEntry) {
for i := 0; i < len(arr)/2; i++ {
arr[i], arr[len(arr)-(1+i)] = arr[len(arr)-(1+i)], arr[i]
}
}

View File

@ -5,7 +5,6 @@ import (
"context"
"fmt"
"sync"
"time"
"github.com/Secured-Finance/dione/beacon"
"github.com/drand/drand/chain"
@ -43,18 +42,15 @@ type DrandResponse struct {
}
type DrandBeacon struct {
DrandClient client.Client
PublicKey kyber.Point
Interval time.Duration
chainGenesisTime uint64
chainRoundTime uint64
DrandClient client.Client
PublicKey kyber.Point
drandResultChannel <-chan client.Result
drandGenesisTime uint64
cacheLock sync.Mutex
localCache map[uint64]types.BeaconEntry
cacheLock sync.Mutex
localCache map[uint64]types.BeaconEntry
}
func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub) (*DrandBeacon, error) {
func NewDrandBeacon(ps *pubsub.PubSub) (*DrandBeacon, error) {
cfg := config.NewDrandConfig()
drandChain, err := chain.InfoFromJSON(bytes.NewReader([]byte(cfg.ChainInfo)))
@ -98,14 +94,29 @@ func NewDrandBeacon(genesisTs, interval uint64, ps *pubsub.PubSub) (*DrandBeacon
}
db.PublicKey = drandChain.PublicKey
db.Interval = drandChain.Period
db.drandGenesisTime = uint64(drandChain.GenesisTime)
db.chainRoundTime = interval
db.chainGenesisTime = genesisTs
db.drandResultChannel = db.DrandClient.Watch(context.TODO())
go db.loop(context.TODO())
return db, nil
}
func (db *DrandBeacon) loop(ctx context.Context) {
for {
select {
case <-ctx.Done():
{
return
}
case res := <-db.drandResultChannel:
{
db.cacheValue(types.NewBeaconEntry(res.Round(), res.Randomness(), map[string]interface{}{"signature": res.Signature()}))
}
}
}
}
func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.BeaconResult {
out := make(chan beacon.BeaconResult, 1)
if round != 0 {
@ -160,15 +171,11 @@ func (db *DrandBeacon) VerifyEntry(curr, prev types.BeaconEntry) error {
return nil
}
b := &chain.Beacon{
PreviousSig: prev.Data,
PreviousSig: prev.Metadata["signature"].([]byte),
Round: curr.Round,
Signature: curr.Data,
Signature: curr.Metadata["signature"].([]byte),
}
err := chain.VerifyBeacon(db.PublicKey, b)
if err == nil {
db.cacheValue(curr)
}
return err
return chain.VerifyBeacon(db.PublicKey, b)
}
func (db *DrandBeacon) LatestBeaconRound() uint64 {

View File

@ -1,23 +0,0 @@
package drand
import (
"context"
"encoding/hex"
"testing"
"github.com/Secured-Finance/dione/config"
drandClient "github.com/drand/drand/client/http"
"github.com/stretchr/testify/assert"
)
func TestPrintGroupInfo(t *testing.T) {
cfg := config.NewDrandConfig()
ctx := context.Background()
drandServer := cfg.Servers[0]
client, err := drandClient.New(drandServer, nil, nil)
assert.NoError(t, err)
drandResult, err := client.Get(ctx, 266966)
assert.NoError(t, err)
stringSha256 := hex.EncodeToString(drandResult.Randomness())
assert.Equal(t, stringSha256, "cb67e13477cad0e54540980a3b621dfd9c5fcd7c92ed42626289a1de6f25c3d1")
}

View File

@ -5,6 +5,8 @@ import (
"fmt"
"time"
drand2 "github.com/Secured-Finance/dione/beacon/drand"
"github.com/libp2p/go-libp2p-core/protocol"
gorpc "github.com/libp2p/go-libp2p-gorpc"
@ -17,7 +19,6 @@ import (
"github.com/Secured-Finance/dione/cache"
"github.com/Secured-Finance/dione/config"
"github.com/Secured-Finance/dione/consensus"
"github.com/Secured-Finance/dione/drand"
"github.com/Secured-Finance/dione/ethclient"
"github.com/Secured-Finance/dione/pubsub"
"github.com/Secured-Finance/dione/types"
@ -61,7 +62,7 @@ func provideMiner(peerID peer.ID, ethAddress common.Address, beacon beacon.Beaco
func provideBeacon(ps *pubsub2.PubSub) (beacon.BeaconNetworks, error) {
networks := beacon.BeaconNetworks{}
bc, err := drand.NewDrandBeacon(config.ChainGenesis, config.TaskEpochInterval, ps)
bc, err := drand2.NewDrandBeacon(ps)
if err != nil {
return nil, fmt.Errorf("failed to setup drand beacon: %w", err)
}

View File

@ -1,15 +1,17 @@
package types
type BeaconEntry struct {
Round uint64
Data []byte
Round uint64
Data []byte
Metadata map[string]interface{}
}
type Randomness []byte
func NewBeaconEntry(round uint64, data []byte) BeaconEntry {
func NewBeaconEntry(round uint64, data []byte, metadata map[string]interface{}) BeaconEntry {
return BeaconEntry{
Round: round,
Data: data,
Round: round,
Data: data,
Metadata: metadata,
}
}

View File

@ -59,5 +59,3 @@ func NewDioneTask(
}
var tasksPerEpoch = NewInt(config.TasksPerEpoch)
const sha256bits = 256