table

package
v0.0.1 Latest Latest
Warning

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

Go to latest
Published: Nov 2, 2025 License: MIT Imports: 9 Imported by: 0

Documentation

Index

Constants

View Source
const (
	// DefaultMaxActiveNodes is the maximum number of nodes to keep in the active state
	DefaultMaxActiveNodes = 500

	// DefaultPingRate is the maximum number of pings per minute
	DefaultPingRate = 400

	// DefaultSweepPercent is the percentage of active nodes to rotate during sweep
	DefaultSweepPercent = 10
)

FlatTable configuration constants

View Source
const (
	RejectionIPLimit   uint8 = 0x01
	RejectionAdmission uint8 = 0x02
)

Rejection reason flags

View Source
const DefaultMaxFailures = 3

DefaultMaxFailures is the maximum consecutive failures before considering a node dead.

View Source
const DefaultMaxNodeAge = 24 * time.Hour

DefaultMaxNodeAge is the maximum time since last seen before considering a node dead.

View Source
const DefaultMaxNodesPerIP = 10

DefaultMaxNodesPerIP is the default maximum nodes per IP address.

View Source
const DefaultPingInterval = 30 * time.Second

DefaultPingInterval is how often we PING nodes to check liveness.

View Source
const RejectionLogTTL = 12 * time.Hour

RejectionLogTTL is how long we remember that we logged a rejection for a node.

Variables

This section is empty.

Functions

This section is empty.

Types

type DB

type DB interface {
	StoreRejection(id node.ID, reason uint8, timestamp time.Time) error
	LoadRejection(id node.ID) (flags uint8, timestamp time.Time, found bool, err error)
	ExpireRejections(ttl time.Duration) (int, error)
}

DB is the interface for node database that supports rejection tracking.

type FlatTable

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

FlatTable is a flat node storage with capped active nodes.

Unlike the bucket-based Kademlia table, this maintains:

  • All nodes in DB (active and inactive)
  • Capped active nodes in memory (max 500)
  • Distributed ping scheduling
  • Periodic active/inactive rotation

func NewFlatTable

func NewFlatTable(cfg FlatTableConfig) (*FlatTable, error)

NewFlatTable creates a new flat node table.

func (*FlatTable) ActiveSize

func (t *FlatTable) ActiveSize() int

ActiveSize returns the number of active nodes.

func (*FlatTable) Add

func (t *FlatTable) Add(n *node.Node) bool

Add adds a node to the active pool.

This method handles adding nodes to the active in-memory pool with the following strategy: - For nodes that already exist in active pool: updates ENR if newer. - For new nodes: adds to active pool even if over capacity (up to hard limit). - Hard limit: 2x maxActiveNodes. If reached, triggers immediate sweep. - IP limiter is still enforced.

This allows newly discovered nodes (which may not be working) to be added without rejecting them immediately. The next sweep will clean up excess nodes.

DB writes must be handled by caller.

func (*FlatTable) CanAddNodeByIP

func (t *FlatTable) CanAddNodeByIP(n *node.Node) bool

CanAddNodeByIP checks if we can add a node based on IP limits. This checks against all nodes (active + inactive) in the DB.

func (*FlatTable) FindClosestNodes

func (t *FlatTable) FindClosestNodes(target node.ID, k int) []*node.Node

FindClosestNodes finds the k closest active nodes to the target ID.

func (*FlatTable) Get

func (t *FlatTable) Get(nodeID node.ID) *node.Node

Get retrieves a node by ID. First checks active nodes, then falls back to DB.

func (*FlatTable) GetActiveNodes

func (t *FlatTable) GetActiveNodes() []*node.Node

GetActiveNodes returns a copy of all active nodes.

func (*FlatTable) GetBucketNodes

func (t *FlatTable) GetBucketNodes(bucketIndex int) []*node.Node

GetBucketNodes is kept for compatibility but returns empty for flat table.

func (*FlatTable) GetNodesByDistance

func (t *FlatTable) GetNodesByDistance(targetID node.ID, distances []uint, k int) []*node.Node

GetNodesByDistance returns nodes at specific distances with score-weighted random selection.

For each requested distance, it finds all matching nodes and selects up to k nodes with probability weighted by their score (RTT, success rate, fork compatibility).

This ensures:

  • Different results on each call (randomized)
  • Better nodes are returned more frequently (score-weighted)
  • Specific distances are respected

func (*FlatTable) GetNodesNeedingPing

func (t *FlatTable) GetNodesNeedingPing() []*node.Node

GetNodesNeedingPing returns active nodes that need a PING check.

This implements distributed ping scheduling by limiting the number of nodes returned.

func (*FlatTable) GetRandomActiveNodes

func (t *FlatTable) GetRandomActiveNodes(k int) []*node.Node

GetRandomActiveNodes returns up to k random active nodes.

func (*FlatTable) GetStats

func (t *FlatTable) GetStats() TableStats

GetStats returns statistics about the table.

func (*FlatTable) LoadInitialNodesFromDB

func (t *FlatTable) LoadInitialNodesFromDB() error

LoadInitialNodesFromDB loads random nodes from DB into the active pool.

func (*FlatTable) NumBucketsFilled

func (t *FlatTable) NumBucketsFilled() int

NumBucketsFilled returns a compatibility value for the flat table. Since we don't have buckets, we return 1 if we have any active nodes, 0 otherwise.

func (*FlatTable) PerformSweep

func (t *FlatTable) PerformSweep()

PerformSweep rotates nodes between active and inactive pools.

This should be called periodically (e.g., every 10 minutes). Only demotes nodes when over capacity. When at or under capacity, nodes are kept to allow newly discovered nodes to be tested before being demoted. Loads inactive nodes from DB and tries to promote them to fill available slots.

func (*FlatTable) SetForkScoringInfo

func (t *FlatTable) SetForkScoringInfo(info *node.ForkScoringInfo)

SetForkScoringInfo updates the fork scoring information used for node ranking. This should be called periodically to reflect fork changes.

func (*FlatTable) Size

func (t *FlatTable) Size() int

Size returns the total number of nodes (active + inactive).

type FlatTableConfig

type FlatTableConfig struct {
	// LocalID is our node ID
	LocalID node.ID

	// DB is the primary node storage
	DB *nodedb.NodeDB

	// MaxActiveNodes is the maximum number of active nodes (default 500)
	MaxActiveNodes int

	// MaxNodesPerIP is the maximum nodes allowed per IP address
	MaxNodesPerIP int

	// PingInterval is how often to ping nodes
	PingInterval time.Duration

	// PingRate is maximum pings per minute (default 400)
	PingRate int

	// MaxNodeAge is the maximum time since last seen
	MaxNodeAge time.Duration

	// MaxFailures is the maximum consecutive failures
	MaxFailures int

	// SweepPercent is percentage of nodes to rotate during sweep (default 10%)
	SweepPercent int

	// NodeChangedCallback is called when a node is added or updated
	NodeChangedCallback NodeChangedCallback

	// Logger for debug messages
	Logger logrus.FieldLogger
}

FlatTableConfig contains configuration for the flat table.

type IPLimiter

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

IPLimiter tracks and enforces per-IP node limits.

This prevents sybil attacks where an attacker tries to fill the routing table with many nodes from the same IP address.

func NewIPLimiter

func NewIPLimiter(maxNodesPerIP int) *IPLimiter

NewIPLimiter creates a new IP limiter.

Parameters:

  • maxNodesPerIP: Maximum nodes allowed per IP (0 = unlimited)

func (*IPLimiter) Add

func (l *IPLimiter) Add(n *node.Node) bool

Add registers a node with the IP limiter.

This should be called when a node is added to the routing table. Returns false if the IP limit is exceeded.

func (*IPLimiter) CanAdd

func (l *IPLimiter) CanAdd(n *node.Node) bool

CanAdd checks if a node can be added without exceeding IP limits.

Returns true if the node can be added, false if the IP limit is exceeded.

func (*IPLimiter) GetNodeCountForIP

func (l *IPLimiter) GetNodeCountForIP(ip net.IP) int

GetNodeCountForIP returns the number of nodes for a given IP.

func (*IPLimiter) GetStats

func (l *IPLimiter) GetStats() IPStats

GetStats returns detailed statistics about IP distribution.

func (*IPLimiter) GetTotalRejections

func (l *IPLimiter) GetTotalRejections() int

GetTotalRejections returns the total number of rejected nodes due to IP limits.

func (*IPLimiter) Remove

func (l *IPLimiter) Remove(nodeID node.ID)

Remove unregisters a node from the IP limiter.

This should be called when a node is removed from the routing table.

type IPStats

type IPStats struct {
	UniqueIPs      int
	TotalNodes     int
	MaxNodesPerIP  int
	Rejections     int
	IPDistribution map[string]int // IP -> node count
}

GetStats returns statistics about IP usage.

type NodeChangedCallback

type NodeChangedCallback func(*node.Node)

NodeChangedCallback is called when a node is added or updated in the table.

type TableStats

type TableStats struct {
	TotalNodes          int
	ActiveNodes         int
	BucketsFilled       int
	AdmissionRejections int
	IPLimitRejections   int
	DeadNodesRemoved    int
	IPStats             IPStats
}

TableStats contains statistics about the routing table.

Jump to

Keyboard shortcuts

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