kademlia

package module
v0.0.0-...-c5e0fec Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 17, 2021 License: MIT Imports: 25 Imported by: 0

README

Kademlia-like

MIT licensed

GitHub Actions status

This is a Go implementation of a Kademlia-like dht using grpc

Currently, This project is experimental. So, I would not recommned using it in production enviroment.

Quick start

package main

import kad "github.com/blackironj/kademlia"

func main() {
	routingTable := kad.NewRoutingTable(
		&kad.Options{
			BucketSize: 10,
			ID:         "your unique id",
			IP:         "127.0.0.1",// your IP 
			Port:       "50051",    // your port number
		})
	// if Options are empty. Set default value

	kadNet := kad.NewKademliaNet(routingTable)

    // if you do not want to bootrap. it's okay to skip this step
    // generate a bootstrap node using node kad.NewNode(id, ip, port)
	bootstrapNodes := []kad.Node{}
	kadNet.Bootstrap(bootstrapNodes)

	kadNet.Start()
}

Documentation

Index

Constants

View Source
const MaxTryConnCount = 3

Variables

View Source
var ErrPeerRejectedNoCapacity = errors.New("peer rejected; insufficient capacity")

Functions

func CommonPrefixLen

func CommonPrefixLen(a, b []byte) int

func ConvertPeerID

func ConvertPeerID(id string) []byte

ConvertPeerID creates a DHT ID by hashing a Peer ID (Multihash)

func GetMyIP

func GetMyIP() (string, error)

func NewKademliaNet

func NewKademliaNet(routingTable *RoutingTable, opt ...KademliaOpt) *kademliaNet

func NewUUIDv4

func NewUUIDv4() string

func RegisterKademliaServiceServer

func RegisterKademliaServiceServer(s *grpc.Server, srv KademliaServiceServer)

func XOR

func XOR(a, b []byte) []byte

Types

type Bucket

type Bucket struct {
	// contains filtered or unexported fields
}

Bucket holds a list of peers.

func (*Bucket) Has

func (b *Bucket) Has(n Node) bool

func (*Bucket) Len

func (b *Bucket) Len() int

func (*Bucket) MoveToFront

func (b *Bucket) MoveToFront(n Node)

func (*Bucket) Nodes

func (b *Bucket) Nodes() []Node

func (*Bucket) PopBack

func (b *Bucket) PopBack() Node

func (*Bucket) PushFront

func (b *Bucket) PushFront(n Node)

func (*Bucket) Remove

func (b *Bucket) Remove(n Node) bool

func (*Bucket) RemoveDeadNodes

func (b *Bucket) RemoveDeadNodes()

func (*Bucket) Split

func (b *Bucket) Split(cpl int, target []byte) *Bucket

Split splits a buckets peers into two buckets, the methods receiver will have peers with CPL equal to cpl, the returned bucket will have peers with CPL greater than cpl (returned bucket has closer peers)

type KademliaOpt

type KademliaOpt struct {
	ParallelismAlpha      int
	ReqFindNodeDeadline   time.Duration
	RefreshBucketInterval time.Duration
}

type KademliaServiceClient

type KademliaServiceClient interface {
	FindNode(ctx context.Context, in *Target, opts ...grpc.CallOption) (*Nodes, error)
}

KademliaServiceClient is the client API for KademliaService service.

For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream.

func NewKademliaServiceClient

func NewKademliaServiceClient(cc *grpc.ClientConn) KademliaServiceClient

type KademliaServiceServer

type KademliaServiceServer interface {
	FindNode(context.Context, *Target) (*Nodes, error)
}

KademliaServiceServer is the server API for KademliaService service.

type Node

type Node struct {
	ID       string
	HashedID []byte

	IP   string
	Port string

	Conn *grpc.ClientConn

	FailedTryConnCount int
}

func NewNode

func NewNode(id, ip, port string) Node

func SortClosestPeers

func SortClosestPeers(peers []Node, target []byte) []Node

Sort the given peers by their ascending distance from the target. A new slice is returned.

func (*Node) IsAlive

func (n *Node) IsAlive() bool

type NodeInfo

type NodeInfo struct {
	Id                   string   `protobuf:"bytes,1,opt,name=id,proto3" json:"id,omitempty"`
	Ip                   string   `protobuf:"bytes,2,opt,name=ip,proto3" json:"ip,omitempty"`
	Port                 string   `protobuf:"bytes,3,opt,name=port,proto3" json:"port,omitempty"`
	XXX_NoUnkeyedLiteral struct{} `json:"-"`
	XXX_unrecognized     []byte   `json:"-"`
	XXX_sizecache        int32    `json:"-"`
}

func (*NodeInfo) Descriptor

func (*NodeInfo) Descriptor() ([]byte, []int)

func (*NodeInfo) GetId

func (m *NodeInfo) GetId() string

func (*NodeInfo) GetIp

func (m *NodeInfo) GetIp() string

func (*NodeInfo) GetPort

func (m *NodeInfo) GetPort() string

func (*NodeInfo) ProtoMessage

func (*NodeInfo) ProtoMessage()

func (*NodeInfo) Reset

func (m *NodeInfo) Reset()

func (*NodeInfo) String

func (m *NodeInfo) String() string

