Skip to content

Commit

Permalink
Feat/mana autopeering (iotaledger#1045)
Browse files Browse the repository at this point in the history
* upgrade hive

* Integrate mana with autopeering

* adjust R parameter

* Increase R parameter to 40

* Update hive.go

* Fix import cycle

* update hive

* Expose ManaScaleFactor

* Fix linter warnings

* Address review

* Address review comments

* Change parameters definition

* Fix typo
  • Loading branch information
capossele authored Mar 30, 2021
1 parent efe3d1d commit 94102b2
Show file tree
Hide file tree
Showing 18 changed files with 189 additions and 130 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ require (
github.com/golang/protobuf v1.4.3
github.com/golang/snappy v0.0.2 // indirect
github.com/gorilla/websocket v1.4.2
github.com/iotaledger/hive.go v0.0.0-20210317185122-1ac328c4054f
github.com/iotaledger/hive.go v0.0.0-20210327095456-8b9171badf36
github.com/kr/pretty v0.2.1 // indirect
github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/gommon v0.3.0
Expand Down
8 changes: 5 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -404,8 +404,8 @@ github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:q
github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA=
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
github.com/iotaledger/hive.go v0.0.0-20210317185122-1ac328c4054f h1:+hbQVRGodH7rBJS/cPG9qgdz37L54WRshFZYf6Cdv2o=
github.com/iotaledger/hive.go v0.0.0-20210317185122-1ac328c4054f/go.mod h1:K/0FfpFpR4elUAvRFMn8UNfmiQmKD7EcZdWngRLi2hw=
github.com/iotaledger/hive.go v0.0.0-20210327095456-8b9171badf36 h1:WBxsDCexBJOz3ObOFazSz4uwYmS/zjOLurmWdLGCURk=
github.com/iotaledger/hive.go v0.0.0-20210327095456-8b9171badf36/go.mod h1:NyBg/Ny7FFAdDs59zdwTVoysU2ZbJVQnRwyLIDFKJYA=
github.com/ipfs/go-cid v0.0.1/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
github.com/ipfs/go-cid v0.0.2/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
github.com/ipfs/go-cid v0.0.3/go.mod h1:GHWU/WuQdMPmIosc4Yn1bcCT7dSeX4lBafM7iqUPQvM=
Expand Down Expand Up @@ -648,6 +648,7 @@ github.com/libp2p/go-yamux v1.3.5/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZ
github.com/libp2p/go-yamux v1.3.6/go.mod h1:FGTiPvoV/3DVdgWpX+tM0OW3tsM+W5bSE3gZwqQTcow=
github.com/lightstep/lightstep-tracer-common/golang/gogo v0.0.0-20190605223551-bc2310a04743/go.mod h1:qklhhLq1aX+mtWk9cPHPzaBjWImj5ULL6C7HFJtXQMM=
github.com/lightstep/lightstep-tracer-go v0.18.1/go.mod h1:jlF1pusYV4pidLvZ+XD0UBX0ZE6WURAspgAczcDHrL4=
github.com/linxGnu/grocksdb v1.6.32/go.mod h1:/+iSQrn7Izt6kFhHBQvcE6FkklsKXa8hc35pFyFDrDw=
github.com/lufia/iostat v1.1.0/go.mod h1:rEPNA0xXgjHQjuI5Cy05sLlS2oRcSlWHRLrvh/AQ+Pg=
github.com/lyft/protoc-gen-validate v0.0.13/go.mod h1:XbGvPuh87YZc5TdIa2/I4pLk0QoUACkjt2znoq26NVQ=
github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
Expand Down Expand Up @@ -1379,8 +1380,9 @@ gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b h1:h8qDotaEPuJATrMmW04NCwg7v22aHH28wwpauUhK9Oo=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
honnef.co/go/tools v0.0.0-20180728063816-88497007e858/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
Expand Down
4 changes: 2 additions & 2 deletions packages/ledgerstate/branch_dag.go
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,7 @@ func (b *BranchDAG) ChildBranches(branchID BranchID) (cachedChildBranches Cached
cachedChildBranches = append(cachedChildBranches, &CachedChildBranch{CachedObject: cachedObject})

return true
}, objectstorage.WithPrefix(branchID.Bytes()))
}, objectstorage.WithIteratorPrefix(branchID.Bytes()))

return
}
Expand Down Expand Up @@ -294,7 +294,7 @@ func (b *BranchDAG) ConflictMembers(conflictID ConflictID) (cachedConflictMember
cachedConflictMembers = append(cachedConflictMembers, &CachedConflictMember{CachedObject: cachedObject})

return true
}, objectstorage.WithPrefix(conflictID.Bytes()))
}, objectstorage.WithIteratorPrefix(conflictID.Bytes()))

return
}
Expand Down
4 changes: 2 additions & 2 deletions packages/ledgerstate/utxo_dag.go
Original file line number Diff line number Diff line change
Expand Up @@ -242,7 +242,7 @@ func (u *UTXODAG) Consumers(outputID OutputID) (cachedConsumers CachedConsumers)
cachedConsumers = append(cachedConsumers, &CachedConsumer{CachedObject: cachedObject})

return true
}, objectstorage.WithPrefix(outputID.Bytes()))
}, objectstorage.WithIteratorPrefix(outputID.Bytes()))

return
}
Expand Down Expand Up @@ -299,7 +299,7 @@ func (u *UTXODAG) AddressOutputMapping(address Address) (cachedAddressOutputMapp
u.addressOutputMappingStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool {
cachedAddressOutputMappings = append(cachedAddressOutputMappings, &CachedAddressOutputMapping{cachedObject})
return true
}, objectstorage.WithPrefix(address.Bytes()))
}, objectstorage.WithIteratorPrefix(address.Bytes()))
return
}

Expand Down
4 changes: 2 additions & 2 deletions packages/tangle/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ func (s *Storage) Approvers(messageID MessageID, optionalApproverType ...Approve
s.approverStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool {
cachedApprovers = append(cachedApprovers, &CachedApprover{CachedObject: cachedObject})
return true
}, objectstorage.WithPrefix(iterationPrefix))
}, objectstorage.WithIteratorPrefix(iterationPrefix))

return
}
Expand Down Expand Up @@ -200,7 +200,7 @@ func (s *Storage) Attachments(transactionID ledgerstate.TransactionID) (cachedAt
s.attachmentStorage.ForEach(func(key []byte, cachedObject objectstorage.CachedObject) bool {
cachedAttachments = append(cachedAttachments, &CachedAttachment{CachedObject: cachedObject})
return true
}, objectstorage.WithPrefix(transactionID.Bytes()))
}, objectstorage.WithIteratorPrefix(transactionID.Bytes()))
return
}

Expand Down
95 changes: 15 additions & 80 deletions plugins/autopeering/autopeering.go
Original file line number Diff line number Diff line change
@@ -1,45 +1,29 @@
package autopeering

import (
"errors"
"fmt"
"net"
"strconv"
"strings"
"sync"

"github.com/iotaledger/hive.go/autopeering/discover"
"github.com/iotaledger/hive.go/autopeering/peer"
"github.com/iotaledger/hive.go/autopeering/peer/service"
"github.com/iotaledger/hive.go/autopeering/selection"
"github.com/iotaledger/hive.go/autopeering/server"
"github.com/iotaledger/hive.go/crypto/ed25519"
"github.com/iotaledger/hive.go/identity"
"github.com/iotaledger/hive.go/logger"
"github.com/mr-tron/base58"

"github.com/iotaledger/goshimmer/plugins/autopeering/discovery"
"github.com/iotaledger/goshimmer/plugins/autopeering/local"
"github.com/iotaledger/goshimmer/plugins/config"
)

// autopeering constants
const (
ProtocolVersion = 0 // update on protocol changes
"github.com/iotaledger/goshimmer/plugins/mana"
)

var (
// ErrParsingMasterNode is returned for an invalid master node.
ErrParsingMasterNode = errors.New("cannot parse master node")

// Conn contains the network connection.
Conn *NetConnMetric
)

