Skip to content
Snippets Groups Projects
Commit 249bc066 authored by capossele's avatar capossele
Browse files

:sparkles: adds new autopeering

parent c2d1b2f9
No related branches found
No related tags found
No related merge requests found
Showing
with 357 additions and 131 deletions
......@@ -3,27 +3,27 @@ module github.com/iotaledger/goshimmer
go 1.13
require (
github.com/AndreasBriese/bbloom v0.0.0-20190825152654-46b345b51c96 // indirect
github.com/dgraph-io/badger v1.6.0
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/dgryski/go-farm v0.0.0-20191112170834-c2139c5d712b // indirect
github.com/ethereum/go-ethereum v1.9.3
github.com/gdamore/tcell v1.2.0
github.com/go-zeromq/zmq4 v0.5.0
github.com/golang/protobuf v1.3.2 // indirect
github.com/google/open-location-code/go v0.0.0-20190723034300-2c7115db77a3
github.com/google/open-location-code/go v0.0.0-20190903173953-119bc96a3a51
github.com/gorilla/websocket v1.4.1
github.com/iotaledger/iota.go v1.0.0-beta.7
github.com/kr/pretty v0.1.0 // indirect
github.com/iotaledger/autopeering-sim v0.0.0-20191120103907-203d7715f04c
github.com/iotaledger/hive.go v0.0.0-20191118130432-89eebe8fe8eb
github.com/iotaledger/iota.go v1.0.0-beta.9
github.com/labstack/echo v3.3.10+incompatible
github.com/labstack/gommon v0.3.0 // indirect
github.com/magiconair/properties v1.8.1
github.com/pkg/errors v0.8.1
github.com/rivo/tview v0.0.0-20190829161255-f8bc69b90341
github.com/rivo/uniseg v0.1.0 // indirect
go.uber.org/atomic v1.5.1 // indirect
go.uber.org/multierr v1.4.0 // indirect
go.uber.org/zap v1.13.0 // indirect
golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472
golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297
golang.org/x/sys v0.0.0-20190904154756-749cb33beabd // indirect
golang.org/x/text v0.3.2 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
gopkg.in/zeromq/goczmq.v4 v4.1.0 // indirect
golang.org/x/net v0.0.0-20191119073136-fc4aabc6c914
golang.org/x/sys v0.0.0-20191119195528-f068ffe820e4 // indirect
golang.org/x/tools v0.0.0-20191120001058-ad01d5993d97 // indirect
google.golang.org/grpc v1.21.0
)
This diff is collapsed.
......@@ -3,13 +3,15 @@ package accountability
import (
"sync"
"github.com/iotaledger/goshimmer/packages/database"
"github.com/dgraph-io/badger"
"github.com/iotaledger/goshimmer/packages/identity"
"github.com/iotaledger/goshimmer/packages/settings"
)
var ownId *identity.Identity
// Name of the key under which the node identity is stored.
const identityKey = "IDENTITY"
var ownId *identity.Identity
var lazyInit sync.Once
func OwnId() *identity.Identity {
......@@ -23,13 +25,13 @@ func initOwnId() {
}
func generateNewIdentity() *identity.Identity {
newIdentity := identity.GenerateRandomIdentity()
if err := settings.Set([]byte("ACCOUNTABILITY_PUBLIC_KEY"), newIdentity.PublicKey); err != nil {
panic(err)
}
newIdentity := identity.GeneratePrivateIdentity()
key := []byte(identityKey)
value := newIdentity.Marshal()
if err := settings.Set([]byte("ACCOUNTABILITY_PRIVATE_KEY"), newIdentity.PrivateKey); err != nil {
if err := settings.Set(key, value); err != nil {
panic(err)
}
......@@ -37,23 +39,21 @@ func generateNewIdentity() *identity.Identity {
}
func getIdentity() *identity.Identity {
publicKey, err := settings.Get([]byte("ACCOUNTABILITY_PUBLIC_KEY"))
key := []byte(identityKey)
value, err := settings.Get(key)
if err != nil {
if err == database.ErrKeyNotFound {
if err == badger.ErrKeyNotFound {
return generateNewIdentity()
} else {
panic(err)
}
}
privateKey, err := settings.Get([]byte("ACCOUNTABILITY_PRIVATE_KEY"))
result, err := identity.Unmarshal(value)
if err != nil {
if err == database.ErrKeyNotFound {
return generateNewIdentity()
} else {
panic(err)
}
}
return identity.NewIdentity(publicKey, privateKey)
return result
}
package daemon
import (
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
)
var Events = struct {
......
package identity
import "crypto/ed25519"
const (
PRIVATE_TYPE = IdentityType(0)
PUBLIC_TYPE = IdentityType(1)
IDENTIFIER_BYTE_LENGTH = 20
PUBLIC_KEY_BYTE_LENGTH = ed25519.PublicKeySize
SIGNATURE_BYTE_LENGTH = ed25519.PublicKeySize + ed25519.SignatureSize
MARSHALED_IDENTITY_PUBLIC_KEY_START = 0
MARSHALED_IDENTITY_PRIVATE_KEY_START = MARSHALED_IDENTITY_PUBLIC_KEY_END
MARSHALED_IDENTITY_PUBLIC_KEY_SIZE = PUBLIC_KEY_BYTE_LENGTH
MARSHALED_IDENTITY_PRIVATE_KEY_SIZE = ed25519.PrivateKeySize
MARSHALED_IDENTITY_PUBLIC_KEY_END = MARSHALED_IDENTITY_PUBLIC_KEY_START + MARSHALED_IDENTITY_PUBLIC_KEY_SIZE
MARSHALED_IDENTITY_PRIVATE_KEY_END = MARSHALED_IDENTITY_PRIVATE_KEY_START + MARSHALED_IDENTITY_PRIVATE_KEY_SIZE
PUBLIC_KEY_BYTE_LENGTH = 65
MARSHALED_IDENTITY_TOTAL_SIZE = MARSHALED_IDENTITY_PRIVATE_KEY_END
)
package identity
import "errors"
var (
ErrInvalidDataLen = errors.New("identity: invalid input data length")
ErrInvalidSignature = errors.New("identity: invalid signature")
)
package identity
import (
"crypto/ecdsa"
"crypto/elliptic"
"crypto/rand"
"crypto/ed25519"
"crypto/sha256"
"fmt"
"encoding/hex"
"github.com/ethereum/go-ethereum/crypto/secp256k1"
"github.com/iotaledger/goshimmer/packages/crypto"
"github.com/iotaledger/autopeering-sim/peer"
)
type Identity struct {
Type IdentityType
Identifier []byte
Identifier peer.ID
StringIdentifier string
PublicKey []byte
PrivateKey []byte
PublicKey ed25519.PublicKey
privateKey ed25519.PrivateKey
}
func NewIdentity(publicKey []byte, optionalPrivateKey ...[]byte) *Identity {
this := &Identity{
Identifier: crypto.Hash20(publicKey),
PublicKey: make([]byte, len(publicKey)),
// Creates a new identity based on the given public key.
func NewPublicIdentity(publicKey ed25519.PublicKey) *Identity {
identifier := sha256.Sum256(publicKey)
return &Identity{
Identifier: identifier,
StringIdentifier: hex.EncodeToString(identifier[:8]),
PublicKey: publicKey,
privateKey: nil,
}
}
// Generates a identity based on a newly generated public/private key pair.
// It will panic if no such pair could be generated.
func GeneratePrivateIdentity() *Identity {
publicKey, privateKey, err := ed25519.GenerateKey(nil)
if err != nil {
panic("identity: failed generating key: " + err.Error())
}
return newPrivateIdentity(publicKey, privateKey)
}
copy(this.PublicKey, publicKey)
// Sign signs the message with privateKey and returns the message plus the signature.
func (id *Identity) AddSignature(msg []byte) []byte {
signatureStart := len(msg)
signature := ed25519.Sign(id.privateKey, msg)
data := make([]byte, signatureStart+SIGNATURE_BYTE_LENGTH)
this.StringIdentifier = fmt.Sprintf("%x", this.Identifier)
copy(data[:signatureStart], msg)
if len(optionalPrivateKey) == 1 {
this.Type = PRIVATE_TYPE
this.PrivateKey = optionalPrivateKey[0]
} else {
this.Type = PUBLIC_TYPE
// add public key and signature
copy(data[signatureStart:signatureStart+ed25519.PublicKeySize], id.PublicKey)
copy(data[signatureStart+ed25519.PublicKeySize:], signature)
return data
}
return this
// Verifies whether the data contains a valid signature of the message.
func (id *Identity) VerifySignature(data []byte) error {
signatureStart := len(data) - SIGNATURE_BYTE_LENGTH
if signatureStart <= 0 {
return ErrInvalidDataLen
}
func (this *Identity) Sign(data []byte) ([]byte, error) {
sha256Hasher := sha256.New()
sha256Hasher.Write(data)
msg := data[:signatureStart]
sig, err := secp256k1.Sign(sha256Hasher.Sum(nil), this.PrivateKey)
if err != nil {
return nil, err
// ignore the public key
sig := data[signatureStart+ed25519.PublicKeySize:]
if !ed25519.Verify(id.PublicKey, msg, sig) {
return ErrInvalidSignature
}
return nil
}
return sig, nil
// Returns the identitiy derived from the signed message.
func FromSignedData(data []byte) (*Identity, error) {
signatureStart := len(data) - SIGNATURE_BYTE_LENGTH
if signatureStart <= 0 {
return nil, ErrInvalidDataLen
}
func (this *Identity) VerifySignature(data []byte, signature []byte) bool {
sha256Hasher := sha256.New()
sha256Hasher.Write(data)
pubKey := data[signatureStart : signatureStart+ed25519.PublicKeySize]
return secp256k1.VerifySignature(this.PublicKey, sha256Hasher.Sum(nil), signature[:64])
identity := NewPublicIdentity(pubKey)
if err := identity.VerifySignature(data); err != nil {
return nil, err
}
func GenerateRandomIdentity() *Identity {
// generate key pair
keyPair, err := ecdsa.GenerateKey(secp256k1.S256(), rand.Reader)
if err != nil {
panic(err)
return identity, nil
}
// build public key bytes
publicKey := elliptic.Marshal(secp256k1.S256(), keyPair.X, keyPair.Y)
func (id *Identity) Marshal() []byte {
data := make([]byte, MARSHALED_IDENTITY_TOTAL_SIZE)
// build private key bytes
privkey := make([]byte, 32)
blob := keyPair.D.Bytes()
copy(privkey[32-len(blob):], blob)
copy(data[MARSHALED_IDENTITY_PUBLIC_KEY_START:MARSHALED_IDENTITY_PUBLIC_KEY_END], id.PublicKey)
copy(data[MARSHALED_IDENTITY_PRIVATE_KEY_START:MARSHALED_IDENTITY_PRIVATE_KEY_END], id.privateKey)
return NewIdentity(publicKey, privkey)
return data
}
func FromSignedData(data []byte, signature []byte) (*Identity, error) {
sha256Hasher := sha256.New()
sha256Hasher.Write(data)
func Unmarshal(data []byte) (*Identity, error) {
if len(data) != MARSHALED_IDENTITY_TOTAL_SIZE {
return nil, ErrInvalidDataLen
}
pubKey, err := secp256k1.RecoverPubkey(sha256Hasher.Sum(nil), signature)
if err != nil {
return nil, err
publicKey := data[MARSHALED_IDENTITY_PUBLIC_KEY_START:MARSHALED_IDENTITY_PUBLIC_KEY_END]
privateKey := data[MARSHALED_IDENTITY_PRIVATE_KEY_START:MARSHALED_IDENTITY_PRIVATE_KEY_END]
return newPrivateIdentity(publicKey, privateKey), nil
}
return NewIdentity(pubKey), nil
func newPrivateIdentity(publicKey []byte, privateKey []byte) *Identity {
identity := NewPublicIdentity(publicKey)
identity.privateKey = privateKey
return identity
}
package network
import (
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
)
type BufferedConnectionEvents struct {
......
......@@ -6,7 +6,7 @@ import (
"sync"
"time"
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
)
type ManagedConnection struct {
......
......@@ -5,7 +5,7 @@ import (
"strconv"
"sync"
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/goshimmer/packages/network"
)
......
package tcp
import (
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/goshimmer/packages/network"
)
......
......@@ -3,7 +3,7 @@ package udp
import (
"net"
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
)
type serverEvents struct {
......
......@@ -5,7 +5,7 @@ import (
"strconv"
"sync"
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
)
type Server struct {
......
package node
import (
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
)
type pluginEvents struct {
......
......@@ -4,7 +4,7 @@ import (
"strings"
"sync"
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/goshimmer/packages/parameter"
)
......
package parameter
import (
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
)
var Events = struct {
......
......@@ -4,9 +4,10 @@ import (
"net"
"time"
"github.com/iotaledger/autopeering-sim/discover"
"github.com/iotaledger/autopeering-sim/selection"
"github.com/iotaledger/goshimmer/packages/accountability"
"github.com/iotaledger/goshimmer/packages/daemon"
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/goshimmer/packages/network"
"github.com/iotaledger/goshimmer/packages/node"
"github.com/iotaledger/goshimmer/packages/timeutil"
......@@ -14,10 +15,7 @@ import (
"github.com/iotaledger/goshimmer/plugins/analysis/types/connectnodes"
"github.com/iotaledger/goshimmer/plugins/analysis/types/disconnectnodes"
"github.com/iotaledger/goshimmer/plugins/analysis/types/ping"
"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/types/peer"
"github.com/iotaledger/hive.go/events"
)
func Run(plugin *node.Plugin) {
......@@ -63,7 +61,7 @@ func getEventDispatchers(conn *network.ManagedConnection) *EventDispatchers {
}
func reportCurrentStatus(eventDispatchers *EventDispatchers) {
eventDispatchers.AddNode(accountability.OwnId().Identifier)
eventDispatchers.AddNode(accountability.OwnId().Identifier.Bytes())
reportChosenNeighbors(eventDispatchers)
}
......@@ -71,43 +69,38 @@ func reportCurrentStatus(eventDispatchers *EventDispatchers) {
func setupHooks(conn *network.ManagedConnection, eventDispatchers *EventDispatchers) {
// define hooks ////////////////////////////////////////////////////////////////////////////////////////////////////
onDiscoverPeer := events.NewClosure(func(p *peer.Peer) {
go eventDispatchers.AddNode(p.GetIdentity().Identifier)
onDiscoverPeer := events.NewClosure(func(ev *discover.DiscoveredEvent) {
go eventDispatchers.AddNode(ev.Peer.ID().Bytes())
})
onAddAcceptedNeighbor := events.NewClosure(func(p *peer.Peer) {
eventDispatchers.ConnectNodes(p.GetIdentity().Identifier, accountability.OwnId().Identifier)
onAddAcceptedNeighbor := events.NewClosure(func(ev *selection.PeeringEvent) {
eventDispatchers.ConnectNodes(ev.Peer.ID().Bytes(), accountability.OwnId().Identifier.Bytes())
})
onRemoveAcceptedNeighbor := events.NewClosure(func(p *peer.Peer) {
eventDispatchers.DisconnectNodes(p.GetIdentity().Identifier, accountability.OwnId().Identifier)
onRemoveNeighbor := events.NewClosure(func(ev *selection.DroppedEvent) {
eventDispatchers.DisconnectNodes(ev.DroppedID.Bytes(), accountability.OwnId().Identifier.Bytes())
eventDispatchers.DisconnectNodes(accountability.OwnId().Identifier.Bytes(), ev.DroppedID.Bytes())
})
onAddChosenNeighbor := events.NewClosure(func(p *peer.Peer) {
eventDispatchers.ConnectNodes(accountability.OwnId().Identifier, p.GetIdentity().Identifier)
})
onRemoveChosenNeighbor := events.NewClosure(func(p *peer.Peer) {
eventDispatchers.DisconnectNodes(accountability.OwnId().Identifier, p.GetIdentity().Identifier)
onAddChosenNeighbor := events.NewClosure(func(ev *selection.PeeringEvent) {
eventDispatchers.ConnectNodes(accountability.OwnId().Identifier.Bytes(), ev.Peer.ID().Bytes())
})
// setup hooks /////////////////////////////////////////////////////////////////////////////////////////////////////
knownpeers.INSTANCE.Events.Add.Attach(onDiscoverPeer)
acceptedneighbors.INSTANCE.Events.Add.Attach(onAddAcceptedNeighbor)
acceptedneighbors.INSTANCE.Events.Remove.Attach(onRemoveAcceptedNeighbor)
chosenneighbors.INSTANCE.Events.Add.Attach(onAddChosenNeighbor)
chosenneighbors.INSTANCE.Events.Remove.Attach(onRemoveChosenNeighbor)
discover.Events.PeerDiscovered.Attach(onDiscoverPeer)
selection.Events.IncomingPeering.Attach(onAddAcceptedNeighbor)
selection.Events.OutgoingPeering.Attach(onAddChosenNeighbor)
selection.Events.Dropped.Attach(onRemoveNeighbor)
// clean up hooks on close /////////////////////////////////////////////////////////////////////////////////////////
var onClose *events.Closure
onClose = events.NewClosure(func() {
knownpeers.INSTANCE.Events.Add.Detach(onDiscoverPeer)
acceptedneighbors.INSTANCE.Events.Add.Detach(onAddAcceptedNeighbor)
acceptedneighbors.INSTANCE.Events.Remove.Detach(onRemoveAcceptedNeighbor)
chosenneighbors.INSTANCE.Events.Add.Detach(onAddChosenNeighbor)
chosenneighbors.INSTANCE.Events.Remove.Detach(onRemoveChosenNeighbor)
discover.Events.PeerDiscovered.Detach(onDiscoverPeer)
selection.Events.IncomingPeering.Detach(onAddAcceptedNeighbor)
selection.Events.OutgoingPeering.Detach(onAddChosenNeighbor)
selection.Events.Dropped.Detach(onRemoveNeighbor)
conn.Events.Close.Detach(onClose)
})
......@@ -115,12 +108,12 @@ func setupHooks(conn *network.ManagedConnection, eventDispatchers *EventDispatch
}
func reportChosenNeighbors(dispatchers *EventDispatchers) {
for _, chosenNeighbor := range chosenneighbors.INSTANCE.Peers.GetMap() {
dispatchers.AddNode(chosenNeighbor.GetIdentity().Identifier)
}
for _, chosenNeighbor := range chosenneighbors.INSTANCE.Peers.GetMap() {
dispatchers.ConnectNodes(accountability.OwnId().Identifier, chosenNeighbor.GetIdentity().Identifier)
}
// for _, chosenNeighbor := range chosenneighbors.INSTANCE.Peers.GetMap() {
// dispatchers.AddNode(chosenNeighbor.GetIdentity().Identifier)
// }
// for _, chosenNeighbor := range chosenneighbors.INSTANCE.Peers.GetMap() {
// dispatchers.ConnectNodes(accountability.OwnId().Identifier, chosenNeighbor.GetIdentity().Identifier)
// }
}
func keepConnectionAlive(conn *network.ManagedConnection) bool {
......
......@@ -2,7 +2,7 @@ package analysis
import (
"github.com/iotaledger/goshimmer/packages/daemon"
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/goshimmer/packages/node"
"github.com/iotaledger/goshimmer/plugins/analysis/client"
"github.com/iotaledger/goshimmer/plugins/analysis/server"
......
package server
import (
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
)
var Events = struct {
......
......@@ -6,7 +6,7 @@ import (
"strconv"
"github.com/iotaledger/goshimmer/packages/daemon"
"github.com/iotaledger/goshimmer/packages/events"
"github.com/iotaledger/hive.go/events"
"github.com/iotaledger/goshimmer/packages/network"
"github.com/iotaledger/goshimmer/packages/network/tcp"
"github.com/iotaledger/goshimmer/packages/node"
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment