From db0dad7ee89fef940cf7012fd7aad1f591f4b1d7 Mon Sep 17 00:00:00 2001
From: Wolfgang Welz <welzwo@gmail.com>
Date: Wed, 12 Jun 2019 20:26:47 +0200
Subject: [PATCH] Add peer storage

---
 .../autopeering/peerstorage/peerstorage.go    | 82 +++++++++++++++++++
 plugins/autopeering/plugin.go                 |  2 +
 2 files changed, 84 insertions(+)
 create mode 100644 plugins/autopeering/peerstorage/peerstorage.go

diff --git a/plugins/autopeering/peerstorage/peerstorage.go b/plugins/autopeering/peerstorage/peerstorage.go
new file mode 100644
index 00000000..5ea1c80f
--- /dev/null
+++ b/plugins/autopeering/peerstorage/peerstorage.go
@@ -0,0 +1,82 @@
+package peerstorage
+
+import (
+	"bytes"
+	"strconv"
+
+	"github.com/iotaledger/goshimmer/packages/database"
+	"github.com/iotaledger/goshimmer/packages/events"
+	"github.com/iotaledger/goshimmer/packages/node"
+	"github.com/iotaledger/goshimmer/plugins/autopeering/instances/knownpeers"
+	"github.com/iotaledger/goshimmer/plugins/autopeering/types/peer"
+)
+
+const peerDbName string = "peers"
+
+var peerDb database.Database
+
+func initDb() {
+	db, err := database.Get(peerDbName)
+	if err != nil {
+		panic(err)
+	}
+
+	peerDb = db
+}
+
+func storePeer(p *peer.Peer) {
+	err := peerDb.Set(p.Identity.Identifier, p.Marshal())
+	if err != nil {
+		panic(err)
+	}
+}
+
+func removePeer(p *peer.Peer) {
+	err := peerDb.Delete(p.Identity.Identifier)
+	if err != nil {
+		panic(err)
+	}
+}
+
+func loadPeers(plugin *node.Plugin) {
+	var count int
+
+	err := peerDb.ForEach(func(key []byte, value []byte) {
+		peer, err := peer.Unmarshal(value)
+		if err != nil {
+			panic(err)
+		}
+		// the peers are stored by identifier in the db
+		if !bytes.Equal(key, peer.Identity.Identifier) {
+			panic("Invalid item in '" + peerDbName + "' database")
+		}
+
+		knownpeers.INSTANCE.AddOrUpdate(peer)
+		count++
+		plugin.LogDebug("Added stored peer: " + peer.Address.String() + " / " + peer.Identity.StringIdentifier)
+	})
+	if err != nil {
+		panic(err)
+	}
+
+	plugin.LogSuccess("Restored " + strconv.Itoa(count) + " peers from database")
+}
+
+func Configure(plugin *node.Plugin) {
+	initDb()
+
+	// do not store the entry nodes by ignoring all peers currently contained in konwnpeers
+	// add peers from db
+	loadPeers(plugin)
+
+	// subscribe to all known peers' events
+	knownpeers.INSTANCE.Events.Add.Attach(events.NewClosure(func(p *peer.Peer) {
+		storePeer(p)
+	}))
+	knownpeers.INSTANCE.Events.Update.Attach(events.NewClosure(func(p *peer.Peer) {
+		storePeer(p)
+	}))
+	knownpeers.INSTANCE.Events.Remove.Attach(events.NewClosure(func(p *peer.Peer) {
+		removePeer(p)
+	}))
+}
diff --git a/plugins/autopeering/plugin.go b/plugins/autopeering/plugin.go
index ce2a0cde..c8633bff 100644
--- a/plugins/autopeering/plugin.go
+++ b/plugins/autopeering/plugin.go
@@ -8,6 +8,7 @@ import (
 	"github.com/iotaledger/goshimmer/plugins/autopeering/instances/acceptedneighbors"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/instances/chosenneighbors"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/instances/knownpeers"
+	"github.com/iotaledger/goshimmer/plugins/autopeering/peerstorage"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/protocol"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/saltmanager"
 	"github.com/iotaledger/goshimmer/plugins/autopeering/server"
@@ -22,6 +23,7 @@ func configure(plugin *node.Plugin) {
 	instances.Configure(plugin)
 	server.Configure(plugin)
 	protocol.Configure(plugin)
+	peerstorage.Configure(plugin)
 
 	daemon.Events.Shutdown.Attach(events.NewClosure(func() {
 		server.Shutdown(plugin)
-- 
GitLab