BlockKeeperCoolerContract.sol
Overview
BlockKeeperCoolerContract.sol defines the BlockKeeperCooler smart contract, which manages stake locking, slashing, and reputation updates within a blockchain epoch system. This contract acts as a cooler component associated with BlockKeeperContractRoot and AckiNackiBlockKeeperNodeWallet contracts, facilitating stake control and penalty enforcement for misbehaving nodes or validators.
The contract's main responsibilities include:
Initializing stake and license data related to a node.
Managing the locking and unlocking of stakes during an epoch.
Executing slashing logic for penalizing nodes.
Interacting with node wallet and root contracts to coordinate stake and penalty operations.
Maintaining internal state such as ownership, stake, licenses, and epoch sequence numbers.
Contract: BlockKeeperCooler
State Variables
Variable | Type | Description |
|---|---|---|
|
| Constant version identifier |
|
| Public key of the contract owner (node). |
|
| Address of the |
|
| Start sequence number for epoch locking. |
|
| Finish sequence number for epoch locking. |
|
| Owner address, typically node wallet. |
|
| Total stake locked in this cooler contract. |
|
| Index of the signer in the epoch. |
|
| Array of licenses and their stakes. |
Constructor
constructor (
uint64 waitStep,
address owner,
address root,
uint16 signerIndex,
LicenseStake[] licenses,
uint128 stake,
bool isContinue,
uint128 stakeContinue,
uint64 epochDurationContinue,
uint64 waitStepContinue,
bytes bls_pubkeyContinue,
uint16 signerIndexContinue,
LicenseStake[] licensesContinue,
optional(uint128) virtualStakeContinue,
uint128 reward_sum_continue,
string myIp,
uint32 unixtimeStart,
uint128 sumReputationCoefContinue,
optional(string) nodeVersionContinue,
optional(uint8) slash_type
)
Purpose: Initializes the cooler contract for a new epoch. Sets up stake locking parameters, license data, and, if continuing from a previous epoch, deploys continuation contracts or performs slashing.
Parameters:
waitStep: Number of blocks to wait in the epoch.owner: Node wallet address owning this cooler.root: Address of the root contract.signerIndex: Signer index in epoch.licenses: Array of license stakes for this node.stake: Total stake amount locked.isContinue: Boolean indicating if continuation from previous epoch.stakeContinue,epochDurationContinue,waitStepContinue,bls_pubkeyContinue,signerIndexContinue,licensesContinue,virtualStakeContinue,reward_sum_continue,myIp,unixtimeStart,sumReputationCoefContinue,nodeVersionContinue: Various parameters for continuation logic.slash_type: Optional parameter to trigger slashing on creation.
Implementation Details:
Validates the sender is the expected epoch contract.
Checks library version embedded in contract code salt.
Initializes epoch sequence numbers.
Calls
AckiNackiBlockKeeperNodeWalletto update lock stake state.If
isContinueand no slash, calls continuation deployment on node wallet.If
slash_typeprovided, triggers slashing immediately.
Usage Example:
// Deploy a cooler contract for new epoch with initial stake and licenses
new BlockKeeperCooler(
waitStep,
ownerAddress,
rootAddress,
signerIndex,
licensesArray,
stakeAmount,
false, // not continuation
0, 0, 0, "", 0, [], optional(uint128), 0, "192.168.1.1", block.timestamp, 0, optional("1.0.0"), optional(uint8)
);
Private Function: ensureBalance
function ensureBalance() private pure
Purpose: Ensures the contract has enough balance for deployment fees by minting currency if below threshold.
Behavior: Checks if the contract's balance in the main currency exceeds a predefined fee (
FEE_DEPLOY_BLOCK_KEEPER_EPOCHE_COOLER_WALLET); if not, mints currency.Note: Uses
gosh.mintshellq()for minting, a platform-specific operation.Usage: Called internally before operations requiring sufficient balance.
Public Function: slash
function slash(uint8 slash_type, bool isFromEpoch) public senderOfTwo(_owner, address(this)) accept
Purpose: Applies slashing penalties to the node's stake and licenses.
Parameters:
slash_type: Type of slashing (e.g., full stake slash or partial percentage).isFromEpoch: Boolean flag indicating if slashing is triggered from epoch contract.
Returns: None.
Implementation Details:
Calls
ensureBalance()to confirm sufficient funds.If
slash_typeequalsFULL_STAKE_SLASH(likely a constant representing 100%), triggers full stake slash by callingslashCooleron the node wallet and notifies the root contract.For partial slash types:
Calculates slashing amount from reward balance and licenses.
Iterates over
_licensesarray to reduce stake proportionally using helper functionslashPartHelper.Updates
_stakeaccordingly.Calls
slashCooleron the node wallet andcoolerSlashon the root contract with slashing amounts.
Security: Requires sender to be either
_owneror the contract itself (viasenderOfTwomodifier).Example:
// Partial slash with type 50 (50% slash)
myCooler.slash(50, true);
Private Function: slashPartHelper
function slashPartHelper(uint i, uint8 slash_type, uint128 slash_stake) private returns(uint128)
Purpose: Helper function to calculate and apply partial slash to a single license stake.
Parameters:
i: Index of the license in_licenses.slash_type: Slash percentage.slash_stake: Accumulated slash stake so far.
Returns: Updated accumulated
slash_stakeafter applying slash on licensei.Implementation Details:
Calculates slash value based on license stake and slash type.
Decrements license stake by slash value.
Adds slash value to
slash_stake.
Usage: Called internally by
slash.
Public Function: touch
function touch() public view senderIs(_owner) accept
Purpose: Checks if the epoch's finish sequence number has passed and unlocks the stake if so.
Behavior:
Calls
ensureBalance().If current block sequence number exceeds
_seqNoFinish, callsunlockStakeCooleron the node wallet to release staked tokens.
Access Control: Only callable by the owner (
_owner).Usage: Invoked to trigger stake unlocking at epoch end.
Fallback / Receive Function
receive() external
Purpose: Accepts incoming plain transfers to the contract.
Behavior: Empty; allows the contract to receive native currency.
Getter Functions
getDetails
function getDetails() external view returns(
uint256 pubkey,
address root,
uint64 seqNoStart,
uint64 seqNoFinish,
address owner,
uint16 signerIndex,
varuint32 NACKLBalance
)
Purpose: Returns the current state details of the cooler contract.
Returns:
pubkey: Owner public key.root: Root contract address.seqNoStart: Epoch start sequence number.seqNoFinish: Epoch finish sequence number.owner: Owner address.signerIndex: Signer index.NACKLBalance: Current balance of the main currency held by the contract.
Usage: Used to query contract state externally.
getVersion
function getVersion() external pure returns(string, string)
Purpose: Returns the version and contract identifier.
Returns: Tuple
(version, "BlockKeeperCooler").Usage: Used for contract version tracking.
Implementation Details and Algorithms
Stake Locking and Unlocking: The contract manages locking of stakes for certain epochs using sequence numbers
_seqNoStartand_seqNoFinish. Thetouch()function unlocks stakes after epoch completion by calling the node wallet contract.Slashing Logic: The
slash()function handles both full and partial slashes. For partial slashes, it calculates penalty portions for each license stake proportionally usingslashPartHelper(). Slashing penalties are reported back to the node wallet and root contracts to update global state.Balance Management: Before operations requiring fees,
ensureBalance()ensures the contract has enough balance and mints currency if needed.Access Control: Uses modifiers like
senderOfTwoandsenderIs(imported frommodifiers.sol) to restrict function calls to authorized accounts (_owneror contract itself).Inter-contract Calls: The contract interacts primarily with:
AckiNackiBlockKeeperNodeWalletat_owneraddress for stake updates, deployment continuation, slashing, and unlocking.BlockKeeperContractRootat_rootaddress for reporting slashing events.
Version Check: Upon construction, the contract validates the embedded library version (
BlockKeeperLib.versionLib) against the code salt to ensure compatibility.
Interactions with Other System Components
AckiNackiBlockKeeperNodeWallet
Responsible for updating lock states, deploying continuation contracts after epoch destruction, and executing stake unlocks and slashes. The cooler contract calls this node wallet to propagate stake-related updates.BlockKeeperContractRoot
Acts as the root authority for the block keeper system. The cooler contract reports slashing events to the root contract, enabling global penalty enforcement and reputation management.BlockKeeperLib
The library whose version is checked during contract creation, ensuring that the contract logic aligns with expected protocol versions.Modifiers from
modifiers.sol
Provide access control and message acceptance rules, ensuring only authorized calls are processed.
Data Structures
LicenseStake
Represents a license with an associated stake. The contract maintains an array of these to track multiple licenses per node.varuint32andmapping(uint32 => varuint32)
Used to represent currency amounts and mappings in calls to node wallet and root contracts.
Diagram: Class Structure of BlockKeeperCooler
classDiagram
class BlockKeeperCooler {
-string version
-uint256 static _owner_pubkey
-address _root
-uint64 static _seqNoStart
-uint64 _seqNoFinish
-address _owner
-uint128 _stake
-uint16 _signerIndex
-LicenseStake[] _licenses
+constructor()
-ensureBalance()
+slash()
-slashPartHelper()
+touch()
+receive()
+getDetails()
+getVersion()
}
This diagram illustrates the BlockKeeperCooler contract's properties and methods, showing the encapsulation of stake and license data alongside the key functions managing slashing and stake lifecycle events.