anza-xyz / anza-xyz/solana-rpc-client-extensions

Past epoch stake activation

Aperta
#21 2 commenti 0 reazioni 0 assegnatari Vedi su GitHub
Lingua principale
TypeScript
Stelle
20
Fork
18
Metriche di merge delle PR
Nessuna PR unita negli ultimi 30g

Descrizione

Hi, I want to share something I built on top of this library and ask for feedback on why it worked at first but then broke.
This library is designed to get stake activation for the current epoch.

I extended it to query stake activation for a specific past epoch by adding a get_stake_activation_by_epoch function.
- I removed rpc_client.get_epoch_info()
- I pass the user-supplied epoch to stake_activating_and_deactivating instead of epoch_info.epoch

```
pub fn get_stake_activation_by_epoch(
rpc_client: &RpcClient,
stake: &Pubkey,
epoch: u64
) -> ClientResult {
let stake_account = rpc_client.get_account(stake)?;
let stake_history_account = rpc_client.get_account(&stake_history::id())?;

let stake_state = bincode::deserialize::(&stake_account.data).map_err(|_| {
Error::from(ErrorKind::Custom(
"Invalid param: stake account not initialized".to_string(),
))
})?;

let delegation = stake_state.delegation();
let rent_exempt_reserve = stake_state
.meta()
.ok_or_else(|| {
Error::from(ErrorKind::Custom(
"Invalid param: stake account not initialized".to_string(),
))
})?
.rent_exempt_reserve;

let delegation = match delegation {
None => {
return Ok(StakeActivation {
state: StakeActivationState::Inactive,
active: 0,
inactive: stake_account.lamports().saturating_sub(rent_exempt_reserve),
})
}
Some(delegation) => delegation,
};

let stake_history =
from_account::(&stake_history_account).ok_or(Error::from(
ErrorKind::Custom("Invalid param: stake history not deserializable".to_string()),
))?;

let StakeActivationStatus {
effective,
activating,
deactivating,
} = delegation.stake_activating_and_deactivating(epoch, &stake_history, Some(0));

let stake_activation_state = if deactivating > 0 {
StakeActivationState::Deactivating
} else if activating > 0 {
StakeActivationState::Activating
} else if effective > 0 {
StakeActivationState::Active
} else {
StakeActivationState::Inactive
};

let inactive_stake = stake_account
.lamports()
.saturating_sub(effective)
.saturating_sub(rent_exempt_reserve);

Ok(StakeActivation {
state: stake_activation_state,
active: effective,
inactive: inactive_stake,
})
}
```
- This worked correctly from approximately January 2025 to June 2025
- Around July 2025 it started returning current active stake value regardless of which past epoch I queried

**My questions**
1. Was my approach fundamentally wrong?
2. If it was wrong, why did it return seemingly correct results for the first 6 months?

Guida per i contributori

Nessuna guida per i contributori indicizzata per questo repository

Valutazione

Questa issue non è ancora stata valutata.

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.