Node Operator Client
Solana Epoch Snapshot
Once an epoch completes, the operator client takes a snapshot of the Bank from the last existing block of the previous epoch.
Generate Tip Distribution Merkle Trees and Meta Merkle Root
Using the Bank, the client constructs the StakeMetaCollection, which includes details about each validator, their tip distribution account, and the active delegations (stake accounts) on that validator.
Based on the StakeMetaCollection, the client generates Merkle trees for each validator, resulting in the GeneratedMerkleTreeCollection. Each tree contains a set of "claimants," which include all the validator's stake accounts, an additional claimant representing the validator’s share of tips (calculated using their mev_commission_bps from the tip distribution account), and a claimant for the fee allocated to the TipRouter.
Details about the TipRouter claimant:
- The inclusion of this claimant is the primary difference between the current creation process for
StakeMetaCollectionandGeneratedMerkleTreeCollectioncompared to the prior approach injito-solana/tip-distributor. - The amount for the
TipRouterclaimant is calculated by multiplying the validator's total tips by theTipRouter'sNcnConfig.fees_config.total_fees_bps(), which aggregates the BaseFees and NcnFees. - The
TipRouterfee represents a percentage of fees assessed on each validator's tips. The program only holds the complete fee once all validators’TipRouterclaimants have been claimed. - The fee's destination is a dedicated Program Derived Address (PDA) for each epoch, known as the
BaseRewardReceiver.
Finally, a MetaMerkleTree is created from the GeneratedMerkleTreeCollection.
Cast Vote
Once the meta_merkle_root is created, the operator submits their vote by calling the cast_vote instruction, provided the BallotBox, EpochSnapshot, and OperatorSnapshot accounts have already been initialized.