Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Kadcast functional implementation #141

Merged
merged 126 commits into from
Dec 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
126 commits
Select commit Hold shift + click to select a range
c3dace5
Basic first commit.
Nov 6, 2019
a05dd7a
Add gotest.tools to go.mod and go.sum
Nov 8, 2019
da3770f
Implement peer basic managing functions
Nov 8, 2019
79663a0
Refactor `Bucket` structure and define `Tree`
Nov 8, 2019
756fa3d
Implement XOR distance computation utility functions
Nov 8, 2019
85dc560
Set result of `computePeerDistance` as uint16 to hold max range case
Nov 8, 2019
d7eeee1
Refactor `idXor` and `collapseDistance`
Nov 8, 2019
d938a79
Refactor tests according to the `uint16` impl.
Nov 8, 2019
df7f831
Implement ID generation from Wallet Pk
Nov 10, 2019
b7524c1
Finnish Peer ID generation functions
Nov 11, 2019
80e5138
Refactor `ip` field type of Peer
Nov 11, 2019
7cb8dbb
Implement LRU policy on Node storage
Nov 11, 2019
8b4a3c9
Finnish Least Recently Used policy impl
Nov 11, 2019
f1b9a55
Split storage into `Bucket` and `Tree` files
Nov 11, 2019
6179dea
Implement makeTree and addPeer for `Tree`
Nov 11, 2019
3d755a5
Implement peer network info translation functions
Nov 12, 2019
9173784
Implement UDP server and Client for kadcast
Nov 12, 2019
c79568a
Create packet.go file and add `processPacket`
Nov 12, 2019
c9241d6
Implement a way for a peer to get its own UDPAddr
Nov 12, 2019
f680ade
Pass pointers and references intead of values
Nov 13, 2019
5b4308e
Implement Enc/Dec for uint32 <-> bytes
Nov 13, 2019
304c6e8
Refactor `Tree` routing struct and makeTree
Nov 14, 2019
6529e3d
Router creation and Ping impl
Nov 14, 2019
f1e99a1
Implement `PING` & `PONG` messages
Nov 14, 2019
839d9f0
Refactor IDNonce generation
Nov 14, 2019
b790f81
Refactor Peer constructor
Nov 14, 2019
46e62bc
Get Local UDP Addr from func instead of param
Nov 15, 2019
ad0d5e5
Implement Packet type and processPacket
Nov 15, 2019
e5c274f
Refactor peer module to work by-value
Nov 15, 2019
b746a00
Create router module
Nov 15, 2019
8a2a001
Refactor argument passing
Nov 15, 2019
68b7f0d
Implement tests for PoW, byteConv and Ping-Pong
Nov 15, 2019
109a6e0
Add a router as a `StartUDPListener` proc variable
Nov 15, 2019
0d27a94
Fix uint length error
Nov 15, 2019
2f6a2e5
Implement small test to see Go's behaviour w/ UDP
Nov 15, 2019
d464bb7
Implement Nonce & ID verification
Nov 17, 2019
f5fc0f7
Refactor verifyIdNonce function for Peer
Nov 18, 2019
e3fdb65
Implement basic Packet processing functions
Nov 18, 2019
b8c49fd
Small receiving changes
Nov 18, 2019
0074a15
Refactor Bytes-Uint32 pointer returns
Nov 18, 2019
74d0c45
Add destPort to `Packet` headers in the protocol
Nov 18, 2019
dc1fffa
Add listenPort on packet headers creation
Nov 18, 2019
6393abd
Add methods for packet construction
Nov 19, 2019
db65189
Unexport testUDP for Ping/Pong tests
Nov 19, 2019
7822428
Implement PeerSort struct
Nov 19, 2019
9064686
Refactor pointer params and impl `xorIsBigger`
Nov 19, 2019
7d2199f
Implement methods for FIND_NODES usage.
Nov 19, 2019
a0d585e
Solve array access errors in getXClosestPeersTo fn
Nov 20, 2019
8bcfe5b
Implement function for `NODES` payload creation
Nov 20, 2019
1b47847
Implement serialization for `Peer`
Nov 20, 2019
af519a9
Implement methods for send `NODES` messages
Nov 20, 2019
12ee7e1
Implement Se/Deserialization for `Peer` struct
Nov 20, 2019
c98fc73
Implement `NODES` message support functions
Nov 20, 2019
432d508
Implement NODES and FIND_NODES cases.
Nov 20, 2019
7ff2da0
Limit the num of Peers sent on `NODES` message
Nov 21, 2019
8953210
Remove requester peer from Nodes payload
Nov 22, 2019
12df9c3
Refactor FINDNODES to not send requester ID
Nov 23, 2019
0d5f1b0
Refactor getTotalPeers function
Nov 23, 2019
eef1bb8
Implement bootstrapping process triggerer.
Nov 23, 2019
a26a5ed
Implement Network Discovery process.
Nov 24, 2019
8c4b7c8
Add retries in Bootstrapping process.
Nov 24, 2019
2613d5a
Add tests for Bootstrap and Netw Discovery
Nov 24, 2019
5a59e68
Add Dest IP^on message sending logs
Nov 24, 2019
37c4174
Fix LRU policy implementation adding peers to map
Nov 25, 2019
5c7bc86
Refactor the totalPeers computation
Nov 25, 2019
92c3918
Add logs for debugging
Nov 25, 2019
5fbe5d6
Solve InitBootstrap logic.
Nov 25, 2019
6e4b695
Refactor validityCheck of NODES message
Nov 25, 2019
0e32783
Solve some bugs on NODES messages
Nov 26, 2019
9f739da
Add logs to protocol processes.
Nov 26, 2019
0376ec2
Refactor tests to send a reference of the `Router`
Nov 26, 2019
d6dcd4a
Don't send NODES message if PeersAnnounced = 0
Nov 27, 2019
80e6f2b
Set actualClosest node to null at Discovery start
Nov 27, 2019
cfbb81b
Make getNodesPayloadInfo to return announcedPeers
Nov 27, 2019
d199773
Fix network discovery logic
Nov 27, 2019
9a54a72
Parse numPeers as BigEndian
Nov 27, 2019
9bbfd64
Hardcode Bootstrapp node IP on tests
Nov 27, 2019
d21d243
Removing or modifying logs
Nov 27, 2019
d4fa817
Dont export infinit-looping tests
Nov 27, 2019
5866fac
Hold Deadline Hangs recreating the connection.
Nov 27, 2019
a0e3ea0
Remove i condition on getNodesPayloadInfo
Nov 27, 2019
42a6cab
Close connection before goto using a new one.
Nov 27, 2019
1e6b6a3
Add mutex on bucket-changing functions
Nov 27, 2019
03c0242
Return error on Bootstrap failure
Nov 28, 2019
0fcbc9b
Remove unnecessary loops
Nov 28, 2019
d2c791a
Implement Serde for CircularQueue (ring) packets
Nov 28, 2019
420ed5d
Refactor packetProcessing methodology.
Nov 28, 2019
89c8b7b
Refactor PacketProcessing methodology
Nov 28, 2019
27a95c8
Remove Router pointer from UDPList params
Nov 28, 2019
1ce244a
Addapt tests to the sync refactor.
Nov 28, 2019
219b7cc
Remove mutex from Bucket
Nov 28, 2019
3c44128
Send PeerInfo instead of Router to UDPListener
Nov 29, 2019
7c40ab0
Add bootstrapping node to Protocol test.
Nov 29, 2019
2fe502d
Use LittleEndian for number deserialization
Nov 29, 2019
f7949d2
Hold deserialization errors
Nov 29, 2019
ef344c2
Unexport function tests
Nov 29, 2019
68da553
Fix decoding issues. PacketProcessor finnished.
Nov 29, 2019
298a773
Implement TCP connection tools for broadcast
Dec 3, 2019
9d8eb06
Export functions to use them in main.go
Dec 3, 2019
295eb37
Remove cmd folder
Dec 3, 2019
7e3f180
Add main.go file and export peerInf
Dec 3, 2019
22c3cc1
Unexport tests and run main.go now
Dec 3, 2019
208538c
Add doc comments and clear unused logs.
Dec 3, 2019
f66abb3
Implement #141 minor issues changes
Dec 5, 2019
b84854c
Update log to logrus log system
Dec 5, 2019
ae0308d
Reduce Nonce computation complexity
Dec 5, 2019
3c12db1
Refactor bootstrapping to catch the trials err
Dec 5, 2019
ecafdad
Refactor logs for `logrus` use
Dec 5, 2019
be2218d
Implement basic skeleton for WaitGroups
Dec 6, 2019
608cbf1
Addapt main.go gorutines to wG
Dec 6, 2019
e0753c4
Fix typo
Dec 6, 2019
1a2c626
Replace `append` for `copy` in `setHeadersINFO`
Dec 6, 2019
368aff4
Fix wrong byte length for ID
Dec 6, 2019
6d52a44
Remove formatting from INFO logs
Dec 6, 2019
f9f166b
Fix ID verification of refactoring.
Dec 6, 2019
f8dec50
Hold watigroup in Pong arrivals
Dec 6, 2019
a9032c7
Remove global state conditions on PONG handler
Dec 8, 2019
69d1911
Implement poll functions for Router
Dec 8, 2019
00cbaca
Refactor protocol methods to work with poll methds
Dec 8, 2019
b3df49a
Remove WG from main and protocol params
Dec 8, 2019
e3661a2
Refactor contiune loop statements
Dec 8, 2019
bcbbedd
Fix setHeaders bug
Dec 8, 2019
8a8d57c
Modify time.Afterfunc structure
Dec 8, 2019
2f74a69
Reduce waitGroup times to speed up polling
Dec 8, 2019
bdd07a7
Merge pull request #182 from dusk-network/protocol_sync
autholykos Dec 10, 2019
5593b62
Fix err formating errors
Dec 10, 2019
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
44 changes: 44 additions & 0 deletions cmd/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package main
CPerezz marked this conversation as resolved.
Show resolved Hide resolved

