plugin.go 4.27 KiB
package client
import (
"github.com/iotaledger/goshimmer/packages/accountability"
"github.com/iotaledger/goshimmer/packages/daemon"
"github.com/iotaledger/goshimmer/packages/network"
"github.com/iotaledger/goshimmer/packages/node"
"github.com/iotaledger/goshimmer/plugins/analysis/types/addnode"
"github.com/iotaledger/goshimmer/plugins/analysis/types/connectnodes"
"github.com/iotaledger/goshimmer/plugins/analysis/types/ping"
"github.com/iotaledger/goshimmer/plugins/autopeering/protocol"
"github.com/iotaledger/goshimmer/plugins/autopeering/types/peer"
"github.com/iotaledger/goshimmer/plugins/autopeering/types/request"
"github.com/iotaledger/goshimmer/plugins/autopeering/types/response"
"github.com/iotaledger/goshimmer/plugins/gossip/neighbormanager"
"net"
"time"
)
func Run(plugin *node.Plugin) {
daemon.BackgroundWorker(func() {
shuttingDown := false
for !shuttingDown {
if conn, err := net.Dial("tcp", *SERVER_ADDRESS.Value); err != nil {
plugin.LogDebug("Could not connect to reporting server: " + err.Error())
} else {
managedConn := network.NewManagedConnection(conn)
eventDispatchers := getEventDispatchers(managedConn)
reportCurrentStatus(eventDispatchers)
setupHooks(managedConn, eventDispatchers)
shuttingDown = keepConnectionAlive(managedConn)
}
}
})
}
func getEventDispatchers(conn *network.ManagedConnection) *EventDispatchers {
return &EventDispatchers{
AddNode: func(nodeId []byte) {
conn.Write((&addnode.Packet{ NodeId: nodeId }).Marshal())
},
ConnectNodes: func(sourceId []byte, targetId []byte) {
conn.Write((&connectnodes.Packet{ SourceId: sourceId, TargetId: targetId }).Marshal())
},
}
}
func reportCurrentStatus(eventDispatchers *EventDispatchers) {
eventDispatchers.AddNode(accountability.OWN_ID.Identifier)
reportChosenNeighbors(eventDispatchers)
}
func setupHooks(conn *network.ManagedConnection, eventDispatchers *EventDispatchers) {
// define hooks ////////////////////////////////////////////////////////////////////////////////////////////////////
onDiscoverPeer := func(p *peer.Peer) {
eventDispatchers.AddNode(p.Identity.Identifier)
}
onIncomingRequestAccepted := func(req *request.Request) {
eventDispatchers.ConnectNodes(req.Issuer.Identity.Identifier, accountability.OWN_ID.Identifier)
}
onOutgoingRequestAccepted := func(res *response.Response) {
eventDispatchers.ConnectNodes(accountability.OWN_ID.Identifier, res.Issuer.Identity.Identifier)
}
// setup hooks /////////////////////////////////////////////////////////////////////////////////////////////////////
protocol.Events.DiscoverPeer.Attach(onDiscoverPeer)
protocol.Events.IncomingRequestAccepted.Attach(onIncomingRequestAccepted)
protocol.Events.OutgoingRequestAccepted.Attach(onOutgoingRequestAccepted)
// clean up hooks on close /////////////////////////////////////////////////////////////////////////////////////////
var onClose func()
onClose = func() {
protocol.Events.DiscoverPeer.Detach(onDiscoverPeer)
protocol.Events.IncomingRequestAccepted.Detach(onIncomingRequestAccepted)
protocol.Events.OutgoingRequestAccepted.Detach(onOutgoingRequestAccepted)
conn.Events.Close.Detach(onClose)
}
conn.Events.Close.Attach(onClose)
}
func reportChosenNeighbors(dispatchers *EventDispatchers) {
for _, chosenNeighbor := range neighbormanager.CHOSEN_NEIGHBORS {
dispatchers.AddNode(chosenNeighbor.Identity.Identifier)
}
for _, chosenNeighbor := range neighbormanager.CHOSEN_NEIGHBORS {
dispatchers.ConnectNodes(accountability.OWN_ID.Identifier, chosenNeighbor.Identity.Identifier)
}
}
func keepConnectionAlive(conn *network.ManagedConnection) bool {
go conn.Read(make([]byte, 1))
ticker := time.NewTicker(1 * time.Second)
for {
select {
case <- daemon.ShutdownSignal:
return true
case <- ticker.C:
if _, err := conn.Write((&ping.Packet{}).Marshal()); err != nil {
return false
}
}
}
}