Files
core/dht/Node.go
Akilan Selvacoumar ae5f1d2fd7 New features (#110)
* added upload status

* added changes for progress bar with more logs and bug fixes, Documentation yet to be added

* huge changes that need more doucmenting

* added possibility to get profile using NodeID

* added fix profile listing user profile information

* removed profile image from the explore reult struct

* saving current changes

* added filter to search based on NodeID

* Monday bug fixing

* updates to the profile

* changes for tracing the blockchain profile image not shown

* added condition to ensure TAG is not sent and removed debug prints

* updated webapi docs
2023-06-28 00:38:17 +01:00

134 lines
2.9 KiB
Go

/*
File Username: Node.go
Copyright: 2021 Peernet s.r.o.
Author: Peter Kleissner
*/
package dht
import (
"bytes"
"math/big"
"time"
)
// Node is the over-the-wire representation of a node
type Node struct {
// ID is the unique identifier
ID []byte
// LastSeen when was this node last considered seen by the DHT
LastSeen time.Time
// Info is an arbitrary pointer specified by the caller
Info interface{}
}
// shortList is used in order to sort a list of arbitrary nodes against a comparator. These nodes are sorted by xor distance
type shortList struct {
// Nodes are a list of nodes to be compared
Nodes []*Node
// Comparator is the ID to compare to
Comparator []byte
// Contacted is a list of nodes that are considered contacted
Contacted map[string]bool
}
func newShortList() *shortList {
return &shortList{
Contacted: make(map[string]bool),
}
}
func areNodesEqual(n1 *Node, n2 *Node, allowNilID bool) bool {
if n1 == nil || n2 == nil {
return false
}
if !allowNilID {
if n1.ID == nil || n2.ID == nil {
return false
}
if bytes.Compare(n1.ID, n2.ID) != 0 {
return false
}
}
return true
}
func (n *shortList) RemoveNode(ID []byte) {
for i := 0; i < n.Len(); i++ {
if bytes.Compare(n.Nodes[i].ID, ID) == 0 {
n.Nodes = append(n.Nodes[:i], n.Nodes[i+1:]...)
return
}
}
}
func (n *shortList) AppendUniqueNodes(nodes ...*Node) {
nodesLoop:
for _, vv := range nodes {
for _, v := range n.Nodes {
if bytes.Compare(v.ID, vv.ID) == 0 {
continue nodesLoop
}
}
n.Nodes = append(n.Nodes, vv)
}
}
func (n *shortList) Len() int {
return len(n.Nodes)
}
func (n *shortList) Swap(i, j int) {
n.Nodes[i], n.Nodes[j] = n.Nodes[j], n.Nodes[i]
}
func (n *shortList) Less(i, j int) bool {
iDist := getDistance(n.Nodes[i].ID, n.Comparator)
jDist := getDistance(n.Nodes[j].ID, n.Comparator)
return iDist.Cmp(jDist) == -1
}
func getDistance(id1 []byte, id2 []byte) *big.Int {
buf1 := new(big.Int).SetBytes(id1)
buf2 := new(big.Int).SetBytes(id2)
result := new(big.Int).Xor(buf1, buf2)
return result
}
// GetUncontacted returns a list of uncontacted nodes. Each returned node will be marked as contacted.
func (n *shortList) GetUncontacted(count int, useCount bool) (Nodes []*Node) {
for _, node := range n.Nodes {
if useCount && count <= 0 {
break
}
// Don't contact nodes already contacted
if n.Contacted[string(node.ID)] == true {
continue
}
n.Contacted[string(node.ID)] = true
Nodes = append(Nodes, node)
count--
}
return Nodes
}
// NodeMessage is a message sent by a node
type NodeMessage struct {
SenderID []byte // Sender of the message
Data []byte // FIND_VALUE: Actual data
Closest []*Node // FIND_VALUE, FIND_NODE: Closest nodes to the requested key
Storing []*Node // FIND_VALUE: Nodes known to store the value
}
// NodeFilterFunc is called to filter nodes based on the callers choice
type NodeFilterFunc func(node *Node) (accept bool)