From 7936d873c9d75e448f47c22886b813d2944f33e0 Mon Sep 17 00:00:00 2001
From: capossele <angelocapossele@gmail.com>
Date: Thu, 19 Mar 2020 18:50:50 +0000
Subject: [PATCH] :sparkles: adds state

---
 packages/binary/drng/dispatcher.go            | 15 +++++
 packages/binary/drng/drng.go                  | 39 +++--------
 packages/binary/drng/events.go                | 15 +++++
 packages/binary/drng/state/options.go         | 22 +++++++
 packages/binary/drng/state/state.go           | 64 +++++++++++++++++++
 packages/binary/drng/state/state_test.go      | 42 ++++++++++++
 .../collectiveBeacon/collective_beacon.go     | 40 ++++++++++++
 .../collective_beacon_test.go}                |  8 +--
 .../collectiveBeacon/payload}/common.go       |  2 +-
 .../collectiveBeacon/payload/payload.go}      |  2 +-
 .../collectiveBeacon/payload/payload_test.go} |  2 +-
 11 files changed, 213 insertions(+), 38 deletions(-)
 create mode 100644 packages/binary/drng/dispatcher.go
 create mode 100644 packages/binary/drng/events.go
 create mode 100644 packages/binary/drng/state/options.go
 create mode 100644 packages/binary/drng/state/state.go
 create mode 100644 packages/binary/drng/state/state_test.go
 create mode 100644 packages/binary/drng/subtypes/collectiveBeacon/collective_beacon.go
 rename packages/binary/drng/{drng_test.go => subtypes/collectiveBeacon/collective_beacon_test.go} (93%)
 rename packages/binary/drng/{payload/collectiveBeacon => subtypes/collectiveBeacon/payload}/common.go (82%)
 rename packages/binary/drng/{payload/collectiveBeacon/collective_beacon.go => subtypes/collectiveBeacon/payload/payload.go} (99%)
 rename packages/binary/drng/{payload/collectiveBeacon/collective_beacon_test.go => subtypes/collectiveBeacon/payload/payload_test.go} (98%)

diff --git a/packages/binary/drng/dispatcher.go b/packages/binary/drng/dispatcher.go
new file mode 100644
index 00000000..657382fb
--- /dev/null
+++ b/packages/binary/drng/dispatcher.go
@@ -0,0 +1,15 @@
+package drng
+
+import (
+	"github.com/iotaledger/goshimmer/packages/binary/drng/payload/header"
+	"github.com/iotaledger/goshimmer/packages/binary/tangle/model/transaction"
+)
+
+func Dispatch(subtype header.Type, tx *transaction.Transaction) {
+	switch subtype {
+	case header.CollectiveBeaconType():
+		//do stuff
+	default:
+		//do other stuff
+	}
+}
diff --git a/packages/binary/drng/drng.go b/packages/binary/drng/drng.go
index d65b6fcf..24c17ba2 100644
--- a/packages/binary/drng/drng.go
+++ b/packages/binary/drng/drng.go
@@ -1,40 +1,17 @@
 package drng
 
 import (
-	"crypto/sha512"
-	"errors"
-
-	"github.com/drand/drand/beacon"
-	"github.com/drand/drand/key"
-	"github.com/iotaledger/goshimmer/packages/binary/drng/payload/collectiveBeacon"
+	"github.com/iotaledger/goshimmer/packages/binary/drng/state"
+	"github.com/iotaledger/hive.go/events"
 )
 
