add create_delegate_stake_account (#4197)
This commit is contained in:
parent
69eeb7cf08
commit
401764ddb1
|
@ -2649,7 +2649,6 @@ dependencies = [
|
|||
"serde_derive 1.0.90 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"solana-logger 0.15.0",
|
||||
"solana-metrics 0.15.0",
|
||||
"solana-runtime 0.15.0",
|
||||
"solana-sdk 0.15.0",
|
||||
"solana-vote-api 0.15.0",
|
||||
]
|
||||
|
|
|
@ -18,9 +18,6 @@ solana-metrics = { path = "../../metrics", version = "0.15.0" }
|
|||
solana-sdk = { path = "../../sdk", version = "0.15.0" }
|
||||
solana-vote-api = { path = "../vote_api", version = "0.15.0" }
|
||||
|
||||
[dev-dependencies]
|
||||
solana-runtime = { path = "../../runtime", version = "0.15.0" }
|
||||
|
||||
[lib]
|
||||
name = "solana_stake_api"
|
||||
crate-type = ["lib"]
|
||||
|
|
|
@ -22,14 +22,14 @@ pub enum StakeInstruction {
|
|||
RedeemVoteCredits,
|
||||
}
|
||||
|
||||
pub fn create_account(from_id: &Pubkey, staker_id: &Pubkey, lamports: u64) -> Vec<Instruction> {
|
||||
vec![system_instruction::create_account(
|
||||
pub fn create_account(from_id: &Pubkey, staker_id: &Pubkey, lamports: u64) -> Instruction {
|
||||
system_instruction::create_account(
|
||||
from_id,
|
||||
staker_id,
|
||||
lamports,
|
||||
std::mem::size_of::<StakeState>() as u64,
|
||||
&id(),
|
||||
)]
|
||||
)
|
||||
}
|
||||
|
||||
pub fn redeem_vote_credits(
|
||||
|
@ -104,13 +104,59 @@ mod tests {
|
|||
use bincode::serialize;
|
||||
use solana_sdk::account::Account;
|
||||
|
||||
fn process_instruction(instruction: &Instruction) -> Result<(), InstructionError> {
|
||||
let mut accounts = vec![];
|
||||
for _ in 0..instruction.accounts.len() {
|
||||
accounts.push(Account::default());
|
||||
}
|
||||
{
|
||||
let mut keyed_accounts: Vec<_> = instruction
|
||||
.accounts
|
||||
.iter()
|
||||
.zip(accounts.iter_mut())
|
||||
.map(|(meta, account)| KeyedAccount::new(&meta.pubkey, meta.is_signer, account))
|
||||
.collect();
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&mut keyed_accounts,
|
||||
&instruction.data,
|
||||
0,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stake_process_instruction() {
|
||||
assert_eq!(
|
||||
process_instruction(&create_account(&Pubkey::default(), &Pubkey::default(), 0)),
|
||||
Err(InstructionError::InvalidInstructionData) // won't even decode ;)
|
||||
);
|
||||
assert_eq!(
|
||||
process_instruction(&redeem_vote_credits(
|
||||
&Pubkey::default(),
|
||||
&Pubkey::default(),
|
||||
&Pubkey::default(),
|
||||
&Pubkey::default()
|
||||
)),
|
||||
Err(InstructionError::InvalidAccountData),
|
||||
);
|
||||
assert_eq!(
|
||||
process_instruction(&delegate_stake(
|
||||
&Pubkey::default(),
|
||||
&Pubkey::default(),
|
||||
&Pubkey::default()
|
||||
)),
|
||||
Err(InstructionError::InvalidAccountData),
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stake_process_instruction_decode_bail() {
|
||||
// these will not call stake_state, have bogus contents
|
||||
|
||||
// gets the first check
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&mut [KeyedAccount::new(
|
||||
&Pubkey::default(),
|
||||
|
@ -123,12 +169,12 @@ mod tests {
|
|||
Err(InstructionError::InvalidInstructionData),
|
||||
);
|
||||
|
||||
// gets the check in delegate_stake
|
||||
// gets the sub-check for number of args
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&mut [
|
||||
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
|
||||
KeyedAccount::new(&Pubkey::default(), true, &mut Account::default()),
|
||||
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
|
||||
],
|
||||
&serialize(&StakeInstruction::DelegateStake).unwrap(),
|
||||
|
@ -137,9 +183,8 @@ mod tests {
|
|||
Err(InstructionError::InvalidInstructionData),
|
||||
);
|
||||
|
||||
// gets the check in redeem_vote_credits
|
||||
assert_eq!(
|
||||
process_instruction(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&mut [
|
||||
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
|
||||
|
@ -151,6 +196,37 @@ mod tests {
|
|||
),
|
||||
Err(InstructionError::InvalidInstructionData),
|
||||
);
|
||||
|
||||
// gets the check in delegate_stake
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&mut [
|
||||
KeyedAccount::new(&Pubkey::default(), true, &mut Account::default()), // from
|
||||
KeyedAccount::new(&Pubkey::default(), true, &mut Account::default()),
|
||||
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
|
||||
],
|
||||
&serialize(&StakeInstruction::DelegateStake).unwrap(),
|
||||
0,
|
||||
),
|
||||
Err(InstructionError::InvalidAccountData),
|
||||
);
|
||||
|
||||
// gets the check in redeem_vote_credits
|
||||
assert_eq!(
|
||||
super::process_instruction(
|
||||
&Pubkey::default(),
|
||||
&mut [
|
||||
KeyedAccount::new(&Pubkey::default(), true, &mut Account::default()), // from
|
||||
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
|
||||
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
|
||||
KeyedAccount::new(&Pubkey::default(), false, &mut Account::default()),
|
||||
],
|
||||
&serialize(&StakeInstruction::RedeemVoteCredits).unwrap(),
|
||||
0,
|
||||
),
|
||||
Err(InstructionError::InvalidAccountData),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -3,10 +3,9 @@
|
|||
//! * keep track of rewards
|
||||
//! * own mining pools
|
||||
|
||||
//use crate::{check_id, id};
|
||||
//use log::*;
|
||||
use crate::id;
|
||||
use serde_derive::{Deserialize, Serialize};
|
||||
use solana_sdk::account::KeyedAccount;
|
||||
use solana_sdk::account::{Account, KeyedAccount};
|
||||
use solana_sdk::instruction::InstructionError;
|
||||
use solana_sdk::instruction_processor_utils::State;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
|
@ -40,7 +39,7 @@ const CREDITS_PER_YEAR: f64 = (365f64 * 24f64 * 3600f64) * TICKS_PER_SECOND / TI
|
|||
const STAKE_REWARD_TARGET_RATE: f64 = 0.20;
|
||||
|
||||
#[cfg(test)]
|
||||
const STAKE_GETS_PAID_EVERY_VOTE: u64 = 200_000_000; // if numbers above move, fix this
|
||||
const STAKE_GETS_PAID_EVERY_VOTE: u64 = 200_000_000; // if numbers above (TICKS_YEAR) move, fix this
|
||||
|
||||
impl StakeState {
|
||||
pub fn calculate_rewards(
|
||||
|
@ -148,6 +147,24 @@ impl<'a> StakeAccount for KeyedAccount<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// utility function, used by Bank, tests, genesis
|
||||
pub fn create_delegate_stake_account(
|
||||
voter_id: &Pubkey,
|
||||
vote_state: &VoteState,
|
||||
lamports: u64,
|
||||
) -> Account {
|
||||
let mut stake_account = Account::new(lamports, std::mem::size_of::<StakeState>(), &id());
|
||||
|
||||
stake_account
|
||||
.set_state(&StakeState::Delegate {
|
||||
voter_id: *voter_id,
|
||||
credits_observed: vote_state.credits(),
|
||||
})
|
||||
.expect("set_state");
|
||||
|
||||
stake_account
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
@ -159,6 +176,8 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn test_stake_delegate_stake() {
|
||||
dbg!(std::env::var("CARGO_FOO").unwrap_or("not set".to_string()));
|
||||
|
||||
let vote_keypair = Keypair::new();
|
||||
let mut vote_state = VoteState::default();
|
||||
for i in 0..1000 {
|
||||
|
@ -176,6 +195,11 @@ mod tests {
|
|||
|
||||
let mut stake_keyed_account = KeyedAccount::new(&stake_pubkey, false, &mut stake_account);
|
||||
|
||||
{
|
||||
let stake_state: StakeState = stake_keyed_account.state().unwrap();
|
||||
assert_eq!(stake_state, StakeState::default());
|
||||
}
|
||||
|
||||
assert_eq!(
|
||||
stake_keyed_account.delegate_stake(&vote_keyed_account),
|
||||
Err(InstructionError::MissingRequiredSignature)
|
||||
|
@ -186,6 +210,13 @@ mod tests {
|
|||
.delegate_stake(&vote_keyed_account)
|
||||
.is_ok());
|
||||
|
||||
// verify that create_delegate_stake_account() matches the
|
||||
// resulting account from delegate_stake()
|
||||
assert_eq!(
|
||||
create_delegate_stake_account(&vote_pubkey, &vote_state, 0),
|
||||
*stake_keyed_account.account,
|
||||
);
|
||||
|
||||
let stake_state: StakeState = stake_keyed_account.state().unwrap();
|
||||
assert_eq!(
|
||||
stake_state,
|
||||
|
@ -194,6 +225,7 @@ mod tests {
|
|||
credits_observed: vote_state.credits()
|
||||
}
|
||||
);
|
||||
|
||||
let stake_state = StakeState::MiningPool;
|
||||
stake_keyed_account.set_state(&stake_state).unwrap();
|
||||
assert!(stake_keyed_account
|
||||
|
|
Loading…
Reference in New Issue