Skip to main content

Staking and Snarking

You can interact with the Mina network by participating in consensus to produce a cryptographic proof for the data by generating zk-SNARKs. By operating a node that helps secure the network, you can receive MINA for your efforts. See Staking Rewards on Mina.

Participating in Consensus

The Mina network is secured by proof of stake (PoS) consensus. With this model of consensus, you don't need to have complex equipment like in Bitcoin mining. By simply having MINA in your wallet, you can choose to stake your MINA and run a node or delegate it to another node. When you delegate your tokens, you are staking your MINA tokens with block producers who operate nodes, sometimes known as a staking pools. The staking pool will share the earned block rewards, minus a small fee, with those who have delegated their MINA.

Mina is a public and decentralized blockchain that is open for anyone in the world to participate in actively or passively. You can help increase the security of the network by becoming nodes or block producers, or you can help lower the cost of transactions by becoming SNARK producers, or you can be both.

Staking MINA

You can earn block rewards by participating in block production through staking.

  • Your new stake delegation comes into effect after a latency period of a 2-4 weeks.
  • You can undelegate at any time with no penalty. Submit a delegation transaction with the new staking service or back to yourself if you want to be a block producer. Updates are made after a delay of 1-2 epochs.

Requirements

To properly remain synced to the network and participate in consensus, your server must run a clock synchronization protocol.

Network Time Protocol (NTP) is the most common method for synchronizing computer clocks over a network.

To synchronize your server software clock with internet time servers, be sure to set up NTP. Many popular Linux distributions include NTP as a default service.

Set or change the block producer key

Use the mina client delegate-stake subcommand to set or change the delegation of the block producer key. See Delegating MINA.

Alternatively, to stake with your own node, start the daemon with the -block-producer-pubkey flag:

args={["-block-producer-pubkey $MINA_PUBLIC_KEY"]} />

To check which accounts you are staking with:

mina client status

The expected output is like:

Mina daemon status
-----------------------------------

Global number of accounts: 327371
Block height: 32494
Max observed block height: 32494
Max observed unvalidated block height: 32494
Local uptime: 2d5h11m5s
Ledger Merkle root: ...
Protocol state hash: ...
Chain id: ...
Git SHA-1: ...
Configuration directory: /root/.mina-config
Peers: 77
User_commands sent: 0
SNARK worker: None
SNARK work fee: 1
Sync status: Synced
Catchup status:
To build breadcrumb: 0
To initial validate: 0
Finished: 388
To download: 0
Waiting for parent to finish: 0
To verify: 0

Block producers running: 1 (...)
Coinbase receiver: Block producer
Best tip consensus time: epoch=6, slot=4505
Best tip global slot (across all hard-forks): 47345
Next block will be produced in: in 7.077h for slot: 47487 slot-since-genesis: 47487 (Generated from consensus at slot: 46403 slot-since-genesis: 46403)
Consensus time now: epoch=6, slot=4505
Consensus mechanism: proof_of_stake
Consensus configuration:
Delta: 0
k: 290
Slots per epoch: 7140
Slot duration: 3m
Epoch duration: 14d21h
Chain start timestamp: 2023-10-17 16:01:01.000000Z
Acceptable network delay: 3m

Addresses and ports:
External IP: ...
Bind IP: ...
Libp2p PeerID: ...
Libp2p port: 10801
Client port: 8301

Metrics:
block_production_delay: 7 (0 0 0 0 0 0 1)
transaction_pool_diff_received: 0
transaction_pool_diff_broadcasted: 0
transactions_added_to_pool: 1075
transaction_pool_size: 0
snark_pool_diff_received: 2
snark_pool_diff_broadcasted: 0
pending_snark_work: 0
snark_pool_size: 1967

where:

  • The Block producers running field returns the number of accounts currently staking, with the associated key.

When you are staking independently with funds in an account, you must run a node and remain connected to the network at all times to successfully produce blocks. If you need to go offline frequently, it might be better to delegate your stake to another node operator.

If you want to send your coinbase to an account other than the one that is staking, use the -coinbase-receiver flag when you start your daemon. You can even point the coinbase at a cold wallet.

Delegating MINA

Delegating MINA has the benefit of not having to maintain a node that is always connected to the network. See Mina Foundation Delegation Program.

First, make sure you've unlocked your account:

mina account unlock --public-key $MINA_PUBLIC_KEY

To delegate your stake:

mina client delegate-stake \
--receiver <DELEGATE-PUBLIC-KEY> \
--sender $MINA_PUBLIC_KEY \
--fee 0.1

where:

  • receiver is the public key of the receiver of your stake delegation
  • sender is the public key of the account you want to delegate from
  • fee is the cost to send your transaction, the fee is paid to the network’s block producers

There is no amount parameter. Your full MINA balance is delegated automatically.

This command looks like a payment transaction, because a stake delegation is also a transaction, which is why you have to pay a small transaction fee.

Delegating your stake might be useful if you're interested in:

  • Running your own staking node that uses funds from a cold wallet
  • Delegating to a staking pool that periodically provides token payouts

You might decide to stake your MINA if you don't have enough MINA tokens to make managing a block producer full-time worthwhile.

Compressing data in the Mina network

The Mina protocol is unique because nodes are not required to maintain the full history of the blockchain like other cryptocurrency protocols. By recursively using cryptographic proofs, the Mina protocol effectively compresses the blockchain to constant size. This compression reduces terabytes of data to a few kilobytes.

However, this isn't data encoding or compression in the traditional sense. Mina nodes compress data in the network by generating cryptographic proofs. Node operators play a crucial role in this process by designating themselves as SNARK-workers that generate zk-SNARKs for transactions that have been added to blocks.

To start a SNARK-worker, run these commands:

mina client set-snark-work-fee <FEE>
mina client set-snark-worker --address $MINA_PUBLIC_KEY

If your daemon is already running, restart the daemon with these flags:

args={["-run-snark-worker $MINA_PUBLIC_KEY", "-snark-worker-fee <fee>"]}

As a SNARK worker, you get to share some of the block rewards for each block that include your compressed transactions. The block producer is responsible for gathering compressed transactions before including them into a block and is incentivized by the protocol to reward SNARK workers.

SNARK workers can be fairly compute-intensive. If you need to limit their CPU usage, specify the number of threads that SNARK workers use with the -snark-worker-parallelism flag when running a mina daemon as a SNARK worker. This can be especially useful if you're trying to run a block producer and SNARK worker on the same machine and are having issues producing blocks in time.

The roles and responsibilities of a Mina node operator offer you incentives to participate in block production through staking or delegation. Mina is a permissionless peer-to-peer network, so everything is managed and run in a decentralized manner by nodes all over the world.

Configure your mina daemon in daemon.json

By creating a file at ~/.mina-config/daemon.json, you can configure your mina daemon without providing options on the command line. This can be useful for running mina as a service and to avoiding repetitive typing.

Most of the options that can be passed to mina daemon on the command line can also be provided as options in the config file. See mina daemon -help for more details.

The following example file includes usage of the configuration parameters:

{
"daemon": {
"client-port": 1000,
"external-port": 1001,
"rest-port": 1002,
"block-producer-key": "/path/to/privkey-file",
"block-producer-password": "mypassword",
"block-producer-pubkey": "<MY PUBLICKEY>",
"coinbase-receiver": "<MY PUBLICKEY>",
"log-block-creation": false,
"log-received-blocks": false,
"log-snark-work-gossip": false,
"log-txn-pool-gossip": false,
"peers": ["seed-one.o1test.net", "seed-two.o1test.net"],
"run-snark-worker": "<MY PUBLICKEY>",
"snark-worker-fee": 10,
"snark-worker-parallelism": 1,
"work-reassignment-wait": 420000,
"work-selection": "seq"
}
}

In the ~/.mina-config/daemon.json file, include only the options you want to change.