-// VerifyCollectiveBeacon checks the current signature against the distributed public key
-func VerifyCollectiveBeacon(data *collectiveBeacon.Payload) error {
-	if data == nil {
-		return errors.New("nil data")
-	}
-
-	dpk := key.KeyGroup.Point()
-	if err := dpk.UnmarshalBinary(data.DistributedPK()); err != nil {
-		return err
-	}
-
-	msg := beacon.Message(data.PrevSignature(), data.Round())
-
-	if err := key.Scheme.VerifyRecovered(dpk, msg, data.Signature()); err != nil {
-		return err
-	}
-
-	return nil
+type Instance struct {
+	State  *state.State
+	Events *events.Event
 }
 
-// GetRandomness returns the randomness from a given signature
-func GetRandomness(signature []byte) ([]byte, error) {
-	hash := sha512.New()
-	if _, err := hash.Write(signature); err != nil {
-		return nil, err
+func New() *Instance {
+	return &Instance{
+		State: state.New(),
 	}
-
-	return hash.Sum(nil), nil
 }
diff --git a/packages/binary/drng/events.go b/packages/binary/drng/events.go
new file mode 100644
index 00000000..f0532f47
--- /dev/null
+++ b/packages/binary/drng/events.go
@@ -0,0 +1,15 @@
+package drng
+
+import (
+	"github.com/iotaledger/hive.go/events"
+)
+
+var Events = struct {
+	NewRandomness *events.Event
+}{
+	NewRandomness: events.NewEvent(transactionCaller),
+}
+
+func transactionCaller(handler interface{}, params ...interface{}) {
+	//handler.(func(*value_transaction.ValueTransaction))(params[0].(*value_transaction.ValueTransaction))
+}
diff --git a/packages/binary/drng/state/options.go b/packages/binary/drng/state/options.go
new file mode 100644
index 00000000..0bdcde9e
--- /dev/null
+++ b/packages/binary/drng/state/options.go
@@ -0,0 +1,22 @@
+package state
+
+type Options struct {
+	Committee  *Committee
+	Randomness *Randomness
+}
+
+type option func(*Options)
+
+// SetCommittee sets the initial committee
+func SetCommittee(c *Committee) option {
+	return func(args *Options) {
+		args.Committee = c
+	}
+}
+
+// SetRandomness sets the initial randomness
+func SetRandomness(r *Randomness) option {
+	return func(args *Options) {
+		args.Randomness = r
+	}
+}
diff --git a/packages/binary/drng/state/state.go b/packages/binary/drng/state/state.go
new file mode 100644
index 00000000..5c66c0ed
--- /dev/null
+++ b/packages/binary/drng/state/state.go
@@ -0,0 +1,64 @@
+package state
+
+import (
+	"sync"
+	"time"
+
+	"github.com/iotaledger/goshimmer/packages/binary/signature/ed25119"
+)
+
+type Randomness struct {
+	Round      uint64
+	Randomness []byte
+	Timestamp  time.Time
+}
+
+type Committee struct {
+	InstanceID    uint32
+	Threshold     uint8
+	Identities    []ed25119.PublicKey
+	DistributedPK []byte
+}
+
+type State struct {
+	randomness *Randomness
+	committe   *Committee
+
+	mutex sync.RWMutex
+}
+
+func New(setters ...option) *State {
+	args := &Options{}
+
+	for _, setter := range setters {
+		setter(args)
+	}
+	return &State{
+		randomness: args.Randomness,
+		committe:   args.Committee,
+	}
+}
+
+func (s *State) SetRandomness(r *Randomness) {
+	s.mutex.Lock()
+	defer s.mutex.Unlock()
+	s.randomness = r
+}
+
+func (s *State) Randomness() Randomness {
+	s.mutex.RLock()
+	defer s.mutex.RUnlock()
+	return *s.randomness
+}
+
+func (s *State) SetCommittee(c *Committee) {
+	s.mutex.Lock()
+	defer s.mutex.Unlock()
+	s.committe = c
+}
+
+func (s *State) Committee() Committee {
+	s.mutex.RLock()
+	defer s.mutex.RUnlock()
+	return *s.committe
+}
diff --git a/packages/binary/drng/state/state_test.go b/packages/binary/drng/state/state_test.go
new file mode 100644
index 00000000..314241ed
--- /dev/null
+++ b/packages/binary/drng/state/state_test.go
@@ -0,0 +1,42 @@
+package state
+
+import (
+	"testing"
+	"time"
+
+	"github.com/iotaledger/goshimmer/packages/binary/signature/ed25119"
+	"github.com/stretchr/testify/require"
+)
+
+func dummyRandomness() *Randomness {
+	return &Randomness{
+		Round:      0,
+		Randomness: []byte{},
+	}
+}
+
+func dummyCommittee() *Committee {
+	return &Committee{
+		InstanceID:    0,
+		Threshold:     0,
+		Identities:    []ed25119.PublicKey{},
+		DistributedPK: []byte{},
+	}
+}
+
+func TestState(t *testing.T) {
+	// constructor
+	stateTest := New(SetCommittee(dummyCommittee()), SetRandomness(dummyRandomness()))
+	require.Equal(t, *dummyRandomness(), stateTest.Randomness())
+	require.Equal(t, *dummyCommittee(), stateTest.Committee())
+
+	// committee setters - getters
+	newCommittee := &Committee{1, 1, []ed25119.PublicKey{}, []byte{11}}
+	stateTest.SetCommittee(newCommittee)
+	require.Equal(t, *newCommittee, stateTest.Committee())
+
+	// randomness setters - getters
+	newRandomness := &Randomness{1, []byte{123}, time.Now()}
+	stateTest.SetRandomness(newRandomness)
+	require.Equal(t, *newRandomness, stateTest.Randomness())
+}
diff --git a/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon.go b/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon.go
new file mode 100644
index 00000000..e9998f78
--- /dev/null
+++ b/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon.go
@@ -0,0 +1,40 @@
+package collectiveBeacon
+
+import (
+	"crypto/sha512"
+	"errors"
+
+	"github.com/drand/drand/beacon"
+	"github.com/drand/drand/key"
+	"github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/payload"
+)
+
+// VerifyCollectiveBeacon checks the current signature against the distributed public key
+func VerifyCollectiveBeacon(data *payload.Payload) error {
+	if data == nil {
+		return errors.New("nil data")
+	}
+
+	dpk := key.KeyGroup.Point()
+	if err := dpk.UnmarshalBinary(data.DistributedPK()); err != nil {
+		return err
+	}
+
+	msg := beacon.Message(data.PrevSignature(), data.Round())
+
+	if err := key.Scheme.VerifyRecovered(dpk, msg, data.Signature()); err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// GetRandomness returns the randomness from a given signature
+func GetRandomness(signature []byte) ([]byte, error) {
+	hash := sha512.New()
+	if _, err := hash.Write(signature); err != nil {
+		return nil, err
+	}
+
+	return hash.Sum(nil), nil
+}
diff --git a/packages/binary/drng/drng_test.go b/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon_test.go
similarity index 93%
rename from packages/binary/drng/drng_test.go
rename to packages/binary/drng/subtypes/collectiveBeacon/collective_beacon_test.go
index c3ffafcc..6eeb237c 100644
--- a/packages/binary/drng/drng_test.go
+++ b/packages/binary/drng/subtypes/collectiveBeacon/collective_beacon_test.go
@@ -1,15 +1,15 @@
-package drng
+package collectiveBeacon
 
 import (
 	"encoding/hex"
 	"testing"
 
-	"github.com/iotaledger/goshimmer/packages/binary/drng/payload/collectiveBeacon"
+	"github.com/iotaledger/goshimmer/packages/binary/drng/subtypes/collectiveBeacon/payload"
 	"github.com/stretchr/testify/require"
 )
 
 var (
-	payloadTest       *collectiveBeacon.Payload
+	payloadTest       *payload.Payload
 	prevSignatureTest []byte
 	signatureTest     []byte
 	dpkTest           []byte
@@ -19,7 +19,7 @@ func init() {
 	prevSignatureTest, _ = hex.DecodeString("ae9ba6d1445bffea8e66cb7d28fe5924e0a8d31b11b62a8710204e56e1ba84bc3694a3033e5793fcee6e75e956e5da3016cd0e22aa46fa419cd06343a7ff9d1e9c5c08f660f0bdec099e97ef99f470bb8c607ce9667a165e9caa474710f62ffd")
 	signatureTest, _ = hex.DecodeString("8dee56fae60dcad960f7176d0813d5415b930cf6e20c299ec2c2dfc5f2ad4903916fd462ba1abf5c32a5bfd94dcc8eba062d011a548d99df7fa1e3bbbc9a0455663d60f6ccc736c1d5b6de727dbe4427e21fb660925518be386265913f447c94")
 	dpkTest, _ = hex.DecodeString("a02fcd15edd52c8e134027491a43b597505b466d1679e88f70f927e57c45a93ae0765ff02fc2d015e3a02fd8748e2103")
-	payloadTest = collectiveBeacon.New(1, 1, prevSignatureTest, signatureTest, dpkTest)
+	payloadTest = payload.New(1, 1, prevSignatureTest, signatureTest, dpkTest)
 }
 
 func TestVerifyCollectiveBeacon(t *testing.T) {
diff --git a/packages/binary/drng/payload/collectiveBeacon/common.go b/packages/binary/drng/subtypes/collectiveBeacon/payload/common.go
similarity index 82%
rename from packages/binary/drng/payload/collectiveBeacon/common.go
rename to packages/binary/drng/subtypes/collectiveBeacon/payload/common.go
index fe6fcfaf..8b3b8762 100644
--- a/packages/binary/drng/payload/collectiveBeacon/common.go
+++ b/packages/binary/drng/subtypes/collectiveBeacon/payload/common.go
@@ -1,4 +1,4 @@
-package collectiveBeacon
+package payload
 
 const (
 	// BLS Signature size in bytes
diff --git a/packages/binary/drng/payload/collectiveBeacon/collective_beacon.go b/packages/binary/drng/subtypes/collectiveBeacon/payload/payload.go
similarity index 99%
rename from packages/binary/drng/payload/collectiveBeacon/collective_beacon.go
rename to packages/binary/drng/subtypes/collectiveBeacon/payload/payload.go
index 40f2d75d..a6d28ae0 100644
--- a/packages/binary/drng/payload/collectiveBeacon/collective_beacon.go
+++ b/packages/binary/drng/subtypes/collectiveBeacon/payload/payload.go
@@ -1,4 +1,4 @@
-package collectiveBeacon
+package payload
 
 import (
 	"sync"
diff --git a/packages/binary/drng/payload/collectiveBeacon/collective_beacon_test.go b/packages/binary/drng/subtypes/collectiveBeacon/payload/payload_test.go
similarity index 98%
rename from packages/binary/drng/payload/collectiveBeacon/collective_beacon_test.go
rename to packages/binary/drng/subtypes/collectiveBeacon/payload/payload_test.go
index ecc49d99..5f27e035 100644
--- a/packages/binary/drng/payload/collectiveBeacon/collective_beacon_test.go
+++ b/packages/binary/drng/subtypes/collectiveBeacon/payload/payload_test.go
@@ -1,4 +1,4 @@
-package collectiveBeacon
+package payload
 
 import (
 	"testing"
-- 
GitLab