Skip to content
Snippets Groups Projects
Commit faaf9f73 authored by Hans Moog's avatar Hans Moog
Browse files

Feat: commit of initial packages

parent f9d47f24
No related branches found
No related tags found
No related merge requests found
Showing
with 906 additions and 0 deletions
package udp
import "net"
type Callback = func()
type AddressDataConsumer = func(addr *net.UDPAddr, data []byte)
type ErrorConsumer = func(err error)
package node
const (
LOG_LEVEL_FAILURE = 0
LOG_LEVEL_WARNING = 1
LOG_LEVEL_SUCCESS = 2
LOG_LEVEL_INFO = 3
)
package node
import (
"reflect"
)
type pluginEvents struct {
Configure *callbackEvent
Run *callbackEvent
}
type callbackEvent struct {
callbacks map[uintptr]Callback
}
func (this *callbackEvent) Attach(callback Callback) {
this.callbacks[reflect.ValueOf(callback).Pointer()] = callback
}
func (this *callbackEvent) Detach(callback Callback) {
delete(this.callbacks, reflect.ValueOf(callback).Pointer())
}
func (this *callbackEvent) Trigger(plugin *Plugin) {
for _, callback := range this.callbacks {
callback(plugin)
}
}
package node
import "fmt"
type Logger struct {
Enabled bool
LogInfo func(pluginName string, message string)
LogSuccess func(pluginName string, message string)
LogWarning func(pluginName string, message string)
LogFailure func(pluginName string, message string)
}
func pluginPrefix(pluginName string) string {
var pluginPrefix string
if pluginName == "Node" {
pluginPrefix = ""
} else {
pluginPrefix = pluginName + ": "
}
return pluginPrefix
}
var DEFAULT_LOGGER = &Logger{
Enabled: true,
LogSuccess: func(pluginName string, message string) {
fmt.Println("[ OK ] " + pluginPrefix(pluginName) + message)
},
LogInfo: func(pluginName string, message string) {
fmt.Println("[ INFO ] " + pluginPrefix(pluginName) + message)
},
LogWarning: func(pluginName string, message string) {
fmt.Println("[ WARN ] " + pluginPrefix(pluginName) + message)
},
LogFailure: func(pluginName string, message string) {
fmt.Println("[ FAIL ] " + pluginPrefix(pluginName) + message)
},
}
package node
import (
"fmt"
"github.com/iotaledger/goshimmer/packages/daemon"
"sync"
)
type Node struct {
wg *sync.WaitGroup
loggers []*Logger
loadedPlugins []*Plugin
logLevel int
}
func Load(plugins ...*Plugin) *Node {
fmt.Println(" _____ _ _ ________ ______ ___ ___________ ")
fmt.Println(" / ___| | | |_ _| \\/ || \\/ || ___| ___ \\")
fmt.Println(" \\ `--.| |_| | | | | . . || . . || |__ | |_/ /")
fmt.Println(" `--. \\ _ | | | | |\\/| || |\\/| || __|| / ")
fmt.Println(" /\\__/ / | | |_| |_| | | || | | || |___| |\\ \\ ")
fmt.Println(" \\____/\\_| |_/\\___/\\_| |_/\\_| |_/\\____/\\_| \\_| fullnode 1.0")
fmt.Println()
node := &Node{
logLevel: LOG_LEVEL_INFO,
loggers: make([]*Logger, 0),
wg: &sync.WaitGroup{},
loadedPlugins: make([]*Plugin, 0),
}
node.AddLogger(DEFAULT_LOGGER)
node.Load(plugins...)
return node
}
func Run(plugins ...*Plugin) *Node {
node := Load(plugins...)
node.Run()
return node
}
func (node *Node) AddLogger(logger *Logger) {
node.loggers = append(node.loggers, logger)
}
func (node *Node) LogSuccess(pluginName string, message string) {
if node.logLevel >= LOG_LEVEL_SUCCESS {
for _, logger := range node.loggers {
if logger.Enabled {
logger.LogSuccess(pluginName, message)
}
}
}
}
func (node *Node) LogInfo(pluginName string, message string) {
if node.logLevel >= LOG_LEVEL_INFO {
for _, logger := range node.loggers {
if logger.Enabled {
logger.LogInfo(pluginName, message)
}
}
}
}
func (node *Node) LogWarning(pluginName string, message string) {
if node.logLevel >= LOG_LEVEL_WARNING {
for _, logger := range node.loggers {
if logger.Enabled {
logger.LogWarning(pluginName, message)
}
}
}
}
func (node *Node) LogFailure(pluginName string, message string) {
if node.logLevel >= LOG_LEVEL_FAILURE {
for _, logger := range node.loggers {
if logger.Enabled {
logger.LogFailure(pluginName, message)
}
}
}
}
func (node *Node) Load(plugins ...*Plugin) {
node.LogInfo("Node", "Loading plugins ...")
if len(plugins) >= 1 {
for _, plugin := range plugins {
plugin.wg = node.wg
plugin.Node = node
plugin.Events.Configure.Trigger(plugin)
node.LogInfo("Node", "Loading Plugin: "+plugin.Name+" ... done")
}
}
node.loadedPlugins = append(node.loadedPlugins, plugins...)
}
func (node *Node) Run() {
node.LogInfo("Node", "Executing plugins ...")
if len(node.loadedPlugins) >= 1 {
for _, plugin := range node.loadedPlugins {
plugin.Events.Run.Trigger(plugin)
node.LogSuccess("Node", "Starting Plugin: "+plugin.Name+" ... done")
}
}
node.LogSuccess("Node", "Starting background workers ...")
daemon.Run()
node.LogSuccess("Node", "Shutdown complete!")
}
package node
import (
"sync"
)
type Plugin struct {
Node *Node
Name string
Events pluginEvents
wg *sync.WaitGroup
}
func NewPlugin(name string, callback Callback, callbacks ...Callback) *Plugin {
plugin := &Plugin{
Name: name,
Events: pluginEvents{
Configure: &callbackEvent{make(map[uintptr]Callback)},
Run: &callbackEvent{make(map[uintptr]Callback)},
},
}
if len(callbacks) >= 1 {
plugin.Events.Configure.Attach(callback)
for _, callback = range callbacks[:len(callbacks)-1] {
plugin.Events.Configure.Attach(callback)
}
plugin.Events.Run.Attach(callbacks[len(callbacks)-1])
} else {
plugin.Events.Run.Attach(callback)
}
return plugin
}
func (plugin *Plugin) LogSuccess(message string) {
plugin.Node.LogSuccess(plugin.Name, message)
}
func (plugin *Plugin) LogInfo(message string) {
plugin.Node.LogInfo(plugin.Name, message)
}
func (plugin *Plugin) LogWarning(message string) {
plugin.Node.LogWarning(plugin.Name, message)
}
func (plugin *Plugin) LogFailure(message string) {
plugin.Node.LogFailure(plugin.Name, message)
}
package node
type Callback = func(plugin *Plugin)
package parameter
var (
// expose int methods
AddInt = addInt
GetInt = getInt
GetInts = getInts
// expose string methods
AddString = addString
GetString = getString
GetStrings = getStrings
// expose events
Events = moduleEvents{
AddInt: &intParameterEvent{make(map[uintptr]IntParameterConsumer)},
AddString: &stringParameterEvent{make(map[uintptr]StringParameterConsumer)},
}
)
package parameter
import "reflect"
type moduleEvents struct {
AddInt *intParameterEvent
AddString *stringParameterEvent
}
//region intParameterEvent /////////////////////////////////////////////////////////////////////////////////////////////
type intParameterEvent struct {
callbacks map[uintptr]IntParameterConsumer
}
func (this *intParameterEvent) Attach(callback IntParameterConsumer) {
this.callbacks[reflect.ValueOf(callback).Pointer()] = callback
}
func (this *intParameterEvent) Detach(callback IntParameterConsumer) {
delete(this.callbacks, reflect.ValueOf(callback).Pointer())
}
func (this *intParameterEvent) Trigger(param *IntParameter) {
for _, callback := range this.callbacks {
callback(param)
}
}
//endregion ////////////////////////////////////////////////////////////////////////////////////////////////////////////
//region stringParameterEvent //////////////////////////////////////////////////////////////////////////////////////////
type stringParameterEvent struct {
callbacks map[uintptr]StringParameterConsumer
}
func (this *stringParameterEvent) Attach(callback StringParameterConsumer) {
this.callbacks[reflect.ValueOf(callback).Pointer()] = callback
}
func (this *stringParameterEvent) Detach(callback StringParameterConsumer) {
delete(this.callbacks, reflect.ValueOf(callback).Pointer())
}
func (this *stringParameterEvent) Trigger(param *StringParameter) {
for _, callback := range this.callbacks {
callback(param)
}
}
//endregion ////////////////////////////////////////////////////////////////////////////////////////////////////////////
package parameter
var intParameters = make(map[string]*IntParameter)
func addInt(name string, defaultValue int, description string) *IntParameter {
if intParameters[name] != nil {
panic("duplicate parameter - \"" + name + "\" was defined already")
}
newParameter := &IntParameter{
Name: name,
DefaultValue: defaultValue,
Value: &defaultValue,
Description: description,
}
intParameters[name] = newParameter
Events.AddInt.Trigger(newParameter)
return newParameter
}
func getInt(name string) *IntParameter {
return intParameters[name]
}
func getInts() map[string]*IntParameter {
return intParameters
}
var stringParameters = make(map[string]*StringParameter)
func addString(name string, defaultValue string, description string) *StringParameter {
if intParameters[name] != nil {
panic("duplicate parameter - \"" + name + "\" was defined already")
}
newParameter := &StringParameter{
Name: name,
DefaultValue: defaultValue,
Value: &defaultValue,
Description: description,
}
stringParameters[name] = newParameter
Events.AddString.Trigger(newParameter)
return stringParameters[name]
}
func getString(name string) *StringParameter {
return stringParameters[name]
}
func getStrings() map[string]*StringParameter {
return stringParameters
}
package parameter
type IntParameter struct {
Name string
Value *int
DefaultValue int
Description string
}
type StringParameter struct {
Name string
Value *string
DefaultValue string
Description string
}
type IntParameterConsumer = func(param *IntParameter)
type StringParameterConsumer = func(param *StringParameter)
package settings
import "github.com/iotaledger/goshimmer/packages/database"
var settingsDatabase database.Database
func init() {
if db, err := database.Get("settings"); err != nil {
panic(err)
} else {
settingsDatabase = db
}
}
func Get(key []byte) ([]byte, error) {
return settingsDatabase.Get(key)
}
func Set(key []byte, value []byte) error {
return settingsDatabase.Set(key, value)
}
\ No newline at end of file
package transaction
const (
// sizes of the transaction fields
SIGNATURE_MESSAGE_FRAGMENT_SIZE = 6561
ADDRESS_SIZE = 243
VALUE_SIZE = 81
TIMESTAMP_SIZE = 27
CURRENT_INDEX_SIZE = 27
LATEST_INDEX_SIZE = 27
BUNDLE_HASH_SIZE = 243
TRUNK_TRANSACTION_HASH_SIZE = 243
BRANCH_TRANSACTION_HASH_SIZE = 243
TAG_SIZE = 81
NODE_ID_SIZE = 243
NONCE_SIZE = 81
// offsets of the transaction fields
SIGNATURE_MESSAGE_FRAGMENT_OFFSET = 0
ADDRESS_OFFSET = SIGNATURE_MESSAGE_FRAGMENT_END
VALUE_OFFSET = ADDRESS_END
TIMESTAMP_OFFSET = VALUE_END
CURRENT_INDEX_OFFSET = TIMESTAMP_END
LATEST_INDEX_OFFSET = CURRENT_INDEX_END
BUNDLE_HASH_OFFSET = LATEST_INDEX_END
TRUNK_TRANSACTION_HASH_OFFSET = BUNDLE_HASH_END
BRANCH_TRANSACTION_HASH_OFFSET = TRUNK_TRANSACTION_HASH_END
TAG_OFFSET = BRANCH_TRANSACTION_HASH_END
NODE_ID_OFFSET = TAG_END
NONCE_OFFSET = NODE_ID_END
// ends of the transaction fields
SIGNATURE_MESSAGE_FRAGMENT_END = SIGNATURE_MESSAGE_FRAGMENT_OFFSET + SIGNATURE_MESSAGE_FRAGMENT_SIZE
ADDRESS_END = ADDRESS_OFFSET + ADDRESS_SIZE
VALUE_END = VALUE_OFFSET + VALUE_SIZE
TIMESTAMP_END = TIMESTAMP_OFFSET + TIMESTAMP_SIZE
CURRENT_INDEX_END = CURRENT_INDEX_OFFSET + CURRENT_INDEX_SIZE
LATEST_INDEX_END = LATEST_INDEX_OFFSET + LATEST_INDEX_SIZE
BUNDLE_HASH_END = BUNDLE_HASH_OFFSET + BUNDLE_HASH_SIZE
TRUNK_TRANSACTION_HASH_END = TRUNK_TRANSACTION_HASH_OFFSET + TRUNK_TRANSACTION_HASH_SIZE
BRANCH_TRANSACTION_HASH_END = BRANCH_TRANSACTION_HASH_OFFSET + BRANCH_TRANSACTION_HASH_SIZE
TAG_END = TAG_OFFSET + TAG_SIZE
NODE_ID_END = NODE_ID_OFFSET + NODE_ID_SIZE
NONCE_END = NONCE_OFFSET + NONCE_SIZE
// the full size of a transaction
TRANSACTION_SIZE = NONCE_END
)
package transaction
import (
"github.com/iotadevelopment/go/packages/curl"
"github.com/iotadevelopment/go/packages/ternary"
)
type Transaction struct {
SignatureMessageFragment ternary.Trits
Address ternary.Trits
Value int64
Timestamp uint64
CurrentIndex uint64
LatestIndex uint64
BundleHash ternary.Trits
TrunkTransactionHash ternary.Trits
BranchTransactionHash ternary.Trits
Tag ternary.Trits
NodeId ternary.Trits
Nonce ternary.Trits
Hash ternary.Trits
WeightMagnitude int
Bytes []byte
Trits ternary.Trits
}
func FromTrits(trits ternary.Trits, optionalHash ...ternary.Trits) *Transaction {
hash := <- curl.CURLP81.Hash(trits)
transaction := &Transaction{
SignatureMessageFragment: trits[SIGNATURE_MESSAGE_FRAGMENT_OFFSET:SIGNATURE_MESSAGE_FRAGMENT_END],
Address: trits[ADDRESS_OFFSET:ADDRESS_END],
Value: trits[VALUE_OFFSET:VALUE_END].ToInt64(),
Timestamp: trits[TIMESTAMP_OFFSET:TIMESTAMP_END].ToUint64(),
CurrentIndex: trits[CURRENT_INDEX_OFFSET:CURRENT_INDEX_END].ToUint64(),
LatestIndex: trits[LATEST_INDEX_OFFSET:LATEST_INDEX_END].ToUint64(),
BundleHash: trits[BUNDLE_HASH_OFFSET:BUNDLE_HASH_END],
TrunkTransactionHash: trits[TRUNK_TRANSACTION_HASH_OFFSET:TRUNK_TRANSACTION_HASH_END],
BranchTransactionHash: trits[BRANCH_TRANSACTION_HASH_OFFSET:BRANCH_TRANSACTION_HASH_END],
Tag: trits[TAG_OFFSET:TAG_END],
NodeId: trits[NODE_ID_OFFSET:NODE_ID_END],
Nonce: trits[NONCE_OFFSET:NONCE_END],
Hash: hash,
WeightMagnitude: hash.TrailingZeroes(),
Trits: trits,
}
return transaction
}
func FromBytes(bytes []byte) *Transaction {
transaction := FromTrits(ternary.BytesToTrits(bytes)[:TRANSACTION_SIZE])
transaction.Bytes = bytes
return transaction
}
\ No newline at end of file
package autopeering
import (
"github.com/iotaledger/goshimmer/packages/daemon"
"github.com/iotaledger/goshimmer/packages/node"
"github.com/iotaledger/goshimmer/plugins/autopeering/peermanager"
"github.com/iotaledger/goshimmer/plugins/autopeering/server"
)
func configure(plugin *node.Plugin) {
server.Configure(plugin)
peermanager.Configure(plugin)
daemon.Events.Shutdown.Attach(func() {
server.Shutdown(plugin)
peermanager.Shutdown(plugin)
})
}
func run(plugin *node.Plugin) {
server.Run(plugin)
peermanager.Run(plugin)
}
var PLUGIN = node.NewPlugin("Auto Peering", configure, run)
package parameters
import "github.com/iotaledger/goshimmer/packages/parameter"
var (
ADDRESS = parameter.AddString("AUTOPEERING/ADDRESS", "0.0.0.0", "address to bind for incoming peering requests")
UDP_PORT = parameter.AddInt("AUTOPEERING/UDP_PORT", 14626, "udp port for incoming peering requests")
ENTRY_NODES = parameter.AddString("AUTOPEERING/ENTRY_NODES", "tcp://82.165.29.179:14626", "list of trusted entry nodes for auto peering")
)
package peermanager
import (
"github.com/iotaledger/goshimmer/packages/identity"
"time"
)
const (
FIND_NEIGHBOR_INTERVAL = 5 * time.Second
)
var UNKNOWN_IDENTITY = identity.GenerateRandomIdentity()
package peermanager
import (
"github.com/iotaledger/goshimmer/plugins/autopeering/parameters"
"github.com/iotaledger/goshimmer/plugins/autopeering/protocol"
"net"
"strconv"
"strings"
)
func getEntryNodes() []*protocol.Peer {
result := make([]*protocol.Peer, 0)
for _, entryNodeDefinition := range strings.Fields(*parameters.ENTRY_NODES.Value) {
if entryNodeDefinition == "" {
continue
}
entryNode := &protocol.Peer{
Identity: UNKNOWN_IDENTITY,
}
protocolBits := strings.Split(entryNodeDefinition, "://")
if len(protocolBits) != 2 {
panic("invalid entry in list of trusted entry nodes: " + entryNodeDefinition)
}
switch protocolBits[0] {
case "tcp":
entryNode.PeeringProtocolType = protocol.TCP_PROTOCOL
case "udp":
entryNode.PeeringProtocolType = protocol.UDP_PROTOCOL
}
addressBits := strings.Split(protocolBits[1], ":")
switch len(addressBits) {
case 2:
host := addressBits[0]
port, err := strconv.Atoi(addressBits[1])
if err != nil {
panic("error while parsing port of entry in list of entry nodes")
}
ip := net.ParseIP(host)
if ip == nil {
panic("error while parsing ip of entry in list of entry nodes")
}
entryNode.Address = ip
entryNode.PeeringPort = uint16(port)
case 6:
host := strings.Join(addressBits[:5], ":")
port, err := strconv.Atoi(addressBits[5])
if err != nil {
panic("error while parsing port of entry in list of entry nodes")
}
ip := net.ParseIP(host)
if ip == nil {
panic("error while parsing ip of entry in list of entry nodes")
}
entryNode.Address = ip
entryNode.PeeringPort = uint16(port)
default:
panic("invalid entry in list of trusted entry nodes: " + entryNodeDefinition)
}
result = append(result, entryNode)
}
return result
}
var ENTRY_NODES = getEntryNodes()
\ No newline at end of file
package peermanager
import (
"bytes"
"github.com/iotaledger/goshimmer/packages/accountability"
"github.com/iotaledger/goshimmer/plugins/autopeering/protocol"
"time"
)
type PeerList struct {
Peers map[string]*protocol.Peer
}
func (this *PeerList) Update(peer *protocol.Peer) {
if peer.Identity == UNKNOWN_IDENTITY || bytes.Equal(peer.Identity.Identifier, accountability.OWN_ID.Identifier) {
return
}
now := time.Now()
if existingPeer, exists := this.Peers[peer.Identity.StringIdentifier]; exists {
existingPeer.Address = peer.Address
existingPeer.GossipPort = peer.GossipPort
existingPeer.PeeringPort = peer.PeeringPort
existingPeer.LastSeen = now
existingPeer.LastContact = now
// trigger update peer
} else {
peer.FirstSeen = now
peer.LastSeen = now
peer.LastContact = now
this.Peers[peer.Identity.StringIdentifier] = peer
// trigger add peer
}
}
func (this *PeerList) Add(peer *protocol.Peer) {
this.Peers[peer.Identity.StringIdentifier] = peer
}
func (this *PeerList) Contains(key string) bool {
if _, exists := this.Peers[key]; exists {
return true
} else {
return false
}
}
package peermanager
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/autopeering/parameters"
"github.com/iotaledger/goshimmer/plugins/autopeering/protocol"
"github.com/iotaledger/goshimmer/plugins/autopeering/salt"
"github.com/iotaledger/goshimmer/plugins/autopeering/saltmanager"
"github.com/iotaledger/goshimmer/plugins/autopeering/server"
"math"
"net"
"strconv"
"time"
)
var PEERING_REQUEST *protocol.PeeringRequest
var KNOWN_PEERS = &PeerList{make(map[string]*protocol.Peer)}
var CHOSEN_NEIGHBORS = &PeerList{make(map[string]*protocol.Peer)}
var ACCEPTED_NEIGHBORS = &PeerList{make(map[string]*protocol.Peer)}
func configurePeeringRequest() {
PEERING_REQUEST = &protocol.PeeringRequest{
Issuer: &protocol.Peer{
Identity: accountability.OWN_ID,
PeeringProtocolType: protocol.TCP_PROTOCOL,
PeeringPort: uint16(*parameters.UDP_PORT.Value),
GossipProtocolType: protocol.TCP_PROTOCOL,
GossipPort: uint16(*parameters.UDP_PORT.Value),
Address: net.IPv4(0, 0, 0, 0),
},
Salt: saltmanager.PUBLIC_SALT,
}
PEERING_REQUEST.Sign()
saltmanager.Events.UpdatePublicSalt.Attach(func(salt *salt.Salt) {
PEERING_REQUEST.Sign()
})
}
func Configure(plugin *node.Plugin) {
configurePeeringRequest()
server.Events.ReceivePeeringRequest.Attach(func(ip net.IP, peeringRequest *protocol.PeeringRequest) {
peer := peeringRequest.Issuer
peer.Address = ip
KNOWN_PEERS.Update(peer)
plugin.LogInfo("received peering request from " + peeringRequest.Issuer.Identity.StringIdentifier)
})
server.Events.ReceiveTCPPeeringRequest.Attach(func(conn network.Connection, request *protocol.PeeringRequest) {
peer := request.Issuer
peer.Address = conn.GetConnection().RemoteAddr().(*net.TCPAddr).IP
KNOWN_PEERS.Update(peer)
plugin.LogInfo("received peering request from " + request.Issuer.Identity.StringIdentifier)
sendPeeringResponse(conn.GetConnection())
})
server.Events.Error.Attach(func(ip net.IP, err error) {
plugin.LogFailure("invalid peering request from " + ip.String())
})
}
func Run(plugin *node.Plugin) {
daemon.BackgroundWorker(func() {
chooseNeighbors(plugin)
ticker := time.NewTicker(FIND_NEIGHBOR_INTERVAL)
for {
select {
case <- daemon.ShutdownSignal:
return
case <- ticker.C:
chooseNeighbors(plugin)
}
}
})
}
func Shutdown(plugin *node.Plugin) {}
func generateProposedNodeCandidates() []*protocol.Peer {
peers := make([]*protocol.Peer, 0)
for _, peer := range KNOWN_PEERS.Peers {
peers = append(peers, peer)
}
return peers
}
func rejectPeeringRequest(conn net.Conn) {
conn.Write((&protocol.PeeringResponse{
Type: protocol.PEERING_RESPONSE_REJECT,
Issuer: PEERING_REQUEST.Issuer,
Peers: generateProposedNodeCandidates(),
}).Sign().Marshal())
conn.Close()
}
func acceptPeeringRequest(conn net.Conn) {
conn.Write((&protocol.PeeringResponse{
Type: protocol.PEERING_RESPONSE_ACCEPT,
Issuer: PEERING_REQUEST.Issuer,
Peers: generateProposedNodeCandidates(),
}).Sign().Marshal())
conn.Close()
}
func sendPeeringResponse(conn net.Conn) {
if len(ACCEPTED_NEIGHBORS.Peers) < protocol.NEIGHBOR_COUNT / 2 {
acceptPeeringRequest(conn)
} else {
rejectPeeringRequest(conn)
}
}
func sendPeeringRequest(plugin *node.Plugin, peer *protocol.Peer) {
var protocolString string
switch peer.PeeringProtocolType {
case protocol.TCP_PROTOCOL:
protocolString = "tcp"
case protocol.UDP_PROTOCOL:
protocolString = "udp"
default:
panic("invalid protocol in known peers")
}
conn, err := net.Dial(protocolString, peer.Address.String() + ":" + strconv.Itoa(int(peer.PeeringPort)))
if err != nil {
plugin.LogFailure(err.Error())
} else {
conn := network.NewPeer(protocolString, conn)
conn.Write(PEERING_REQUEST.Marshal())
buffer := make([]byte, protocol.PEERING_RESPONSE_MARSHALLED_TOTAL_SIZE)
offset := 0
conn.OnReceiveData(func(data []byte) {
remainingCapacity := int(math.Min(float64(protocol.PEERING_RESPONSE_MARSHALLED_TOTAL_SIZE - offset), float64(len(data))))
copy(buffer[offset:], data[:remainingCapacity])
offset += len(data)
if offset >= protocol.PEERING_RESPONSE_MARSHALLED_TOTAL_SIZE {
peeringResponse, err := protocol.UnmarshalPeeringResponse(buffer)
if err != nil {
plugin.LogFailure("invalid peering response from " + conn.GetConnection().RemoteAddr().String())
} else {
processPeeringResponse(plugin, peeringResponse)
}
conn.GetConnection().Close()
}
})
go conn.HandleConnection()
}
}
func processPeeringResponse(plugin *node.Plugin, response *protocol.PeeringResponse) {
KNOWN_PEERS.Update(response.Issuer)
for _, peer := range response.Peers {
KNOWN_PEERS.Update(peer)
}
switch response.Type {
case protocol.PEERING_RESPONSE_ACCEPT:
CHOSEN_NEIGHBORS.Update(response.Issuer)
case protocol.PEERING_RESPONSE_REJECT:
default:
plugin.LogInfo("invalid response type in peering response of " + response.Issuer.Address.String() + ":" + strconv.Itoa(int(response.Issuer.PeeringPort)))
}
}
func getChosenNeighborCandidates() []*protocol.Peer {
result := make([]*protocol.Peer, 0)
for _, peer := range KNOWN_PEERS.Peers {
result = append(result, peer)
}
for _, peer := range ENTRY_NODES {
result = append(result, peer)
}
return result
}
func chooseNeighbors(plugin *node.Plugin) {
for _, peer := range getChosenNeighborCandidates() {
sendPeeringRequest(plugin, peer)
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment