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 LatestBeaconRound() uint64
} }
func ValidateTaskBeacons(beaconNetworks BeaconNetworks, t *types.DioneTask, prevEpoch types.DrandRound, prevEntry types.BeaconEntry) error { // ValidateTaskBeacons is a function that verifies dione task randomness
parentBeacon := beaconNetworks.BeaconNetworkForRound(prevEpoch) func ValidateTaskBeacons(beaconNetworks BeaconNetworks, t *types.DioneTask, prevEntry types.BeaconEntry) error {
parentBeacon := beaconNetworks.BeaconNetworkForRound(t.DrandRound - 1)
currBeacon := beaconNetworks.BeaconNetworkForRound(t.DrandRound) currBeacon := beaconNetworks.BeaconNetworkForRound(t.DrandRound)
if parentBeacon != currBeacon { if parentBeacon != currBeacon {
if len(t.BeaconEntries) != 2 { if len(t.BeaconEntries) != 2 {
@ -89,59 +90,22 @@ func BeaconEntriesForTask(ctx context.Context, beaconNetworks BeaconNetworks) ([
beacon := beaconNetworks.BeaconNetworkForRound(0) beacon := beaconNetworks.BeaconNetworkForRound(0)
round := beacon.LatestBeaconRound() 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() 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) out := make([]types.BeaconEntry, 2)
rch := beacon.Entry(ctx, round-1) prevBeaconEntry := beacon.Entry(ctx, round-1)
res := <-rch res := <-prevBeaconEntry
if res.Err != nil { if res.Err != nil {
return nil, fmt.Errorf("getting entry %d returned error: %w", round-1, res.Err) return nil, fmt.Errorf("getting entry %d returned error: %w", round-1, res.Err)
} }
out[0] = res.Entry out[0] = res.Entry
rch = beacon.Entry(ctx, round) curBeaconEntry := beacon.Entry(ctx, round)
res = <-rch res = <-curBeaconEntry
if res.Err != nil { if res.Err != nil {
return nil, fmt.Errorf("getting entry %d returned error: %w", round, res.Err) return nil, fmt.Errorf("getting entry %d returned error: %w", round, res.Err)
} }
out[1] = res.Entry out[1] = res.Entry
logrus.Debugf("fetching beacon entries: took %v, count of entries: %v", lib.Clock.Since(start), len(out)) logrus.Debugf("fetching beacon entries: took %v, count of entries: %v", lib.Clock.Since(start), len(out))
//reverse(out)
return out, nil 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" "context"
"fmt" "fmt"
"sync" "sync"
"time"
"github.com/Secured-Finance/dione/beacon" "github.com/Secured-Finance/dione/beacon"
"github.com/drand/drand/chain" "github.com/drand/drand/chain"
@ -45,16 +44,13 @@ type DrandResponse struct {
type DrandBeacon struct { type DrandBeacon struct {
DrandClient client.Client DrandClient client.Client
PublicKey kyber.Point PublicKey kyber.Point
Interval time.Duration drandResultChannel <-chan client.Result
chainGenesisTime uint64
chainRoundTime uint64
drandGenesisTime uint64
cacheLock sync.Mutex cacheLock sync.Mutex
localCache map[uint64]types.BeaconEntry 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() cfg := config.NewDrandConfig()
drandChain, err := chain.InfoFromJSON(bytes.NewReader([]byte(cfg.ChainInfo))) 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.PublicKey = drandChain.PublicKey
db.Interval = drandChain.Period
db.drandGenesisTime = uint64(drandChain.GenesisTime) db.drandResultChannel = db.DrandClient.Watch(context.TODO())
db.chainRoundTime = interval
db.chainGenesisTime = genesisTs go db.loop(context.TODO())
return db, nil 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 { func (db *DrandBeacon) Entry(ctx context.Context, round uint64) <-chan beacon.BeaconResult {
out := make(chan beacon.BeaconResult, 1) out := make(chan beacon.BeaconResult, 1)
if round != 0 { if round != 0 {
@ -160,15 +171,11 @@ func (db *DrandBeacon) VerifyEntry(curr, prev types.BeaconEntry) error {
return nil return nil
} }
b := &chain.Beacon{ b := &chain.Beacon{
PreviousSig: prev.Data, PreviousSig: prev.Metadata["signature"].([]byte),
Round: curr.Round, Round: curr.Round,
Signature: curr.Data, Signature: curr.Metadata["signature"].([]byte),
} }
err := chain.VerifyBeacon(db.PublicKey, b) return chain.VerifyBeacon(db.PublicKey, b)
if err == nil {
db.cacheValue(curr)
}
return err
} }
func (db *DrandBeacon) LatestBeaconRound() uint64 { 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" "fmt"
"time" "time"
drand2 "github.com/Secured-Finance/dione/beacon/drand"
"github.com/libp2p/go-libp2p-core/protocol" "github.com/libp2p/go-libp2p-core/protocol"
gorpc "github.com/libp2p/go-libp2p-gorpc" gorpc "github.com/libp2p/go-libp2p-gorpc"
@ -17,7 +19,6 @@ import (
"github.com/Secured-Finance/dione/cache" "github.com/Secured-Finance/dione/cache"
"github.com/Secured-Finance/dione/config" "github.com/Secured-Finance/dione/config"
"github.com/Secured-Finance/dione/consensus" "github.com/Secured-Finance/dione/consensus"
"github.com/Secured-Finance/dione/drand"
"github.com/Secured-Finance/dione/ethclient" "github.com/Secured-Finance/dione/ethclient"
"github.com/Secured-Finance/dione/pubsub" "github.com/Secured-Finance/dione/pubsub"
"github.com/Secured-Finance/dione/types" "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) { func provideBeacon(ps *pubsub2.PubSub) (beacon.BeaconNetworks, error) {
networks := beacon.BeaconNetworks{} networks := beacon.BeaconNetworks{}
bc, err := drand.NewDrandBeacon(config.ChainGenesis, config.TaskEpochInterval, ps) bc, err := drand2.NewDrandBeacon(ps)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to setup drand beacon: %w", err) return nil, fmt.Errorf("failed to setup drand beacon: %w", err)
} }

View File

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

View File

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