# 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]]*