diff --git a/plugins/autopeering/peerstorage/peerstorage.go b/plugins/autopeering/peerstorage/peerstorage.go new file mode 100644 index 0000000000000000000000000000000000000000..5ea1c80fc4aa81515d42c8d89f1881e2fcbb6f93 --- /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 ce2a0cde4e34e3c9372170882ed0adac0b792871..c8633bffc4f2d02e21afd16fdc113e90be347bcc 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)