var (
// the peer discovery protocol
peerDisc *discover.Protocol
peerDiscOnce sync.Once

// the peer selection protocol
peerSel *selection.Protocol
peerSelOnce sync.Once
Expand All @@ -49,16 +33,8 @@ var (
once sync.Once
c chan *server.Server
}{c: make(chan *server.Server, 1)}

networkVersion uint32
)

// Discovery returns the peer discovery instance.
func Discovery() *discover.Protocol {
peerDiscOnce.Do(createPeerDisc)
return peerDisc
}

// Selection returns the neighbor selection instance.
func Selection() *selection.Protocol {
peerSelOnce.Do(createPeerSel)
Expand All @@ -84,29 +60,17 @@ func StartSelection() {
})
}

func createPeerDisc() {
// assure that the logger is available
log := logger.NewLogger(PluginName).Named("disc")

masterPeers, err := parseEntryNodes()
if err != nil {
log.Errorf("Invalid entry nodes; ignoring: %v", err)
}
log.Debugf("Master peers: %v", masterPeers)

peerDisc = discover.New(local.GetInstance(), ProtocolVersion, NetworkVersion(),
discover.Logger(log),
discover.MasterPeers(masterPeers),
)
}

func createPeerSel() {
// assure that the logger is available
log := logger.NewLogger(PluginName).Named("sel")

peerSel = selection.New(local.GetInstance(), Discovery(),
peerSel = selection.New(local.GetInstance(), discovery.Discovery(),
selection.Logger(log),
selection.NeighborValidator(selection.ValidatorFunc(isValidNeighbor)),
selection.UseMana(Parameters.Mana),
selection.ManaFunc(evalMana),
selection.R(Parameters.R),
selection.Ro(Parameters.Ro),
)
}

Expand Down Expand Up @@ -145,11 +109,11 @@ func start(shutdownSignal <-chan struct{}) {
Conn = &NetConnMetric{UDPConn: conn}

// start a server doing peerDisc and peering
srv := server.Serve(lPeer, Conn, log.Named("srv"), Discovery(), Selection())
srv := server.Serve(lPeer, Conn, log.Named("srv"), discovery.Discovery(), Selection())
defer srv.Close()

// start the peer discovery on that connection
Discovery().Start(srv)
discovery.Discovery().Start(srv)
srvBarrier.c <- srv

log.Infof("%s started: ID=%s Address=%s/%s", PluginName, lPeer.ID(), localAddr.String(), localAddr.Network())
Expand All @@ -158,45 +122,16 @@ func start(shutdownSignal <-chan struct{}) {

log.Infof("Stopping %s ...", PluginName)

Discovery().Close()
discovery.Discovery().Close()
Selection().Close()

lPeer.Database().Close()
}

func parseEntryNodes() (result []*peer.Peer, err error) {
for _, entryNodeDefinition := range config.Node().Strings(CfgEntryNodes) {
if entryNodeDefinition == "" {
continue
}

parts := strings.Split(entryNodeDefinition, "@")
if len(parts) != 2 {
return nil, fmt.Errorf("%w: master node parts must be 2, is %d", ErrParsingMasterNode, len(parts))
}
pubKey, err := base58.Decode(parts[0])
if err != nil {
return nil, fmt.Errorf("%w: invalid public key: %s", ErrParsingMasterNode, err)
}
addr, err := net.ResolveUDPAddr("udp", parts[1])
if err != nil {
return nil, fmt.Errorf("%w: host cannot be resolved: %s", ErrParsingMasterNode, err)
}
publicKey, _, err := ed25519.PublicKeyFromBytes(pubKey)
if err != nil {
return nil, err
}

services := service.New()
services.Update(service.PeeringKey, addr.Network(), addr.Port)

result = append(result, peer.NewPeer(identity.New(publicKey), addr.IP, services))
func evalMana(nodeIdentity *identity.Identity) uint64 {
m, _, err := mana.GetConsensusMana(nodeIdentity.ID())
if err != nil {
return 0
}

return result, nil
}

// NetworkVersion returns the network version of the autopeering.
func NetworkVersion() uint32 {
return networkVersion
return uint64(m)
}
101 changes: 101 additions & 0 deletions plugins/autopeering/discovery/discovery.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package discovery

import (
"errors"
"fmt"
"net"
"strings"
"sync"

"github.com/iotaledger/hive.go/autopeering/discover"
"github.com/iotaledger/hive.go/autopeering/peer"
"github.com/iotaledger/hive.go/autopeering/peer/service"
"github.com/iotaledger/hive.go/crypto/ed25519"
"github.com/iotaledger/hive.go/identity"
"github.com/iotaledger/hive.go/logger"
"github.com/mr-tron/base58"

"github.com/iotaledger/goshimmer/plugins/autopeering/local"
)

// autopeering constants
const (
ProtocolVersion = 0 // update on protocol changes

// PluginName is the name of the autopeering plugin.
PluginName = "Autopeering"

entryNodeParts = 2
)

var (
// ErrParsingEntryNode is returned for an invalid entry node.
ErrParsingEntryNode = errors.New("cannot parse entry node")

// the peer discovery protocol
peerDisc *discover.Protocol
peerDiscOnce sync.Once

networkVersion uint32
)

// Discovery returns the peer discovery instance.
func Discovery() *discover.Protocol {
peerDiscOnce.Do(createPeerDisc)
return peerDisc
}

func createPeerDisc() {
// assure that the logger is available
log := logger.NewLogger(PluginName).Named("disc")

networkVersion = uint32(Parameters.NetworkVersion)

entryNodes, err := parseEntryNodes()
if err != nil {
log.Errorf("Invalid entry nodes; ignoring: %v", err)
}
log.Debugf("Entry nodes: %v", entryNodes)

peerDisc = discover.New(local.GetInstance(), ProtocolVersion, NetworkVersion(),
discover.Logger(log),
discover.MasterPeers(entryNodes),
)
}

func parseEntryNodes() (result []*peer.Peer, err error) {
for _, entryNodeDefinition := range Parameters.EntryNodes {
if entryNodeDefinition == "" {
continue
}

parts := strings.Split(entryNodeDefinition, "@")
if len(parts) != entryNodeParts {
return nil, fmt.Errorf("%w: entry node information must contains %d parts, is %d", ErrParsingEntryNode, entryNodeParts, len(parts))
}
pubKey, err := base58.Decode(parts[0])
if err != nil {
return nil, fmt.Errorf("%w: invalid public key: %s", ErrParsingEntryNode, err)
}
addr, err := net.ResolveUDPAddr("udp", parts[1])
if err != nil {
return nil, fmt.Errorf("%w: host cannot be resolved: %s", ErrParsingEntryNode, err)
}
publicKey, _, err := ed25519.PublicKeyFromBytes(pubKey)
if err != nil {
return nil, err
}

services := service.New()
services.Update(service.PeeringKey, addr.Network(), addr.Port)

result = append(result, peer.NewPeer(identity.New(publicKey), addr.IP, services))
}

return result, nil
}

// NetworkVersion returns the network version of the autopeering.
func NetworkVersion() uint32 {
return networkVersion
}
16 changes: 16 additions & 0 deletions plugins/autopeering/discovery/parameters.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package discovery

import "github.com/iotaledger/hive.go/configuration"

// Parameters contains the configuration parameters used by the message layer.
var Parameters = struct {
// NetworkVersion defines the config flag of the network version.
NetworkVersion int `default:"22" usage:"autopeering network version"`

// EntryNodes defines the config flag of the entry nodes.
EntryNodes []string `default:"[email protected]:15626,5EDH4uY78EA6wrBkHHAVBWBMDt7EcksRq6pjzipoW15B@entryshimmer.tanglebay.com:14646" usage:"list of trusted entry nodes for auto peering"`
}{}

func init() {
configuration.BindParameters(&Parameters, "autopeering")
}
Loading

0 comments on commit 94102b2

Please sign in to comment.