Terminology
A reference glossary for all NCN-specific concepts, accounts, and data structures.
Core Concepts
Operator
A trusted participant who independently generates stake snapshots and votes on-chain. Operators are managed by the governance authority via the ProgramConfig whitelist (max 64). Each operator has an Ed25519 keypair — their public key appears in the whitelist and is used to authenticate snapshot uploads to the verifier service.
BallotBox
The on-chain vote collection account for a specific snapshot_slot. Created once per governance proposal (via init_ballot_box). Tracks which operator voted for which ballot, tallies votes per unique ballot, and automatically records a winner when the consensus threshold is crossed.
PDA seeds: ["BallotBox", snapshot_slot.to_le_bytes()]
Ballot
The identity of a single snapshot — a pair of:
meta_merkle_root: [u8; 32]— Merkle root of the entire stake distribution treesnapshot_hash: [u8; 32]— SHA-256 hash of the raw snapshot bytes (prevents two different snapshots from having the same root)
Two operators agree on a ballot if and only if both their root and hash match exactly.
BallotTally
A running count of votes for a single unique Ballot. The BallotBox maintains up to 64 tallies (one per unique ballot submitted). When a tally’s count first exceeds the consensus threshold, that ballot becomes the winning_ballot.
ConsensusResult
The final, immutable on-chain record of the agreed-upon snapshot. Created by finalize_ballot once consensus is reached. The svmgov program references this account to verify stake proofs.
PDA seeds: ["ConsensusResult", snapshot_slot.to_le_bytes()]
ProgramConfig
The global singleton configuration account for the ncn-snapshot program. Stores the operator whitelist, consensus threshold, tie-breaker admin, and vote duration.
PDA seeds: ["ProgramConfig"]
Tie-Breaker
A special admin key stored in ProgramConfig that can force a winner after voting expires but before consensus is reached. This prevents a permanently deadlocked BallotBox. When the tie-breaker sets a result, tie_breaker_consensus = true on the ConsensusResult.
Vote Duration
The number of seconds (from init_ballot_box) during which operators can cast and remove votes. After expiry: operators can no longer vote; the tie-breaker admin can act; and finalize_ballot can still be called if consensus was already reached before expiry.
Consensus Threshold (min_consensus_threshold_bps)
Expressed in basis points (1–10,000). A ballot wins when (votes_for_ballot / total_operators_in_voter_list) * 10,000 ≥ min_consensus_threshold_bps.
Merkle Tree Terms
MetaMerkleTree
The top-level Merkle tree. Each leaf represents one validator’s vote account. Contains the validator’s total active stake and a sub-tree root for their individual stake accounts.
MetaMerkleLeaf
A single leaf in the MetaMerkleTree:
| Field | Description |
|---|---|
voting_wallet | The wallet authorized to vote on behalf of this validator (may differ from withdraw authority for stake pools) |
vote_account | The Solana SPL vote account address |
stake_merkle_root | Root of the StakeMerkleTree for this validator’s delegators |
active_stake | Total lamports of active delegated stake |
Hash: SHA256(0x00 ‖ voting_wallet ‖ vote_account ‖ stake_merkle_root ‖ active_stake.le_bytes)
StakeMerkleTree
A per-validator subtree. Each leaf represents one individual stake account delegated to that validator.
StakeMerkleLeaf
A single leaf in the StakeMerkleTree:
| Field | Description |
|---|---|
voting_wallet | Same voting wallet as the parent MetaMerkleLeaf |
stake_account | The individual stake account address |
active_stake | Lamports of active stake in this account |
Hash: SHA256(0x00 ‖ voting_wallet ‖ stake_account ‖ active_stake.le_bytes)
MetaMerkleSnapshot
The compressed archive (.zip, gzip + Borsh) generated by the NCN CLI. Contains the root, slot, and all MetaMerkleLeafBundles (leaf data + proof paths).
MetaMerkleProof
A temporary on-chain account storing a validator’s proof path in the MetaMerkleTree. Used by the svmgov program during cast_vote to verify a validator’s stake weight without loading the entire snapshot.
PDA seeds: ["MetaMerkleProof", consensus_result_pubkey, vote_account_pubkey]
It carries a close_timestamp chosen by the payer; once that time has elapsed, anyone may close the account permissionlessly to reclaim its rent. The svmgov CLI defaults this to the proposal’s vote-expiry time so the proof stays protected for the duration of voting.
Voting Terms
Voter List
A snapshot of the whitelisted_operators list taken at init_ballot_box time. Stored directly in the BallotBox. This ensures that operators added or removed after ballot creation do not affect the quorum calculation.
OperatorVote
Records which ballot an operator voted for and at which slot. Stored in BallotBox.operator_votes.
Snapshot Slot
The specific Solana slot for which the stake snapshot was generated. Used as the seed for BallotBox and ConsensusResult PDAs. Must be in the future at init_ballot_box time (so a snapshot at that slot hasn’t been produced yet on testnet/mainnet, ensuring freshness).
Snapshot Hash
SHA256(borsh_serialized_decompressed_snapshot_bytes) — a content hash of the full snapshot. Two snapshots with the same Merkle root but different content (impossible in practice but possible via hash collision) are distinguished by this hash.
Basis Points (BPS)
Used for the consensus threshold. 10,000 bps = 100%. Example: min_consensus_threshold_bps = 6667 means at least 2/3 of operators must agree.