From 2eae45ca384ee84f54f80f730901e85a8264f5b6 Mon Sep 17 00:00:00 2001 From: ChronosX88 Date: Sat, 5 Jun 2021 00:07:04 +0300 Subject: [PATCH] Add watching new DRAND entries and fix drand entry validation --- beacon/beacon.go | 50 +++++--------------------------- {drand => beacon/drand}/drand.go | 49 +++++++++++++++++-------------- drand/drand_test.go | 23 --------------- node/node_dep_providers.go | 5 ++-- types/beacon.go | 12 ++++---- types/task.go | 2 -- 6 files changed, 45 insertions(+), 96 deletions(-) rename {drand => beacon/drand}/drand.go (83%) delete mode 100644 drand/drand_test.go diff --git a/beacon/beacon.go b/beacon/beacon.go index 1589a51..f735319 100644 --- a/beacon/beacon.go +++ b/beacon/beacon.go @@ -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] - } -} diff --git a/drand/drand.go b/beacon/drand/drand.go similarity index 83% rename from drand/drand.go rename to beacon/drand/drand.go index 529f158..c1181ca 100644 --- a/drand/drand.go +++ b/beacon/drand/drand.go @@ -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 { diff --git a/drand/drand_test.go b/drand/drand_test.go deleted file mode 100644 index 1db4fb6..0000000 --- a/drand/drand_test.go +++ /dev/null @@ -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") -} diff --git a/node/node_dep_providers.go b/node/node_dep_providers.go index 6107361..ba4b7be 100644 --- a/node/node_dep_providers.go +++ b/node/node_dep_providers.go @@ -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) } diff --git a/types/beacon.go b/types/beacon.go index 567b1b9..b10bc9c 100644 --- a/types/beacon.go +++ b/types/beacon.go @@ -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, } } diff --git a/types/task.go b/types/task.go index cfd1a82..29338c7 100644 --- a/types/task.go +++ b/types/task.go @@ -59,5 +59,3 @@ func NewDioneTask( } var tasksPerEpoch = NewInt(config.TasksPerEpoch) - -const sha256bits = 256