Skip to content

Conversation

@akhi3030
Copy link
Contributor

Problem

Summary of Changes

Fixes #

@akhi3030 akhi3030 force-pushed the akhi3030/pay-rewards branch 5 times, most recently from 53aebe8 to c2bf3d0 Compare November 20, 2025 18:17
@akhi3030 akhi3030 force-pushed the akhi3030/pay-rewards branch from c2bf3d0 to 817e89b Compare November 23, 2025 19:52
let mut accounts = Arc::unwrap_or_clone(self.vote_accounts());
let (_stake, account) = accounts.remove(&voter).unwrap();
let data = account.account().data_clone();
let mut vote_state: VoteStateV3 = bincode::deserialize(&data).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We want to be targetting VoteStateV4 here

let shared_account =
AccountSharedData::new_data(account.lamports(), &vote_state, account.owner()).unwrap();
// XXX: is the stake getting set properly?
self.store_account(&voter, &shared_account);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Generally prefer store_accounts when storing multiple accounts as AccountsDB is able to use its thread pool to do some of the stuff in parallel.

// XXX: pay the leader rewards
let _leader_reward_lamports = reward_lamports - validator_reward_lamports;

bank.pay_vote_reward(validator, validator_reward_lamports);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't quite correct as credits != lamports.

Here's how inflationary rewards are calculated. Let V be the validator set:
Let

points(v) = credits(v) * stake(v) for any validator v

If the total inflation this epoch is T

rewards(v) = T * points(v) / Sum_{u \in V}(points(u))

You can see the full details by poking around in the caller of

pub(crate) fn calculate_stake_points_and_credits(

Copy link
Contributor

@AshwinSekar AshwinSekar Nov 24, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We no longer want the sum of points in the denominator as in Alpenglow rewards are not based on relative performance.

When alpenglow is active we'll want to replace that with 432000 (slots per epoch) * total stake and then I believe you can just add 1 credit here.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry I realized that the leader also needs to be paid out for the same sol value. This is difficult because the leader's point calculation will multiply by the leader's stake rather than the voter's stake.

I'll need to think more about how to solve the leader's side of rewards.

}

pub(crate) fn pay_vote_reward(&self, voter: Pubkey, reward: u64) {
let mut accounts = Arc::unwrap_or_clone(self.vote_accounts());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might be able to avoid some of these clones with something like this

let Some((_, vote_account)) = self.vote_accounts().get(&voter) else {
  return;
};
let mut vote_state: VoteStateV4 = vote_account.account().deserialize_data();

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could even avoid the deserialize and calculate the offset into epoch credits to update if necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants