Acki Nacki documentation
Acki Nacki docsFor DevelopersWhat is Acki Nacki?
  • Acki Nacki Overview
  • Glossary
  • Launch & Genesis
  • Tokenomics
    • Fee System
  • Protocol participation
    • License
      • Acki Nacki Node License
      • Working with Licenses
      • License Delegation Guide
    • Block Keeper
      • Guide for Block Keeper testing on Shellnet
      • Join DNSP Gossip
      • Setting up Block Keeper Node
      • How to join the protocol as Block Keeper?
      • Formal Verification
        • Block Keeper Contracts Business-Level Specification
        • Block Keeper Contracts High Level Specification
    • Block Manager
      • Setting up Block Manager Node
    • Proxy service
  • Wallet
    • Create Your Wallet
    • ZK Login Authentication Flow
Powered by GitBook
On this page
  • Setting up Block Keeper Node
  • How to join a network as a Block Keeper
  • Contracts
  • Stage 1: Initializing the Block Keeper Wallet before joining the Acki Nacki protocol
  • Stage 2: Preparing the node for participation in the protocol
  • Stage 3: Starting the Epoch
  • Stage 4: Preparing the stake for the next epoch
  • Stage 5: Finalizing the Active Epoch
  • Stage 6: Withdrawing a Portion of the Rewards
  • Stage 7: Stopping the Work as a BK
  1. Protocol participation
  2. Block Keeper

How to join the protocol as Block Keeper?

PreviousSetting up Block Keeper NodeNextFormal Verification

Last updated 3 months ago

you can review multiple plots detailing various aspects of .

Setting up Block Keeper Node

By this point, you should already have a .

How to join a network as a Block Keeper

Contracts

  • BlockKeeperContractRoot (Root) - The main system contract that manages a participation in the network.

  • AckiNackiBlockKeeperNodeWallet (Wallet) - The BK wallet contract, responsible for management.

  • BlockKeeperPreEpochContract (Pre Epoch) - The contract responsible for BK's preparation during the .

  • BlockKeeperEpochContract (Epoch) - The contract that indicates its owner is an active BK.

  • BlockKeeperCoolerContract (Cooler) - The contract where the stake (plus ) is locked for the duration of the BK's operation verification.

Stage 1: Initializing the Block Keeper Wallet before joining the Acki Nacki protocol

  1. To become a network member, a prospective BK must lock their stake. To do this, the Owner needs to deploy a wallet for every BK. To deploy BK wallet Owner should send an external message to the Root contract, signed with their public key:

deployAckiNackiBlockKeeperNodeWallet(pubkey)
  1. The Root contract will deploy the BK wallet using the owner's public key:

constructor (
     TvmCell BlockKeeperPreEpochCode,
     TvmCell AckiNackiBlockKeeperNodeWalletCode,
     TvmCell BlockKeeperEpochCode,
     TvmCell BlockKeeperEpochCoolerCode,
     TvmCell BlockKeeperSlashCode,
     uint256 walletId
)
setServiceKey(optional(uint256))
receive()

Ensure that the NACKL amount sent to the wallet exceeds 2 minimum stakes if you want continuous re-staking.

To determine the minimum stake amount, you can request this information from the Root contract.:

tvm-cli -u -j run 0:7777777.....7777 getDetails {} --abi <BlockKeeperContractRoot_ABI_FILE>

Stage 2: Preparing the node for participation in the protocol

  1. Send a request to the Wallet contract for registration as a BK in the Acki Nacki Protocol (this must be signed with either the owner’s public key or the service key):

sendBlockKeeperRequestWithStake(bytes bls_pubkey, varuint32 stake)
  1. The Wallet contract sends a request with the NACKL stake attached.

receiveBlockKeeperRequestWithStakeFromWallet(uint256 pubkey, bytes bls_pubkey )
  1. The Root contract permits the Wallet to deploy the Pre Epoch contract with the NACKL stake attached:

deployPreEpochContract(
    uint32 epochDuration,
    uint64 epochCliff,
    uint64 waitStep,
    bytes bls_pubkey
)
  1. The Wallet deploys the Pre Epoch contract, attaching the NACKL stake:

constructor (
     uint64 waitStep,
     uint32 epochDuration,
     bytes bls_pubkey,
     mapping(uint8 => TvmCell) code,
     uint256 walletId
)
setLockStake(uint64 seqNoStart, uint256 stake)

Stage 3: Starting the Epoch

  1. The BK script calls a function in the Pre-Epoch contract to join the Acki Nacki protocol:

touch()

11.1. The Pre-Epoch contract deploys the Epoch contract with the stake attached:

constructor (
     uint64 waitStep,
     uint32 epochDuration,
     bytes bls_pubkey,
     mapping(uint8 => TvmCell) code,
     bool isContinue, // is false in this case
     uint256 walletId,
     uint32 reputationTime
)

11.2 The Pre Epoch contract destructs itself:

selfdestruct(epoch)

12.1 The Epoch contract sends a message to the Root contract to increase the number of BKs:

increaseActiveBlockKeeperNumber(
    uint256 pubkey,
    uint64 seqNoStart,
    uint256 stake
)

12.2 The Epoch contract sends a message to the Wallet to update information about the previously locked stake:

updateLockStake(
    uint64 seqNoStart,
    uint32 timeStampFinish,
    uint256 stake
)

Stage 4: Preparing the stake for the next epoch

BKs receive a base reward for blocks, but their Reputation Coefficient adds a premium reward depending on how long they have continuously participated in network work and restaked their tokens.

The longer a BK operates without missing any epochs, the higher their Reputation Coefficient, which can significantly increase their total reward.

However, if a BK skips even one epoch, the coefficient is reset to the minimum value.

If the Node Owner wants to remain on the Acki Nacki network after the epoch ends they must send another stake upfront.

When the active Epoch contract will be destroyed:

  • the old stake will be transferred to the Cooler contract

  • The new Epoch contract will be deployed with the new stake

  • If no slashing occurred then the stake + rewards will be transferred from the Cooler Contract when the cooling period is over to Block Keeper wallet, so that they become available to be re-staked again

This process is not automatically repeatable, it just allows transitioning from one epoch to another without time gaps and, therefore, reputation loss but you still need to do it every epoch.

  1. To initiate this, send an external message to the Wallet contract with next stake attached while the current epoch is still active:

   sendBlockKeeperRequestWithStakeContinue(
    bytes bls_pubkey,
    varuint32 stake,
    uint64 seqNoStartOld
)
  1. The Root contract accepts the stake and sends a permission to deploy a new Epoch contract to the Wallet contract:

receiveBlockKeeperRequestWithStakeFromWalletContinue(
    uint256 pubkey,
    bytes bls_pubkey,
    uint64 seqNoStartOld
)
  1. The BK script calls a function in the Wallet contract to lock the stake for rejoining the Acki Nacki network:

 deployBlockKeeperContractContinue(
        uint32 epochDuration,
        uint64 waitStep,
        uint64 seqNoStartold, 
        bytes bls_pubkey
)
  1. A flag is activated in the existing Epoch contract, indicating that the BK will remain for the next epoch:

continueStake(
    uint32 epochDuration,
    uint64 waitStep,
    bytes bls_pubkey
)

Stage 5: Finalizing the Active Epoch

17. Block Producer checks Block Keeper set and epochs duration and when it sees that some BK's epoch is over, it sends a touch message to it:

touch()

18. The Epoch contract requests permission from the Root contract to delete itself. If, after deletion, the number of BKs is less than the required minimum, the function returns false, making it impossible to complete the epoch.

canDeleteEpoch(
    uint256 pubkey,
    uint64 seqNoStart,
    uint256 stake,
    uint32 epochDuration,
    uint32 reputationTime,
    uint256 totalStakeOld
)

19. The Root contract authorizes the deletion of the Epoch contract, with the reward attached:

canDelete(uint256 reward)

20.1 The Epoch contract initiates its own self-destruction:

destroy(bool isSlash) 

20.2 The Epoch contract notifies the Root contract about the decrease in the number of BKs:

decreaseActiveBlockKeeperNumber(
    uint256 pubkey,
    uint64 seqNoStart,
    uint256 stake
)

20.3 The Epoch contract will call the Wallet contract function, which will deploy a new Epoch contract for the next iteration:

deployBlockKeeperContractContinueAfterDestroy(
    uint32 epochDuration,
    uint64 waitStep,
    bytes bls_pubkey,
    uint64 seqNoStartOld,
    uint32 reputationTime
)
  constructor (
        uint64 waitStep,
        uint32 epochDuration,
        bytes bls_pubkey,
        mapping(uint8 => TvmCell) code,
        bool isContinue,
        uint256 walletId,
        uint32 reputationTime
   

20.5 The Epoch contract deploys the Cooler contract with the NACKL stake (+reward) attached:

constructor (
     uint64 waitStep,
     address owner,
     address root,
     bytes bls_pubkey,
     mapping(uint256 => bool) slashMember,
     uint128 slashed,
     mapping(uint8 => TvmCell) code,
     uint256 walletId
)

20.6 The active Epoch contract destructs itself:

selfdestruct(
    BlockKeeperWalletAddress,
    _root,
    _owner_pubkey
)
  1. An unsigned external message is sent by Block Keeper script to notify that the Cooling stage has finished:

touch()

22.1 The stake and reward are unlocked in the Wallet contract:

unlockStakeCooler(uint64 seqNoStart)

22.2 The Cooler contract destroys itself:

destroy(address to)

Stage 6: Withdrawing a Portion of the Rewards

After the Cooler contract sends the tokens to the Wallet, they can be withdrawn.

To do this, send an external message to the Wallet contract.

Only the Node Owner is authorized to perform this action.

withdrawToken(
    address to, 
    varuint32 value
)

Stage 7: Stopping the Work as a BK

To conclude their activity as a BK, the Node Owner must wait for the end of the epoch and the cooling period, then call a specific function in the Wallet contract. This function triggers the process of exiting the Acki Nacki protocol and unlocking the staked funds.

sendBlockKeeperRequestWithCancelStakeContinue(uint64 seqNoStartOld)

To restrict access to the wallet but allow node operations, the should set a service key by calling a function in the Wallet contract:

Top Up with (from any source):

The contract sends a message to the Wallet contract to lock the stake:

20.4 The Wallet contract deploys a new Epoch contract if there is already another stake with isContinue=true flag (. At the same time, the number of active BKs is updated in the Root Contract, and information about the previously blocked stake is refreshed (steps ):

see the previous step)
12.1 and 12.2
Here
Tokenomics
Glossary
node running
Node Owner
NACKL
Pre-Epoch
Block Keeper's (BK)
stake
Epoch
rewards