import (
log "github.com/sirupsen/logrus"

"github.com/dusk-network/dusk-blockchain/pkg/p2p/kadcast"
"github.com/dusk-network/dusk-blockchain/pkg/util/container/ring"
)

func main() {
CPerezz marked this conversation as resolved.
Show resolved Hide resolved
log.Infoln("Starting Kadcast Node!")
// Our node info.
var port uint16 = 25519
ip := [4]byte{62, 57, 180, 247}
router := kadcast.MakeRouter(ip, port)
log.Infoln("Router was created Successfully.")

// Create buffer.
queue := ring.NewBuffer(500)

// Launch PacketProcessor rutine.
go kadcast.ProcessPacket(queue, &router)

// Launch a listener for our node.
go kadcast.StartUDPListener("udp", queue, router.MyPeerInfo)

// Create BootstrapNodes Peer structs
var port1 uint16 = 25519
ip1 := [4]byte{157, 230, 219, 77}
boot1 := kadcast.MakePeer(ip1, port1)
var bootstrapNodes []kadcast.Peer
bootstrapNodes = append(bootstrapNodes[:], boot1)

// Start Bootstrapping process.
err := kadcast.InitBootstrap(&router, bootstrapNodes)
if err != nil {
log.Panic("Error during the Bootstrap Process. Job terminated.")
}

// Once the bootstrap succeeded, start the network discovery.
kadcast.StartNetworkDiscovery(&router)

select {}
}
1 change: 1 addition & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ require (
golang.org/x/net v0.0.0-20190926025831-c00fd9afed17 // indirect
golang.org/x/sys v0.0.0-20191010194322-b09406accb47 // indirect
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 // indirect
gotest.tools v2.2.0+incompatible
)

go 1.13
4 changes: 4 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ github.com/golang/snappy v0.0.0-20180518054509-2e65f85255db/go.mod h1:/XxbfmMg8l
github.com/golang/snappy v0.0.1 h1:Qgr9rKW7uDUkrbSmQeiDsGa8SjGyCOGtuasMWwvp2P4=
github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.2.0 h1:+dTQ8DZQJz0Mb/HjFlkptS1FeQ4cWSnN941F8aEG4SQ=
github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M=
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ=
github.com/graphql-go/graphql v0.7.8 h1:769CR/2JNAhLG9+aa8pfLkKdR0H+r5lsQqling5WwpU=
Expand Down Expand Up @@ -122,6 +123,7 @@ github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y8
github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk=
github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA=
github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU=
github.com/robpike/ivy v0.0.0-20180326033303-3dd8a2d16657 h1:gKsXF1HCXqryC0W9Y2W4Nw4R/GAPj/SjnsXby0jZ62s=
github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg=
github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo=
github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4=
Expand Down Expand Up @@ -229,4 +231,6 @@ gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
99 changes: 99 additions & 0 deletions pkg/p2p/kadcast/bucket.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package kadcast

// MaxBucketPeers represents the maximum
//number of peers that a `bucket` can hold.
var MaxBucketPeers uint8 = 25

// bucket stores peer info of the peers that are at a certain
// distance range to the peer itself.
type bucket struct {
idLength uint8
peerCount uint8
totalPeersPassed uint64
// Should always be less than `MaxBucketPeers`
entries []Peer
// This map keeps the order of arrivals for LRU
lru map[Peer]uint64
// This map allows us to quickly see if a Peer is
// included on a entries set without iterating over
// it.
lruPresent map[Peer]bool
autholykos marked this conversation as resolved.
Show resolved Hide resolved
}

