From 5aa4c170c1e78c75b1af6b45d055ad97f2120c43 Mon Sep 17 00:00:00 2001
From: Hans Moog <hm@mkjc.net>
Date: Mon, 3 Jun 2019 15:38:16 +0200
Subject: [PATCH] Feat: intermediary commit for the tangle.Approvers

---
 packages/accountability/accountability.go     |  2 +-
 plugins/analysis/client/plugin.go             | 12 +--
 .../autopeering/instances/ownpeer/instance.go |  2 +-
 .../protocol/outgoing_ping_processor.go       |  2 +-
 .../protocol/outgoing_request_processor.go    |  2 +-
 .../types/peerregister/peer_register.go       |  2 +-
 plugins/gossip/neighbors.go                   |  2 +-
 plugins/gossip/protocol_v1.go                 |  2 +-
 plugins/gossip/server.go                      |  2 +-
 plugins/statusscreen/ui_header_bar.go         |  2 +-
 plugins/tangle/approvers.go                   | 91 +++++++++++++++++++
 11 files changed, 106 insertions(+), 15 deletions(-)
 create mode 100644 plugins/tangle/approvers.go

diff --git a/packages/accountability/accountability.go b/packages/accountability/accountability.go
index eef9bcbc..b34a5f74 100644
--- a/packages/accountability/accountability.go
+++ b/packages/accountability/accountability.go
@@ -11,7 +11,7 @@ var ownId *identity.Identity
 
 var lazyInit sync.Once
 
-func GetOwnId() *identity.Identity {
+func OwnId() *identity.Identity {
 	lazyInit.Do(initOwnId)
 
 	return ownId
diff --git a/plugins/analysis/client/plugin.go b/plugins/analysis/client/plugin.go
index ae494ea8..7925cae5 100644
--- a/plugins/analysis/client/plugin.go
+++ b/plugins/analysis/client/plugin.go
@@ -62,7 +62,7 @@ func getEventDispatchers(conn *network.ManagedConnection) *EventDispatchers {
 }
 
 func reportCurrentStatus(eventDispatchers *EventDispatchers) {
-    eventDispatchers.AddNode(accountability.GetOwnId().Identifier)
+    eventDispatchers.AddNode(accountability.OwnId().Identifier)
 
     reportChosenNeighbors(eventDispatchers)
 }
@@ -75,19 +75,19 @@ func setupHooks(conn *network.ManagedConnection, eventDispatchers *EventDispatch
     })
 
     onAddAcceptedNeighbor := events.NewClosure(func(p *peer.Peer) {
-        eventDispatchers.ConnectNodes(p.Identity.Identifier, accountability.GetOwnId().Identifier)
+        eventDispatchers.ConnectNodes(p.Identity.Identifier, accountability.OwnId().Identifier)
     })
 
     onRemoveAcceptedNeighbor := events.NewClosure(func(p *peer.Peer) {
-        eventDispatchers.DisconnectNodes(p.Identity.Identifier, accountability.GetOwnId().Identifier)
+        eventDispatchers.DisconnectNodes(p.Identity.Identifier, accountability.OwnId().Identifier)
     })
 
     onAddChosenNeighbor := events.NewClosure(func(p *peer.Peer) {
-        eventDispatchers.ConnectNodes(accountability.GetOwnId().Identifier, p.Identity.Identifier)
+        eventDispatchers.ConnectNodes(accountability.OwnId().Identifier, p.Identity.Identifier)
     })
 
     onRemoveChosenNeighbor := events.NewClosure(func(p *peer.Peer) {
-        eventDispatchers.DisconnectNodes(accountability.GetOwnId().Identifier, p.Identity.Identifier)
+        eventDispatchers.DisconnectNodes(accountability.OwnId().Identifier, p.Identity.Identifier)
     })
 
     // setup hooks /////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -118,7 +118,7 @@ func reportChosenNeighbors(dispatchers *EventDispatchers) {
         dispatchers.AddNode(chosenNeighbor.Identity.Identifier)
     }
     for _, chosenNeighbor := range chosenneighbors.INSTANCE.Peers {
-        dispatchers.ConnectNodes(accountability.GetOwnId().Identifier, chosenNeighbor.Identity.Identifier)
+        dispatchers.ConnectNodes(accountability.OwnId().Identifier, chosenNeighbor.Identity.Identifier)
     }
 }
 
diff --git a/plugins/autopeering/instances/ownpeer/instance.go b/plugins/autopeering/instances/ownpeer/instance.go
index e5af993c..558491ad 100644
--- a/plugins/autopeering/instances/ownpeer/instance.go
+++ b/plugins/autopeering/instances/ownpeer/instance.go
@@ -14,7 +14,7 @@ var INSTANCE *peer.Peer
 
 func Configure(plugin *node.Plugin) {
     INSTANCE = &peer.Peer{
-        Identity:    accountability.GetOwnId(),
+        Identity:    accountability.OwnId(),
         PeeringPort: uint16(*parameters.PORT.Value),
         GossipPort:  uint16(*gossip.PORT.Value),
         Address:     net.IPv4(0, 0, 0, 0),
diff --git a/plugins/autopeering/protocol/outgoing_ping_processor.go b/plugins/autopeering/protocol/outgoing_ping_processor.go
index c10ac98e..8fb0916c 100644
--- a/plugins/autopeering/protocol/outgoing_ping_processor.go
+++ b/plugins/autopeering/protocol/outgoing_ping_processor.go
@@ -64,7 +64,7 @@ func pingPeers(plugin *node.Plugin, outgoingPing *ping.Ping) {
             for i := 0; i < constants.PING_CONTACT_COUNT_PER_CYCLE; i++ {
                 randomNeighborHoodPeer := neighborhood.LIST_INSTANCE[rand.Intn(len(neighborhood.LIST_INSTANCE))]
 
-                if randomNeighborHoodPeer.Identity.StringIdentifier != accountability.GetOwnId().StringIdentifier {
+                if randomNeighborHoodPeer.Identity.StringIdentifier != accountability.OwnId().StringIdentifier {
                     chosenPeers[randomNeighborHoodPeer.Identity.StringIdentifier] = randomNeighborHoodPeer
                 }
             }
diff --git a/plugins/autopeering/protocol/outgoing_request_processor.go b/plugins/autopeering/protocol/outgoing_request_processor.go
index 75961075..7d687933 100644
--- a/plugins/autopeering/protocol/outgoing_request_processor.go
+++ b/plugins/autopeering/protocol/outgoing_request_processor.go
@@ -60,7 +60,7 @@ func candidateShouldBeContacted(candidate *peer.Peer) bool {
     nodeId := candidate.Identity.StringIdentifier
 
     return (!acceptedneighbors.INSTANCE.Contains(nodeId) &&!chosenneighbors.INSTANCE.Contains(nodeId) &&
-        accountability.GetOwnId().StringIdentifier != nodeId) && (
+        accountability.OwnId().StringIdentifier != nodeId) && (
             len(chosenneighbors.INSTANCE.Peers) < constants.NEIGHBOR_COUNT / 2 ||
                 chosenneighbors.OWN_DISTANCE(candidate) < chosenneighbors.FURTHEST_NEIGHBOR_DISTANCE)
 }
diff --git a/plugins/autopeering/types/peerregister/peer_register.go b/plugins/autopeering/types/peerregister/peer_register.go
index ea4221fd..1ab502c5 100644
--- a/plugins/autopeering/types/peerregister/peer_register.go
+++ b/plugins/autopeering/types/peerregister/peer_register.go
@@ -33,7 +33,7 @@ func (this *PeerRegister) AddOrUpdate(peer *peer.Peer, lock... bool) bool {
         defer this.Lock()()
     }
 
-    if peer.Identity == nil || bytes.Equal(peer.Identity.Identifier, accountability.GetOwnId().Identifier) {
+    if peer.Identity == nil || bytes.Equal(peer.Identity.Identifier, accountability.OwnId().Identifier) {
         return false
     }
 
diff --git a/plugins/gossip/neighbors.go b/plugins/gossip/neighbors.go
index 1d4a1d31..eb1a8225 100644
--- a/plugins/gossip/neighbors.go
+++ b/plugins/gossip/neighbors.go
@@ -156,7 +156,7 @@ func (neighbor *Neighbor) Connect() (*protocol, bool, errors.IdentifiableError)
 
     // drop the "secondary" connection upon successful handshake
     neighbor.InitiatedProtocol.Events.HandshakeCompleted.Attach(events.NewClosure(func() {
-        if accountability.GetOwnId().StringIdentifier <= neighbor.Identity.StringIdentifier {
+        if accountability.OwnId().StringIdentifier <= neighbor.Identity.StringIdentifier {
             neighbor.acceptedProtocolMutex.Lock()
             var acceptedProtocolConn *network.ManagedConnection
             if neighbor.AcceptedProtocol != nil {
diff --git a/plugins/gossip/protocol_v1.go b/plugins/gossip/protocol_v1.go
index 52dce40c..74687858 100644
--- a/plugins/gossip/protocol_v1.go
+++ b/plugins/gossip/protocol_v1.go
@@ -15,7 +15,7 @@ import (
 // region protocolV1 ///////////////////////////////////////////////////////////////////////////////////////////////////
 
 func protocolV1(protocol *protocol) errors.IdentifiableError {
-    if err := protocol.Send(accountability.GetOwnId()); err != nil {
+    if err := protocol.Send(accountability.OwnId()); err != nil {
         return err
     }
 
diff --git a/plugins/gossip/server.go b/plugins/gossip/server.go
index 3fa56b64..a8125e61 100644
--- a/plugins/gossip/server.go
+++ b/plugins/gossip/server.go
@@ -43,7 +43,7 @@ func configureServer(plugin *node.Plugin) {
 
         // drop the "secondary" connection upon successful handshake
         protocol.Events.HandshakeCompleted.Attach(events.NewClosure(func() {
-            if protocol.Neighbor.Identity.StringIdentifier <= accountability.GetOwnId().StringIdentifier {
+            if protocol.Neighbor.Identity.StringIdentifier <= accountability.OwnId().StringIdentifier {
                 protocol.Neighbor.initiatedProtocolMutex.Lock()
                 var initiatedProtocolConn *network.ManagedConnection
                 if protocol.Neighbor.InitiatedProtocol != nil {
diff --git a/plugins/statusscreen/ui_header_bar.go b/plugins/statusscreen/ui_header_bar.go
index 33315322..0404c159 100644
--- a/plugins/statusscreen/ui_header_bar.go
+++ b/plugins/statusscreen/ui_header_bar.go
@@ -65,7 +65,7 @@ func (headerBar *UIHeaderBar) Update() {
     fmt.Fprintln(headerBar.InfoContainer)
     fmt.Fprintln(headerBar.InfoContainer)
     fmt.Fprintln(headerBar.InfoContainer)
-    fmt.Fprintf(headerBar.InfoContainer, "[::b]Node ID: [::d]%40v  ", accountability.GetOwnId().StringIdentifier)
+    fmt.Fprintf(headerBar.InfoContainer, "[::b]Node ID: [::d]%40v  ", accountability.OwnId().StringIdentifier)
     fmt.Fprintln(headerBar.InfoContainer)
     fmt.Fprintf(headerBar.InfoContainer, "[::b]Neighbors: [::d]%40v  ", strconv.Itoa(len(chosenneighbors.INSTANCE.Peers)) + " chosen / " + strconv.Itoa(len(acceptedneighbors.INSTANCE.Peers)) + " accepted")
     fmt.Fprintln(headerBar.InfoContainer)
diff --git a/plugins/tangle/approvers.go b/plugins/tangle/approvers.go
new file mode 100644
index 00000000..7ca77561
--- /dev/null
+++ b/plugins/tangle/approvers.go
@@ -0,0 +1,91 @@
+package tangle
+
+import (
+	"github.com/iotaledger/goshimmer/packages/ternary"
+	"sync"
+)
+
+type Approvers struct {
+	hash        ternary.Trinary
+	hashes      map[ternary.Trinary]bool
+	hashesMutex sync.RWMutex
+	modified    bool
+}
+
+func NewApprovers(hash ternary.Trinary) *Approvers {
+	return &Approvers{
+		hash:     hash,
+		hashes:   make(map[ternary.Trinary]bool),
+		modified: false,
+	}
+}
+
+// region public method with locking ///////////////////////////////////////////////////////////////////////////////////
+
+func (approvers *Approvers) Add(transactionHash ternary.Trinary) {
+	approvers.hashesMutex.Lock()
+	defer approvers.hashesMutex.Unlock()
+
+	approvers.add(transactionHash)
+}
+
+func (approvers *Approvers) Remove(approverHash ternary.Trinary) {
+	approvers.hashesMutex.Lock()
+	defer approvers.hashesMutex.Unlock()
+
+	approvers.remove(approverHash)
+}
+
+func (approvers *Approvers) GetHashes() []ternary.Trinary {
+	approvers.hashesMutex.RLock()
+	defer approvers.hashesMutex.RUnlock()
+
+	return approvers.getHashes()
+}
+
+// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+// region private methods without locking //////////////////////////////////////////////////////////////////////////////
+
+func (approvers *Approvers) add(transactionHash ternary.Trinary) {
+	if _, exists := approvers.hashes[transactionHash]; !exists {
+		approvers.hashes[transactionHash] = true
+		approvers.modified = true
+	}
+}
+
+func (approvers *Approvers) remove(approverHash ternary.Trinary) {
+	if _, exists := approvers.hashes[approverHash]; exists {
+		delete(approvers.hashes, approverHash)
+		approvers.modified = true
+	}
+}
+
+func (approvers *Approvers) getHashes() []ternary.Trinary {
+	hashes := make([]ternary.Trinary, len(approvers.hashes))
+
+	counter := 0
+	for hash, _ := range approvers.hashes {
+		hashes[counter] = hash
+
+		counter++
+	}
+
+	return hashes
+}
+
+// endregion ///////////////////////////////////////////////////////////////////////////////////////////////////////////
+
+func (approvers *Approvers) Store(approverHash ternary.Trinary) {
+	approvers.hashesMutex.Lock()
+	approvers.hashesMutex.RUnlock()
+
+	approvers.modified = false
+}
+
+func (approvers *Approvers) Marshal() []byte {
+	approvers.hashesMutex.RLock()
+	defer approvers.hashesMutex.RUnlock()
+
+	return make([]byte, 0)
+}
-- 
GitLab