func (*NodeInfo) XXX_DiscardUnknown

func (m *NodeInfo) XXX_DiscardUnknown()

func (*NodeInfo) XXX_Marshal

func (m *NodeInfo) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*NodeInfo) XXX_Merge

func (m *NodeInfo) XXX_Merge(src proto.Message)

func (*NodeInfo) XXX_Size

func (m *NodeInfo) XXX_Size() int

func (*NodeInfo) XXX_Unmarshal

func (m *NodeInfo) XXX_Unmarshal(b []byte) error

type Nodes

type Nodes struct {
	Nodes                []*NodeInfo `protobuf:"bytes,1,rep,name=nodes,proto3" json:"nodes,omitempty"`
	XXX_NoUnkeyedLiteral struct{}    `json:"-"`
	XXX_unrecognized     []byte      `json:"-"`
	XXX_sizecache        int32       `json:"-"`
}

func (*Nodes) Descriptor

func (*Nodes) Descriptor() ([]byte, []int)

func (*Nodes) GetNodes

func (m *Nodes) GetNodes() []*NodeInfo

func (*Nodes) ProtoMessage

func (*Nodes) ProtoMessage()

func (*Nodes) Reset

func (m *Nodes) Reset()

func (*Nodes) String

func (m *Nodes) String() string

func (*Nodes) XXX_DiscardUnknown

func (m *Nodes) XXX_DiscardUnknown()

func (*Nodes) XXX_Marshal

func (m *Nodes) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Nodes) XXX_Merge

func (m *Nodes) XXX_Merge(src proto.Message)

func (*Nodes) XXX_Size

func (m *Nodes) XXX_Size() int

func (*Nodes) XXX_Unmarshal

func (m *Nodes) XXX_Unmarshal(b []byte) error

type Options

type Options struct {
	BucketSize  int
	ID          string
	IP          string
	Port        string
	PeerRemoved func(string)
	PeerAdded   func(string)
}

Options for initialize routing table

type RoutingTable

type RoutingTable struct {

	// kBuckets define all the fingers to other nodes.
	Buckets []*Bucket

	PeerRemoved func(string)
	PeerAdded   func(string)
	// contains filtered or unexported fields
}

RoutingTable defines the routing table.

func NewRoutingTable

func NewRoutingTable(options *Options) *RoutingTable

NewRoutingTable creates a new routing table with a given bucketsize, local ID, and latency tolerance.

func (*RoutingTable) Find

func (rt *RoutingTable) Find(id string) Node

Find a specific peer by ID or return nil

func (*RoutingTable) ListPeers

func (rt *RoutingTable) ListPeers() []Node

ListPeers takes a RoutingTable and returns a list of all peers from all buckets in the table.

func (*RoutingTable) NearestPeer

func (rt *RoutingTable) NearestPeer(hashedID []byte) Node

NearestPeer returns a single peer that is nearest to the given ID

func (*RoutingTable) NearestPeers

func (rt *RoutingTable) NearestPeers(hashedID []byte, count int) []Node

NearestPeers returns a list of the 'count' closest peers to the given ID

func (*RoutingTable) Remove

func (rt *RoutingTable) Remove(n Node)

Remove deletes a peer from the routing table. This is to be used when we are sure a node has disconnected completely.

func (*RoutingTable) RemoveDeadNodes

func (rt *RoutingTable) RemoveDeadNodes()

func (*RoutingTable) Size

func (rt *RoutingTable) Size() int

Size returns the total number of peers in the routing table

func (*RoutingTable) Update

func (rt *RoutingTable) Update(n Node) (err error)

Update adds or moves the given peer to the front of its respective bucket

type Target

type Target struct {
	TargetId             string    `protobuf:"bytes,1,opt,name=target_id,json=targetId,proto3" json:"target_id,omitempty"`
	Sender               *NodeInfo `protobuf:"bytes,2,opt,name=sender,proto3" json:"sender,omitempty"`
	XXX_NoUnkeyedLiteral struct{}  `json:"-"`
	XXX_unrecognized     []byte    `json:"-"`
	XXX_sizecache        int32     `json:"-"`
}

func (*Target) Descriptor

func (*Target) Descriptor() ([]byte, []int)

func (*Target) GetSender

func (m *Target) GetSender() *NodeInfo

func (*Target) GetTargetId

func (m *Target) GetTargetId() string

func (*Target) ProtoMessage

func (*Target) ProtoMessage()

func (*Target) Reset

func (m *Target) Reset()

func (*Target) String

func (m *Target) String() string

func (*Target) XXX_DiscardUnknown

func (m *Target) XXX_DiscardUnknown()

func (*Target) XXX_Marshal

func (m *Target) XXX_Marshal(b []byte, deterministic bool) ([]byte, error)

func (*Target) XXX_Merge

func (m *Target) XXX_Merge(src proto.Message)

func (*Target) XXX_Size

func (m *Target) XXX_Size() int

func (*Target) XXX_Unmarshal

func (m *Target) XXX_Unmarshal(b []byte) error

type UnimplementedKademliaServiceServer

type UnimplementedKademliaServiceServer struct {
}

UnimplementedKademliaServiceServer can be embedded to have forward compatible implementations.

func (*UnimplementedKademliaServiceServer) FindNode

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL