## Overview
The DHT (Distributed Hash Table) module implements a Kademlia-based distributed hash table system for efficient peer discovery, data distribution, and network topology management in the Cellframe blockchain network. This module provides scalable, decentralized storage and retrieval mechanisms essential for P2P network operations.
**Based on:** `dap_chain_dht.h`, `dap_chain_dht.c`
## Document Structure
- [[#Overview|Overview]]
- [[#Module Structures|Module Structures]]
- [[#dap_dht_t|dap_dht_t - Core DHT instance structure]]
- [[#dap_dht_node_t|dap_dht_node_t - DHT network node representation]]
- [[#dap_dht_key_t|dap_dht_key_t - DHT key structure for storage operations]]
- [[#dap_dht_bucket_t|dap_dht_bucket_t - Routing table bucket structure]]
- [[#dap_dht_state_t|dap_dht_state_t - DHT operational states]]
- [[#Module Functions|Module Functions]]
- [[#Initialization Functions|Initialization Functions]]
- [[#Node Management Functions|Node Management Functions]]
- [[#Data Storage Functions|Data Storage Functions]]
- [[#Network Discovery Functions|Network Discovery Functions]]
- [[#Routing Functions|Routing Functions]]
- [[#Error Codes|Error Codes]]
- [[#Typical Examples|Typical Examples]]
## Module Structures
### dap_dht_t
Core DHT instance containing routing table, storage, and network configuration.
```c
typedef struct dap_dht {
struct {
dap_chain_net_t *net; // Associated network
dap_chain_node_addr_t *node_addr; // Local node address
uint16_t port; // DHT service port
uint32_t bucket_size; // K-bucket size (default: 20)
uint32_t alpha; // Concurrency parameter (default: 3)
bool enabled; // DHT service status
} pub;
// Private fields
dap_dht_bucket_t *routing_table[DHT_KEY_SIZE_BITS]; // Kademlia routing table
dap_hashtable_t *storage; // Local data storage
dap_list_t *pending_requests; // Pending network requests
pthread_rwlock_t rwlock; // Thread synchronization
dap_timer_t *maintenance_timer; // Routing table maintenance
} dap_dht_t;
```
**Public Fields:**
- `net` - Blockchain network associated with this DHT instance
- `node_addr` - Local node address for DHT identification
- `port` - Network port for DHT communication
- `bucket_size` - Maximum nodes per K-bucket (Kademlia parameter)
- `alpha` - Concurrency level for parallel requests
- `enabled` - Current operational status of DHT service
### dap_dht_node_t
Network node representation in the DHT with contact information and metrics.
```c
typedef struct dap_dht_node {
struct {
dap_chain_node_addr_t addr; // Node network address
dap_chain_node_info_t info; // Node information
uint64_t last_seen; // Last contact timestamp
uint32_t response_time_ms; // Average response time
uint16_t reliability_score; // Node reliability (0-1000)
bool is_good; // Node quality flag
} pub;
// Distance calculation cache
dap_dht_key_t distance_cache; // XOR distance to local node
uint32_t bucket_index; // Routing table bucket index
dap_list_t *pending_pings; // Pending ping requests
} dap_dht_node_t;
```
**Public Fields:**
- `addr` - Network address including IP and port information
- `info` - Node metadata including capabilities and version
- `last_seen` - Unix timestamp of last successful communication
- `response_time_ms` - Rolling average response time for performance tracking
- `reliability_score` - Calculated reliability score (0-1000 scale)
- `is_good` - Boolean flag indicating if node meets quality thresholds
### dap_dht_key_t
DHT key structure for storage and lookup operations with XOR distance calculations.
```c
typedef struct dap_dht_key {
struct {
uint8_t raw[DHT_KEY_SIZE_BYTES]; // Raw key bytes (32 bytes)
char *str_repr; // String representation
uint32_t prefix_length; // Significant prefix length
} pub;
// Precomputed values for optimization
uint32_t hash_cache; // Hash value cache
uint8_t leading_zeros; // Leading zero bits count
} dap_dht_key_t;
```
**Public Fields:**
- `raw` - 256-bit key data for DHT operations
- `str_repr` - Hexadecimal string representation for debugging
- `prefix_length` - Number of significant bits in key prefix
### dap_dht_bucket_t
Routing table bucket implementing Kademlia K-bucket with node management.
```c
typedef struct dap_dht_bucket {
struct {
dap_list_t *nodes; // List of nodes in bucket
uint32_t node_count; // Current node count
uint64_t last_update; // Last bucket update time
uint32_t prefix_length; // Bucket prefix length
} pub;
// Bucket management
dap_list_t *replacement_cache; // Replacement node cache
pthread_mutex_t mutex; // Bucket synchronization
dap_timer_t *refresh_timer; // Bucket refresh timer
} dap_dht_bucket_t;
```
**Public Fields:**
- `nodes` - Linked list of active nodes in this bucket
- `node_count` - Current number of nodes (max: bucket_size)
- `last_update` - Timestamp of last bucket modification
- `prefix_length` - Common prefix length for bucket range
### dap_dht_state_t
DHT operational states for lifecycle and error management.
```c
typedef enum dap_dht_state {
DHT_STATE_UNINITIALIZED = 0, // Not initialized
DHT_STATE_INITIALIZING, // Initialization in progress
DHT_STATE_BOOTSTRAPPING, // Bootstrap phase
DHT_STATE_ACTIVE, // Normal operation
DHT_STATE_MAINTENANCE, // Maintenance mode
DHT_STATE_ERROR, // Error state
DHT_STATE_SHUTDOWN // Shutdown in progress
} dap_dht_state_t;
```
**State Transitions:**
- `UNINITIALIZED` → `INITIALIZING` - Start initialization
- `INITIALIZING` → `BOOTSTRAPPING` - Begin network bootstrap
- `BOOTSTRAPPING` → `ACTIVE` - Normal operations begin
- `ACTIVE` → `MAINTENANCE` - Scheduled maintenance
- `ANY` → `ERROR` - Error condition detected
## Module Functions
### Initialization Functions
#### `dap_dht_init()`
Initialize DHT module with network configuration and routing table setup.
```c
int dap_dht_init(void);
```
**Returns:**
- `0` - Success, DHT module initialized
- `-1` - Initialization failed
- `-ENOMEM` - Insufficient memory for DHT structures
**Error Conditions:**
- Returns `-1` if network subsystem not initialized
- Returns `-ENOMEM` if memory allocation fails
**Description:** Initializes the global DHT module, sets up routing table structures, and prepares the DHT subsystem for network operations. Must be called before any other DHT functions.
#### `dap_dht_create()`
Create new DHT instance for specified network with custom configuration.
```c
dap_dht_t* dap_dht_create(dap_chain_net_t *net, const dap_dht_config_t *config);
```
**Parameters:**
- `net` (dap_chain_net_t*) - Target blockchain network
- `config` (dap_dht_config_t*) - DHT configuration parameters
**Returns:**
- `dap_dht_t*` - DHT instance pointer on success
- `NULL` - Creation failed
**Error Conditions:**
- Returns `NULL` if network parameter is invalid
- Returns `NULL` if configuration validation fails
**Description:** Creates and configures a new DHT instance for the specified network with custom parameters including bucket size, concurrency level, and maintenance intervals.
#### `dap_dht_start()`
Start DHT operations including bootstrap and routing table population.
```c
int dap_dht_start(dap_dht_t *dht);
```
**Parameters:**
- `dht` (dap_dht_t*) - DHT instance to start
**Returns:**
- `0` - DHT started successfully
- `-1` - Start operation failed
- `-EALREADY` - DHT already running
**Error Conditions:**
- Returns `-1` if DHT instance is invalid
- Returns `-EALREADY` if DHT is already in active state
**Description:** Initiates DHT operations by starting the bootstrap process, enabling routing table maintenance, and beginning peer discovery operations.
### Node Management Functions
#### `dap_dht_node_add()`
Add node to DHT routing table with distance calculation and bucket placement.
```c
int dap_dht_node_add(dap_dht_t *dht, const dap_chain_node_addr_t *node_addr);
```
**Parameters:**
- `dht` (dap_dht_t*) - DHT instance
- `node_addr` (dap_chain_node_addr_t*) - Node address to add
**Returns:**
- `0` - Node added successfully
- `-1` - Addition failed
- `-EEXIST` - Node already exists in routing table
**Error Conditions:**
- Returns `-1` if DHT or node_addr is NULL
- Returns `-EEXIST` if node already present in routing table
**Description:** Adds a new node to the DHT routing table by calculating XOR distance, determining appropriate K-bucket, and managing bucket capacity according to Kademlia protocol.
#### `dap_dht_node_remove()`
Remove node from DHT routing table and update bucket structure.
```c
int dap_dht_node_remove(dap_dht_t *dht, const dap_chain_node_addr_t *node_addr);
```
**Parameters:**
- `dht` (dap_dht_t*) - DHT instance
- `node_addr` (dap_chain_node_addr_t*) - Node address to remove
**Returns:**
- `0` - Node removed successfully
- `-1` - Removal failed
- `-ENOENT` - Node not found in routing table
**Error Conditions:**
- Returns `-1` if parameters are invalid
- Returns `-ENOENT` if node not present in routing table
**Description:** Removes a node from the DHT routing table, updates bucket structures, and promotes replacement nodes from cache if available.
#### `dap_dht_node_ping()`
Send ping request to node for liveness check and RTT measurement.
```c
int dap_dht_node_ping(dap_dht_t *dht, dap_dht_node_t *node);
```
**Parameters:**
- `dht` (dap_dht_t*) - DHT instance
- `node` (dap_dht_node_t*) - Target node to ping
**Returns:**
- `0` - Ping sent successfully
- `-1` - Ping failed to send
- `-ETIMEDOUT` - Previous ping still pending
**Error Conditions:**
- Returns `-1` if node is unreachable
- Returns `-ETIMEDOUT` if too many pending pings
**Description:** Sends a ping message to the specified node to verify liveness, measure response time, and update node reliability metrics.
### Data Storage Functions
#### `dap_dht_store()`
Store key-value pair in DHT with replication to closest nodes.
```c
int dap_dht_store(dap_dht_t *dht, const dap_dht_key_t *key, const void *data, size_t data_size);
```
**Parameters:**
- `dht` (dap_dht_t*) - DHT instance
- `key` (dap_dht_key_t*) - Storage key
- `data` (void*) - Data to store
- `data_size` (size_t) - Size of data in bytes
**Returns:**
- `0` - Data stored successfully
- `-1` - Storage operation failed
- `-ENOMEM` - Insufficient memory
- `-ENOSPC` - Storage capacity exceeded
**Error Conditions:**
- Returns `-1` if key or data is invalid
- Returns `-ENOMEM` if memory allocation fails for data copy
- Returns `-ENOSPC` if local storage quota exceeded
**Description:** Stores data in the DHT by finding the k closest nodes to the key and replicating the data across multiple nodes for fault tolerance.
#### `dap_dht_retrieve()`
Retrieve data from DHT by key with automatic node discovery.
```c
int dap_dht_retrieve(dap_dht_t *dht, const dap_dht_key_t *key, void **data, size_t *data_size);
```
**Parameters:**
- `dht` (dap_dht_t*) - DHT instance
- `key` (dap_dht_key_t*) - Lookup key
- `data` (void**) - Output pointer for retrieved data
- `data_size` (size_t*) - Output pointer for data size
**Returns:**
- `0` - Data retrieved successfully
- `-1` - Retrieval failed
- `-ENOENT` - Key not found in DHT
- `-ETIMEDOUT` - Lookup timeout
**Error Conditions:**
- Returns `-1` if parameters are invalid
- Returns `-ENOENT` if key not found after exhaustive search
- Returns `-ETIMEDOUT` if lookup exceeds maximum time limit
**Description:** Retrieves data from the DHT by performing iterative lookup to find nodes closest to the key and requesting data from multiple sources for verification.
### Network Discovery Functions
#### `dap_dht_find_nodes()`
Find k closest nodes to target key using iterative lookup algorithm.
```c
int dap_dht_find_nodes(dap_dht_t *dht, const dap_dht_key_t *target, dap_list_t **nodes);
```
**Parameters:**
- `dht` (dap_dht_t*) - DHT instance
- `target` (dap_dht_key_t*) - Target key for lookup
- `nodes` (dap_list_t**) - Output list of closest nodes
**Returns:**
- `0` - Lookup completed successfully
- `-1` - Lookup failed
- `-ETIMEDOUT` - Lookup timeout
- `-ENOMEM` - Memory allocation failed
**Error Conditions:**
- Returns `-1` if DHT state is not active
- Returns `-ETIMEDOUT` if iterative lookup exceeds time limit
- Returns `-ENOMEM` if node list allocation fails
**Description:** Performs Kademlia iterative lookup to find the k nodes closest to the target key, used for both data storage and retrieval operations.
#### `dap_dht_bootstrap()`
Bootstrap DHT by connecting to initial seed nodes and populating routing table.
```c
int dap_dht_bootstrap(dap_dht_t *dht, const dap_list_t *seed_nodes);
```
**Parameters:**
- `dht` (dap_dht_t*) - DHT instance to bootstrap
- `seed_nodes` (dap_list_t*) - List of initial seed nodes
**Returns:**
- `0` - Bootstrap completed successfully
- `-1` - Bootstrap failed
- `-ENOENT` - No responsive seed nodes found
- `-ETIMEDOUT` - Bootstrap timeout
**Error Conditions:**
- Returns `-1` if DHT instance is invalid
- Returns `-ENOENT` if all seed nodes are unreachable
- Returns `-ETIMEDOUT` if bootstrap process exceeds time limit
**Description:** Initiates DHT bootstrap process by connecting to seed nodes, performing self-lookup to populate routing table, and establishing initial network presence.
### Routing Functions
#### `dap_dht_get_bucket()`
Get routing table bucket for specified key with distance calculation.
```c
dap_dht_bucket_t* dap_dht_get_bucket(dap_dht_t *dht, const dap_dht_key_t *key);
```
**Parameters:**
- `dht` (dap_dht_t*) - DHT instance
- `key` (dap_dht_key_t*) - Key to find bucket for
**Returns:**
- `dap_dht_bucket_t*` - Appropriate bucket pointer
- `NULL` - Bucket lookup failed
**Error Conditions:**
- Returns `NULL` if parameters are invalid
- Returns `NULL` if bucket index calculation fails
**Description:** Calculates the appropriate K-bucket for a given key by determining XOR distance from local node ID and returning the corresponding routing table bucket.
#### `dap_dht_calculate_distance()`
Calculate XOR distance between two DHT keys for routing decisions.
```c
void dap_dht_calculate_distance(const dap_dht_key_t *key1, const dap_dht_key_t *key2, dap_dht_key_t *distance);
```
**Parameters:**
- `key1` (dap_dht_key_t*) - First key
- `key2` (dap_dht_key_t*) - Second key
- `distance` (dap_dht_key_t*) - Output distance result
**Returns:**
- `void` - Distance stored in output parameter
**Error Conditions:**
- No error conditions - function always succeeds with valid parameters
**Description:** Computes XOR distance between two DHT keys, which is fundamental to Kademlia routing decisions and bucket placement calculations.
## Error Codes
### DHT Error Codes
```c
typedef enum dap_dht_error {
DAP_DHT_ERROR_SUCCESS = 0, // Operation successful
DAP_DHT_ERROR_INVALID_PARAM = -1, // Invalid parameter
DAP_DHT_ERROR_NOT_INITIALIZED = -2, // DHT not initialized
DAP_DHT_ERROR_ALREADY_RUNNING = -3, // DHT already active
DAP_DHT_ERROR_NETWORK_FAILURE = -4, // Network communication failed
DAP_DHT_ERROR_TIMEOUT = -5, // Operation timeout
DAP_DHT_ERROR_NOT_FOUND = -6, // Key/node not found
DAP_DHT_ERROR_STORAGE_FULL = -7, // Storage capacity exceeded
DAP_DHT_ERROR_INVALID_KEY = -8, // Invalid DHT key format
DAP_DHT_ERROR_ROUTING_FAILED = -9 // Routing table operation failed
} dap_dht_error_t;
```
### DHT Configuration Constants
```c
// DHT operational parameters
#define DHT_KEY_SIZE_BITS 256 // Key size in bits
#define DHT_KEY_SIZE_BYTES 32 // Key size in bytes
#define DHT_DEFAULT_BUCKET_SIZE 20 // Default K-bucket size
#define DHT_DEFAULT_ALPHA 3 // Default concurrency
#define DHT_MAX_DATA_SIZE (64*1024) // Maximum data size (64KB)
#define DHT_BOOTSTRAP_TIMEOUT_SEC 30 // Bootstrap timeout
#define DHT_LOOKUP_TIMEOUT_SEC 10 // Lookup timeout
#define DHT_MAINTENANCE_INTERVAL 300 // Maintenance interval (5 min)
```
## Typical Examples
### Example 1: DHT Initialization and Startup
```c
#include "dap_chain_dht.h"
#include "dap_common.h"
int initialize_dht_service(dap_chain_net_t *network) {
log_it(L_INFO, "=== Initializing DHT Service ===");
// Initialize DHT module globally
int result = dap_dht_init();
if (result != 0) {
log_it(L_ERROR, "Failed to initialize DHT module: %d", result);
return -1;
}
// Create DHT configuration
dap_dht_config_t config = {
.bucket_size = DHT_DEFAULT_BUCKET_SIZE,
.alpha = DHT_DEFAULT_ALPHA,
.port = 8079,
.maintenance_interval = DHT_MAINTENANCE_INTERVAL,
.enable_storage = true,
.max_storage_size = 100 * 1024 * 1024 // 100MB
};
// Create DHT instance for network
dap_dht_t *dht = dap_dht_create(network, &config);
if (!dht) {
log_it(L_ERROR, "Failed to create DHT instance");
return -1;
}
// Prepare seed nodes for bootstrap
dap_list_t *seed_nodes = NULL;
// Add seed nodes from configuration
const char *seed_addrs[] = {
"192.168.1.100:8079",
"10.0.0.50:8079",
"bootstrap.cellframe.net:8079"
};
for (size_t i = 0; i < sizeof(seed_addrs) / sizeof(seed_addrs[0]); i++) {
dap_chain_node_addr_t *seed_addr = dap_chain_node_addr_from_str(seed_addrs[i]);
if (seed_addr) {
seed_nodes = dap_list_append(seed_nodes, seed_addr);
log_it(L_INFO, "Added seed node: %s", seed_addrs[i]);
}
}
// Start DHT with bootstrap
result = dap_dht_start(dht);
if (result != 0) {
log_it(L_ERROR, "Failed to start DHT: %d", result);
dap_list_free(seed_nodes);
return -1;
}
// Perform bootstrap
result = dap_dht_bootstrap(dht, seed_nodes);
if (result != 0) {
log_it(L_WARNING, "DHT bootstrap completed with warnings: %d", result);
} else {
log_it(L_INFO, "✓ DHT bootstrap completed successfully");
}
// Cleanup seed nodes list
dap_list_free_full(seed_nodes, (dap_callback_destroyed_t)DAP_DELETE);
log_it(L_INFO, "✓ DHT service initialized and running");
return 0;
}
```
### Example 2: Data Storage and Retrieval
```c
#include "dap_chain_dht.h"
#include "dap_common.h"
int dht_data_operations_example(dap_dht_t *dht) {
log_it(L_INFO, "=== DHT Data Operations Example ===");
// Create storage key from data hash
const char *data_content = "Important blockchain data";
size_t data_size = strlen(data_content);
dap_dht_key_t storage_key = {0};
dap_hash_fast(data_content, data_size, (dap_hash_fast_t*)&storage_key);
// Convert key to string for logging
char *key_str = dap_dht_key_to_str(&storage_key);
log_it(L_INFO, "Storage key: %s", key_str);
// Store data in DHT
int result = dap_dht_store(dht, &storage_key, data_content, data_size);
if (result != 0) {
log_it(L_ERROR, "Failed to store data in DHT: %d", result);
DAP_DELETE(key_str);
return -1;
}
log_it(L_INFO, "✓ Data stored successfully in DHT");
// Wait for replication to complete
sleep(2);
// Retrieve data from DHT
void *retrieved_data = NULL;
size_t retrieved_size = 0;
result = dap_dht_retrieve(dht, &storage_key, &retrieved_data, &retrieved_size);
if (result != 0) {
log_it(L_ERROR, "Failed to retrieve data from DHT: %d", result);
DAP_DELETE(key_str);
return -1;
}
// Verify retrieved data
if (retrieved_size != data_size ||
memcmp(retrieved_data, data_content, data_size) != 0) {
log_it(L_ERROR, "Retrieved data doesn't match original");
DAP_DELETE(retrieved_data);
DAP_DELETE(key_str);
return -1;
}
log_it(L_INFO, "✓ Data retrieved and verified successfully");
log_it(L_DEBUG, "Retrieved: %.*s", (int)retrieved_size, (char*)retrieved_data);
// Cleanup
DAP_DELETE(retrieved_data);
DAP_DELETE(key_str);
return 0;
}
```
### Example 3: Node Discovery and Routing
```c
#include "dap_chain_dht.h"
#include "dap_common.h"
int dht_node_discovery_example(dap_dht_t *dht) {
log_it(L_INFO, "=== DHT Node Discovery Example ===");
// Create target key for node lookup
dap_dht_key_t target_key = {0};
dap_random_bytes(target_key.raw, DHT_KEY_SIZE_BYTES);
char *target_str = dap_dht_key_to_str(&target_key);
log_it(L_INFO, "Looking for nodes closest to: %s", target_str);
// Find closest nodes to target
dap_list_t *closest_nodes = NULL;
int result = dap_dht_find_nodes(dht, &target_key, &closest_nodes);
if (result != 0) {
log_it(L_ERROR, "Node lookup failed: %d", result);
DAP_DELETE(target_str);
return -1;
}
// Process found nodes
size_t node_count = dap_list_length(closest_nodes);
log_it(L_INFO, "Found %zu nodes closest to target", node_count);
dap_list_t *current = closest_nodes;
size_t index = 0;
while (current && index < 10) { // Display first 10 nodes
dap_dht_node_t *node = (dap_dht_node_t*)current->data;
if (!node) {
current = current->next;
continue;
}
// Calculate distance to target
dap_dht_key_t distance = {0};
dap_dht_key_t node_key = {0};
memcpy(&node_key, &node->addr, sizeof(dap_chain_node_addr_t));
dap_dht_calculate_distance(&target_key, &node_key, &distance);
char *node_addr_str = dap_chain_node_addr_to_str(&node->addr);
char *distance_str = dap_dht_key_to_str(&distance);
log_it(L_INFO, "Node %zu: %s (distance: %s, RTT: %ums, score: %u)",
index + 1, node_addr_str, distance_str,
node->response_time_ms, node->reliability_score);
// Add node to routing table if not already present
result = dap_dht_node_add(dht, &node->addr);
if (result == 0) {
log_it(L_DEBUG, "Added node to routing table");
} else if (result == -EEXIST) {
log_it(L_DEBUG, "Node already in routing table");
}
DAP_DELETE(node_addr_str);
DAP_DELETE(distance_str);
current = current->next;
index++;
}
// Ping best nodes to verify connectivity
current = closest_nodes;
size_t ping_count = 0;
while (current && ping_count < 3) { // Ping first 3 nodes
dap_dht_node_t *node = (dap_dht_node_t*)current->data;
if (node && node->is_good) {
result = dap_dht_node_ping(dht, node);
if (result == 0) {
log_it(L_INFO, "✓ Ping sent to node %zu", ping_count + 1);
} else {
log_it(L_WARNING, "Failed to ping node %zu: %d", ping_count + 1, result);
}
ping_count++;
}
current = current->next;
}
// Cleanup
dap_list_free(closest_nodes);
DAP_DELETE(target_str);
log_it(L_INFO, "✓ Node discovery completed");
return 0;
}
```
### Example 4: DHT Maintenance and Monitoring
```c
#include "dap_chain_dht.h"
#include "dap_common.h"
void dht_maintenance_callback(dap_dht_t *dht) {
log_it(L_INFO, "=== DHT Maintenance Cycle ===");
// Check routing table health
size_t total_nodes = 0;
size_t active_buckets = 0;
for (int i = 0; i < DHT_KEY_SIZE_BITS; i++) {
dap_dht_bucket_t *bucket = &dht->routing_table[i];
if (bucket->node_count > 0) {
active_buckets++;
total_nodes += bucket->node_count;
log_it(L_DEBUG, "Bucket %d: %u nodes (prefix_len: %u)",
i, bucket->node_count, bucket->prefix_length);
}
}
log_it(L_INFO, "Routing table: %zu nodes in %zu active buckets",
total_nodes, active_buckets);
// Ping random nodes to verify liveness
size_t ping_count = 0;
for (int i = 0; i < DHT_KEY_SIZE_BITS && ping_count < 10; i++) {
dap_dht_bucket_t *bucket = &dht->routing_table[i];
if (bucket->node_count == 0) continue;
// Select random node from bucket
dap_list_t *current = bucket->nodes;
uint32_t random_index = rand() % bucket->node_count;
for (uint32_t j = 0; j < random_index && current; j++) {
current = current->next;
}
if (current) {
dap_dht_node_t *node = (dap_dht_node_t*)current->data;
if (node) {
int result = dap_dht_node_ping(dht, node);
if (result == 0) {
ping_count++;
log_it(L_DEBUG, "Maintenance ping sent to node in bucket %d", i);
}
}
}
}
log_it(L_INFO, "Sent %zu maintenance pings", ping_count);
// Check storage health
size_t storage_count = dap_hashtable_count(dht->storage);
log_it(L_INFO, "Local storage: %zu items", storage_count);
log_it(L_INFO, "✓ DHT maintenance completed");
}
int setup_dht_monitoring(dap_dht_t *dht) {
log_it(L_INFO, "Setting up DHT monitoring");
// Create maintenance timer
dht->maintenance_timer = dap_timer_new(
DHT_MAINTENANCE_INTERVAL * 1000, // Convert to milliseconds
(dap_timer_callback_t)dht_maintenance_callback,
dht
);
if (!dht->maintenance_timer) {
log_it(L_ERROR, "Failed to create maintenance timer");
return -1;
}
// Start periodic maintenance
dap_timer_start(dht->maintenance_timer);
log_it(L_INFO, "✓ DHT monitoring started (interval: %d seconds)",
DHT_MAINTENANCE_INTERVAL);
return 0;
}
```
---
**See also:** [[Module Chain Network|Module Chain Network]], [[Module Common|Module Common]], [[Services Overview|Services Overview]], [[Architecture Overview|Architecture Overview]]
---
*Based on: `dap_chain_dht.h`, `dap_chain_dht.c`*