// Allocates space for a `bucket` and returns a instance
// of it with the specified `idLength`.
func makeBucket(idlen uint8) bucket {
return bucket{
idLength: idlen,
totalPeersPassed: 0,
peerCount: 0,
entries: make([]Peer, 0, MaxBucketPeers),
lru: make(map[Peer]uint64),
lruPresent: make(map[Peer]bool),
}
}

// Finds the Least Recently Used Peer on the entries set
// of the `bucket` and returns it's index on the entries
// set and the `Peer` info that is hold on it.
func (b bucket) findLRUPeerIndex() (int, uint64) {
var val = b.totalPeersPassed
i := 0
for index, p := range b.entries {
if b.lru[p] <= val {
val = b.lru[p]
i = index
}
}
return i, val
}

// Remove a `Peer` from the entries set without
// caring about the order.
// It also maps the `Peer` to false on the LRU map.
// The resulting slice of entries is then returned.
func (b *bucket) removePeerAtIndex(index int) []Peer {
// Remove peer from the lruPresent map.
b.lruPresent[b.entries[index]] = false

b.entries[index] = b.entries[len(b.entries)-1]
// We do not need to put s[i] at the end, as it will be discarded anyway
return b.entries[:len(b.entries)-1]
}

// Adds a `Peer` to the `bucket` entries list.
// It also increments the peerCount all according
// the LRU policy.
func (b *bucket) addPeer(peer Peer) {
// Check if the entries set can hold more peers.
if len(b.entries) < int(MaxBucketPeers) {
// Insert it into the set if not present
// on the current entries set.
if b.lruPresent[peer] == false {
jules marked this conversation as resolved.
Show resolved Hide resolved
b.entries = append(b.entries, peer)
b.peerCount++
b.lruPresent[peer] = true
}
// Store recently used peer.
b.lru[peer] = b.totalPeersPassed
b.totalPeersPassed++
return
}
// If the entries set is full, we perform
// LRU and remove a peer to include the new one.
//
// Check if peer is not already present into the
// entries set
if b.lruPresent[peer] == false {
// Search for the least recently used peer.
var index, _ = b.findLRUPeerIndex()
// Remove it from the entries set and from
// the lruPresent map.
b.entries = b.removePeerAtIndex(index)
// Add the new peer to the entries set.
b.entries = append(b.entries, peer)
b.lruPresent[peer] = true
b.totalPeersPassed++
}
b.lru[peer] = b.totalPeersPassed
}
65 changes: 65 additions & 0 deletions pkg/p2p/kadcast/network.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
package kadcast

import (
log "github.com/sirupsen/logrus"
"net"
"time"

"github.com/dusk-network/dusk-blockchain/pkg/util/container/ring"
)

// StartUDPListener listens infinitely for UDP packet arrivals and
// executes it's processing inside a gorutine by sending
// the packets to the circularQueue.
func StartUDPListener(netw string, queue *ring.Buffer, MyPeerInfo Peer, ) {

lAddr := getLocalUDPAddress()
// Set listening port.
lAddr.Port = int(MyPeerInfo.port)
PacketConnCreation:
// listen to incoming udp packets
pc, err := net.ListenUDP(netw, &lAddr)
if err != nil {
log.Panic(err)
}
// Set initial deadline.
pc.SetDeadline(time.Now().Add(time.Minute))

// Instanciate the buffer
buffer := make([]byte, 1024)
for {
// Read UDP packet.
byteNum, uAddr, err := pc.ReadFromUDP(buffer)

if err != nil {
log.WithError(err).Warn("Error on packet read")
pc.Close()
goto PacketConnCreation
}
// Set a new deadline for the connection.
pc.SetDeadline(time.Now().Add(5 * time.Minute))
// Serialize the packet.
encodedPack := encodeRedPacket(uint16(byteNum), *uAddr, buffer[0:byteNum])
// Send the packet to the Consumer putting it on the queue.
queue.Put(encodedPack)
}
}

// Gets the local address of the sender `Peer` and the UDPAddress of the
// reciever `Peer` and sends to it a UDP Packet with the payload inside.
func sendUDPPacket(netw string, addr net.UDPAddr, payload []byte) {
localAddr := getLocalUDPAddress()
conn, err := net.DialUDP(netw, &localAddr, &addr)
if err != nil {
log.WithError(err).Warn("Could not stablish a connection with the dest Peer.")
return
}
defer conn.Close()

// Simple write
_, err = conn.Write(payload)
if err != nil {
log.WithError(err).Warn("Error while writting to the filedescriptor.")
return
}
}