# Module Service - Staking
## Overview
The Staking Service implements Proof-of-Stake delegation and validator management within the Cellframe SDK. This service provides comprehensive functionality for stake delegation, validator registration, network validation participation, reward distribution, and slashing mechanisms for network security.
**Service UID:** `DAP_CHAIN_NET_SRV_STAKE_POS_DELEGATE_ID` (0x13)
## Document Structure
- [[#Overview|Overview]]
- [[#Staking Structures|Staking Structures]]
- [[#dap_chain_net_srv_stake_item_t|dap_chain_net_srv_stake_item_t - Main staking item]]
- [[#dap_chain_net_srv_stake_cache_data_t|dap_chain_net_srv_stake_cache_data_t - Cache data structure]]
- [[#dap_chain_net_srv_stake_t|dap_chain_net_srv_stake_t - Network staking context]]
- [[#Staking Functions|Staking Functions]]
- [[#Delegation Management|Delegation Management Functions]]
- [[#Validator Operations|Validator Operations Functions]]
- [[#Network Management|Network Management Functions]]
- [[#Typical Examples|Typical Examples]]
## Staking Structures
### dap_chain_net_srv_stake_item_t
Main staking item structure containing all validator and delegation information.
```c
typedef struct dap_chain_net_srv_stake_item {
bool is_active; // Stake activation status
dap_chain_net_t *net; // Network context
uint256_t locked_value; // Locked stake amount
uint256_t value; // Total stake value
dap_chain_addr_t signing_addr; // Validator signing address
dap_chain_hash_fast_t tx_hash; // Staking transaction hash
dap_chain_node_addr_t node_addr; // Validator node address
dap_chain_addr_t sovereign_addr; // Sovereign delegator address
uint256_t sovereign_tax; // Sovereign tax rate
dap_pkey_t *pkey; // Validator public key
UT_hash_handle hh, ht; // Hash table handles
} dap_chain_net_srv_stake_item_t;
```
**Fields:**
- `is_active` - Whether this stake is currently active in validation
- `net` - Pointer to the network where this stake operates
- `locked_value` - Amount of tokens locked for staking
- `value` - Total value including rewards and delegations
- `signing_addr` - Address used for signing blocks and validations
- `tx_hash` - Hash of the transaction that created this stake
- `node_addr` - Network address of the validator node
- `sovereign_addr` - Address of the sovereign (delegator) if applicable
- `sovereign_tax` - Tax rate charged by sovereign for delegation
- `pkey` - Public key used for validation and signing
- `hh, ht` - Hash table handles for efficient lookup
### dap_chain_net_srv_stake_cache_data_t
Cache data structure for efficient stake lookup and management.
```c
typedef struct dap_chain_net_srv_stake_cache_data {
dap_chain_hash_fast_t tx_hash; // Transaction hash
dap_chain_addr_t signing_addr; // Signing address
} DAP_ALIGN_PACKED dap_chain_net_srv_stake_cache_data_t;
```
### dap_chain_net_srv_stake_cache_item_t
Cache item structure for hash table management.
```c
typedef struct dap_chain_net_srv_stake_cache_item {
dap_chain_hash_fast_t tx_hash; // Transaction hash
dap_chain_addr_t signing_addr; // Signing address
UT_hash_handle hh; // Hash table handle
} dap_chain_net_srv_stake_cache_item_t;
```
### dap_chain_net_srv_stake_t
Network-level staking management structure.
```c
typedef struct dap_chain_net_srv_stake {
dap_chain_net_id_t net_id; // Network identifier
uint256_t delegate_allowed_min; // Minimum delegation amount
uint256_t delegate_percent_max; // Maximum delegation percentage
dap_chain_net_srv_stake_item_t *itemlist; // Active stakes list
dap_chain_net_srv_stake_item_t *tx_itemlist; // Transaction-based lookup
dap_chain_net_srv_stake_cache_item_t *cache; // Cache for fast lookup
} dap_chain_net_srv_stake_t;
```
## Staking Functions
### Delegation Management
#### `dap_chain_net_srv_stake_key_delegate()`
Delegates stake to a validator with specified parameters.
```c
void dap_chain_net_srv_stake_key_delegate(
dap_chain_net_t *a_net,
dap_chain_addr_t *a_signing_addr,
dap_hash_fast_t *a_stake_tx_hash,
uint256_t a_value,
dap_chain_node_addr_t *a_node_addr,
dap_pkey_t *a_pkey
);
```
**Parameters:**
- `a_net` (dap_chain_net_t *) - Target network for delegation
- `a_signing_addr` (dap_chain_addr_t *) - Validator signing address
- `a_stake_tx_hash` (dap_hash_fast_t *) - Staking transaction hash
- `a_value` (uint256_t) - Amount of stake being delegated
- `a_node_addr` (dap_chain_node_addr_t *) - Validator node address
- `a_pkey` (dap_pkey_t *) - Validator public key
**Description:** Registers a new stake delegation in the network, associating tokens with a specific validator for participation in consensus.
#### `dap_chain_net_srv_stake_key_invalidate()`
Invalidates a stake delegation.
```c
void dap_chain_net_srv_stake_key_invalidate(dap_chain_addr_t *a_signing_addr);
```
**Parameters:**
- `a_signing_addr` (dap_chain_addr_t *) - Signing address to invalidate
**Description:** Removes a validator from active participation by invalidating their stake delegation.
#### `dap_chain_net_srv_stake_key_update()`
Updates stake delegation parameters.
```c
void dap_chain_net_srv_stake_key_update(
dap_chain_addr_t *a_signing_addr,
uint256_t a_new_value,
dap_hash_fast_t *a_new_tx_hash
);
```
**Parameters:**
- `a_signing_addr` (dap_chain_addr_t *) - Validator signing address
- `a_new_value` (uint256_t) - New stake value
- `a_new_tx_hash` (dap_hash_fast_t *) - New transaction hash
### Validator Operations
#### `dap_chain_net_srv_stake_verify_key_and_node()`
Verifies validator key and node address combination.
```c
int dap_chain_net_srv_stake_verify_key_and_node(
dap_chain_addr_t *a_signing_addr,
dap_chain_node_addr_t *a_node_addr
);
```
**Parameters:**
- `a_signing_addr` (dap_chain_addr_t *) - Validator signing address
- `a_node_addr` (dap_chain_node_addr_t *) - Validator node address
**Returns:**
- `0` - Verification successful
- `-1` - Verification failed
- Other negative values for specific error conditions
#### `dap_chain_net_srv_stake_key_delegated()`
Checks if a key is currently delegated.
```c
int dap_chain_net_srv_stake_key_delegated(dap_chain_addr_t *a_addr);
```
**Parameters:**
- `a_addr` (dap_chain_addr_t *) - Address to check
**Returns:**
- `1` - Key is actively delegated
- `0` - Key is registered but not actively delegated
- `-1` - Key is not found in delegation system
#### `dap_chain_net_srv_stake_mark_validator_active()`
Marks a validator as active or inactive.
```c
int dap_chain_net_srv_stake_mark_validator_active(
dap_chain_addr_t *a_signing_addr,
bool a_on_off
);
```
**Parameters:**
- `a_signing_addr` (dap_chain_addr_t *) - Validator signing address
- `a_on_off` (bool) - Activation status (true = active, false = inactive)
**Returns:**
- `0` - Status change successful
- Non-zero - Error occurred
### Network Management
#### `dap_chain_net_srv_stake_get_validators()`
Retrieves list of validators for a network.
```c
dap_list_t *dap_chain_net_srv_stake_get_validators(
dap_chain_net_id_t a_net_id,
bool a_only_active,
uint16_t **a_excluded_list
);
```
**Parameters:**
- `a_net_id` (dap_chain_net_id_t) - Network identifier
- `a_only_active` (bool) - Return only active validators
- `a_excluded_list` (uint16_t **) - List of excluded validator indices
**Returns:**
- List of validator structures
- `NULL` if no validators found or error occurred
#### `dap_chain_net_srv_stake_get_total_weight()`
Gets total staking weight for a network.
```c
uint256_t dap_chain_net_srv_stake_get_total_weight(
dap_chain_net_id_t a_net_id,
uint256_t *a_locked_weight
);
```
**Parameters:**
- `a_net_id` (dap_chain_net_id_t) - Network identifier
- `a_locked_weight` (uint256_t *) - Output for locked weight
**Returns:**
- Total staking weight for the network
#### `dap_chain_net_srv_stake_get_total_keys()`
Gets total number of staking keys.
```c
size_t dap_chain_net_srv_stake_get_total_keys(
dap_chain_net_id_t a_net_id,
size_t *a_in_active_count
);
```
**Parameters:**
- `a_net_id` (dap_chain_net_id_t) - Network identifier
- `a_in_active_count` (size_t *) - Output for inactive key count
**Returns:**
- Total number of staking keys
#### `dap_chain_net_srv_stake_get_fee_validators()`
Retrieves validator fee information.
```c
bool dap_chain_net_srv_stake_get_fee_validators(
dap_chain_net_t *a_net,
uint256_t *a_max_fee,
uint256_t *a_average_fee,
uint256_t *a_min_fee,
uint256_t *a_median_fee
);
```
**Parameters:**
- `a_net` (dap_chain_net_t *) - Network context
- `a_max_fee` (uint256_t *) - Output for maximum fee
- `a_average_fee` (uint256_t *) - Output for average fee
- `a_min_fee` (uint256_t *) - Output for minimum fee
- `a_median_fee` (uint256_t *) - Output for median fee
**Returns:**
- `true` - Fee information retrieved successfully
- `false` - Error occurred or no data available
## Typical Examples
### Stake Delegation Example
```c
#include <dap_chain_net_srv_stake_pos_delegate.h>
void stake_delegation_example() {
log_it_info("=== Stake Delegation Example ===");
// Step 1: Setup network context
dap_chain_net_t *net = dap_chain_net_by_name("backbone");
if (!net) {
log_it_error("✗ Network 'backbone' not found");
return;
}
// Step 2: Prepare delegation parameters
dap_chain_addr_t signing_addr;
dap_chain_node_addr_t node_addr;
dap_hash_fast_t stake_tx_hash;
uint256_t stake_value = dap_chain_balance_scan("1000.0"); // 1000 tokens
// Convert addresses from strings (example addresses)
if (dap_chain_addr_from_str(&signing_addr, "mJWQjJA4iXQ7HCZkZHgmPFNv9xAA7GV9eMUTjRdBGNBuKVaZZ3qw2k") != 0) {
log_it_error("✗ Invalid signing address format");
return;
}
if (dap_chain_node_addr_from_str(&node_addr, "0123456789ABCDEF") != 0) {
log_it_error("✗ Invalid node address format");
return;
}
// Generate example transaction hash
memset(&stake_tx_hash, 0x42, sizeof(dap_chain_hash_fast_t));
log_it_info("Delegation parameters:");
log_it_info(" Stake value: %s tokens", dap_chain_balance_to_coins(stake_value));
log_it_info(" Signing address: %s", dap_chain_addr_to_str(&signing_addr));
log_it_info(" Node address: %s", dap_chain_node_addr_to_str(&node_addr));
// Step 3: Get or create validator public key
dap_pkey_t *validator_pkey = dap_pkey_generate_new(DAP_PKEY_TYPE_SIG_DILITHIUM);
if (!validator_pkey) {
log_it_error("✗ Failed to generate validator public key");
return;
}
log_it_info("✓ Validator public key generated");
// Step 4: Perform stake delegation
dap_chain_net_srv_stake_key_delegate(
net,
&signing_addr,
&stake_tx_hash,
stake_value,
&node_addr,
validator_pkey
);
log_it_info("✓ Stake delegation registered");
// Step 5: Verify delegation status
int delegation_status = dap_chain_net_srv_stake_key_delegated(&signing_addr);
switch (delegation_status) {
case 1:
log_it_info("✓ Key is actively delegated and participating in validation");
break;
case 0:
log_it_info("Key is registered but not actively delegated");
break;
case -1:
log_it_error("✗ Key is not found in delegation system");
break;
default:
log_it_error("✗ Delegation check failed: %d", delegation_status);
break;
}
// Step 6: Verify validator key and node combination
int verification_result = dap_chain_net_srv_stake_verify_key_and_node(&signing_addr, &node_addr);
if (verification_result == 0) {
log_it_info("✓ Validator key and node verified successfully");
} else {
log_it_error("✗ Validator verification failed: %d", verification_result);
}
// Step 7: Cleanup
dap_pkey_delete(validator_pkey);
log_it_info("Stake delegation example completed");
}
```
### Validator Management Example
```c
#include <dap_chain_net_srv_stake_pos_delegate.h>
void validator_management_example() {
log_it_info("=== Validator Management Example ===");
// Step 1: Setup network
dap_chain_net_t *net = dap_chain_net_by_name("backbone");
if (!net) {
log_it_error("✗ Network not found");
return;
}
// Step 2: Get list of validators
dap_list_t *validators = dap_chain_net_srv_stake_get_validators(net->pub.id, false, NULL);
if (!validators) {
log_it_info("No validators found in the network");
return;
}
// Step 3: Display validator information
log_it_info("Network Validators:");
log_it_info("╭─────────────────────────────────────────────────────────────────────╮");
log_it_info("│ Signing Address │ Status │ Stake Value │ Node ID │");
log_it_info("├─────────────────────────────────────────────────────────────────────┤");
dap_list_t *current = validators;
int validator_count = 0;
while (current) {
dap_chain_net_srv_stake_item_t *stake_item = (dap_chain_net_srv_stake_item_t *)current->data;
char *signing_addr_str = dap_chain_addr_to_str(&stake_item->signing_addr);
char *node_addr_str = dap_chain_node_addr_to_str(&stake_item->node_addr);
char short_addr[17];
char short_node[9];
// Truncate addresses for display
strncpy(short_addr, signing_addr_str ? signing_addr_str : "N/A", 16);
short_addr[16] = '\0';
strncpy(short_node, node_addr_str ? node_addr_str : "N/A", 8);
short_node[8] = '\0';
const char *status = stake_item->is_active ? "Active" : "Inactive";
log_it_info("│ %-30s │ %-6s │ %-13s │ %-7s │",
short_addr,
status,
dap_chain_balance_to_coins(stake_item->value),
short_node);
// Cleanup
if (signing_addr_str) DAP_DELETE(signing_addr_str);
if (node_addr_str) DAP_DELETE(node_addr_str);
current = current->next;
validator_count++;
}
log_it_info("╰─────────────────────────────────────────────────────────────────────╯");
log_it_info("Total validators: %d", validator_count);
// Step 4: Get network staking statistics
uint256_t locked_weight = {0};
uint256_t total_weight = dap_chain_net_srv_stake_get_total_weight(net->pub.id, &locked_weight);
size_t inactive_count = 0;
size_t total_keys = dap_chain_net_srv_stake_get_total_keys(net->pub.id, &inactive_count);
log_it_info("");
log_it_info("Network Staking Statistics:");
log_it_info(" Total staking weight: %s", dap_chain_balance_to_coins(total_weight));
log_it_info(" Locked staking weight: %s", dap_chain_balance_to_coins(locked_weight));
log_it_info(" Total staking keys: %zu", total_keys);
log_it_info(" Active validators: %zu", total_keys - inactive_count);
log_it_info(" Inactive validators: %zu", inactive_count);
// Step 5: Get validator fee information
uint256_t max_fee, average_fee, min_fee, median_fee;
bool fee_info_available = dap_chain_net_srv_stake_get_fee_validators(
net, &max_fee, &average_fee, &min_fee, &median_fee
);
if (fee_info_available) {
log_it_info("");
log_it_info("Validator Fee Statistics:");
log_it_info(" Maximum fee: %s", dap_chain_balance_to_coins(max_fee));
log_it_info(" Average fee: %s", dap_chain_balance_to_coins(average_fee));
log_it_info(" Minimum fee: %s", dap_chain_balance_to_coins(min_fee));
log_it_info(" Median fee: %s", dap_chain_balance_to_coins(median_fee));
} else {
log_it_info("Fee information not available");
}
// Step 6: Cleanup
dap_list_free(validators);
log_it_info("Validator management example completed");
}
```
### Validator Activation Example
```c
#include <dap_chain_net_srv_stake_pos_delegate.h>
void validator_activation_example() {
log_it_info("=== Validator Activation Example ===");
// Step 1: Setup validator address
dap_chain_addr_t validator_addr;
if (dap_chain_addr_from_str(&validator_addr, "mJWQjJA4iXQ7HCZkZHgmPFNv9xAA7GV9eMUTjRdBGNBuKVaZZ3qw2k") != 0) {
log_it_error("✗ Invalid validator address format");
return;
}
char *addr_str = dap_chain_addr_to_str(&validator_addr);
log_it_info("Managing validator: %s", addr_str ? addr_str : "N/A");
// Step 2: Check current delegation status
int current_status = dap_chain_net_srv_stake_key_delegated(&validator_addr);
log_it_info("Current delegation status:");
switch (current_status) {
case 1:
log_it_info(" ✓ Validator is actively delegated");
break;
case 0:
log_it_info(" ~ Validator is registered but not active");
break;
case -1:
log_it_error(" ✗ Validator not found in system");
if (addr_str) DAP_DELETE(addr_str);
return;
default:
log_it_error(" ✗ Status check failed: %d", current_status);
if (addr_str) DAP_DELETE(addr_str);
return;
}
// Step 3: Activate validator
log_it_info("Activating validator...");
int activation_result = dap_chain_net_srv_stake_mark_validator_active(&validator_addr, true);
if (activation_result == 0) {
log_it_info("✓ Validator activated successfully");
} else {
log_it_error("✗ Validator activation failed: %d", activation_result);
}
// Step 4: Verify activation
int new_status = dap_chain_net_srv_stake_key_delegated(&validator_addr);
log_it_info("Post-activation status:");
switch (new_status) {
case 1:
log_it_info(" ✓ Validator is now actively participating in validation");
break;
case 0:
log_it_info(" ~ Validator remains inactive (activation may be pending)");
break;
case -1:
log_it_error(" ✗ Validator disappeared from system");
break;
default:
log_it_error(" ✗ Status check failed: %d", new_status);
break;
}
// Step 5: Demonstrate deactivation
log_it_info("--- Deactivation Test ---");
log_it_info("Deactivating validator...");
int deactivation_result = dap_chain_net_srv_stake_mark_validator_active(&validator_addr, false);
if (deactivation_result == 0) {
log_it_info("✓ Validator deactivated successfully");
// Verify deactivation
int final_status = dap_chain_net_srv_stake_key_delegated(&validator_addr);
log_it_info("Final status: %s",
final_status == 1 ? "Active" :
final_status == 0 ? "Inactive" : "Not Found");
} else {
log_it_error("✗ Validator deactivation failed: %d", deactivation_result);
}
// Step 6: Cleanup
if (addr_str) {
DAP_DELETE(addr_str);
}
log_it_info("Validator activation example completed");
}
```
---
*See also: [[Modules/Module Service|Module Service]], [[Modules/Module Consensus|Module Consensus]], [[ETC/Services Overview|Services Overview]]*