Add convenience function for programs to get minimum delegation (#24175)
This commit is contained in:
parent
b4b26894cd
commit
e146e860e2
|
@ -3032,6 +3032,13 @@ dependencies = [
|
|||
"solana-program 1.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-get-minimum-delegation"
|
||||
version = "1.11.0"
|
||||
dependencies = [
|
||||
"solana-program 1.11.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "solana-bpf-rust-instruction-introspection"
|
||||
version = "1.11.0"
|
||||
|
|
|
@ -57,6 +57,7 @@ members = [
|
|||
"rust/error_handling",
|
||||
"rust/log_data",
|
||||
"rust/external_spend",
|
||||
"rust/get_minimum_delegation",
|
||||
"rust/finalize",
|
||||
"rust/instruction_introspection",
|
||||
"rust/invoke",
|
||||
|
|
|
@ -70,6 +70,7 @@ fn main() {
|
|||
"log_data",
|
||||
"external_spend",
|
||||
"finalize",
|
||||
"get_minimum_delegation",
|
||||
"instruction_introspection",
|
||||
"invoke",
|
||||
"invoke_and_error",
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
[package]
|
||||
name = "solana-bpf-rust-get-minimum-delegation"
|
||||
version = "1.11.0"
|
||||
description = "Solana BPF test program written in Rust"
|
||||
authors = ["Solana Maintainers <maintainers@solana.foundation>"]
|
||||
repository = "https://github.com/solana-labs/solana"
|
||||
license = "Apache-2.0"
|
||||
homepage = "https://solana.com/"
|
||||
documentation = "https://docs.rs/solana-bpf-rust-get-minimum-delegation"
|
||||
edition = "2021"
|
||||
|
||||
[dependencies]
|
||||
solana-program = { path = "../../../../sdk/program", version = "=1.11.0" }
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
targets = ["x86_64-unknown-linux-gnu"]
|
|
@ -0,0 +1,23 @@
|
|||
//! Example/test program to get the minimum stake delegation via the helper function
|
||||
|
||||
#![allow(unreachable_code)]
|
||||
|
||||
extern crate solana_program;
|
||||
use solana_program::{
|
||||
account_info::AccountInfo, entrypoint::ProgramResult, msg, pubkey::Pubkey, stake,
|
||||
};
|
||||
|
||||
solana_program::entrypoint!(process_instruction);
|
||||
#[allow(clippy::unnecessary_wraps)]
|
||||
fn process_instruction(
|
||||
_program_id: &Pubkey,
|
||||
_accounts: &[AccountInfo],
|
||||
_instruction_data: &[u8],
|
||||
) -> ProgramResult {
|
||||
let minimum_delegation = stake::tools::get_minimum_delegation()?;
|
||||
msg!(
|
||||
"The minimum stake delegation is {} lamports",
|
||||
minimum_delegation
|
||||
);
|
||||
Ok(())
|
||||
}
|
|
@ -56,6 +56,7 @@ use {
|
|||
pubkey::Pubkey,
|
||||
rent::Rent,
|
||||
signature::{keypair_from_seed, Keypair, Signer},
|
||||
stake,
|
||||
system_instruction::{self, MAX_PERMITTED_DATA_LENGTH},
|
||||
system_program,
|
||||
sysvar::{self, clock, rent},
|
||||
|
@ -3522,3 +3523,32 @@ fn test_program_fees() {
|
|||
let post_balance = bank_client.get_balance(&mint_keypair.pubkey()).unwrap();
|
||||
assert_eq!(pre_balance - post_balance, expected_min_fee);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "bpf_rust")]
|
||||
fn test_get_minimum_delegation() {
|
||||
let GenesisConfigInfo {
|
||||
genesis_config,
|
||||
mint_keypair,
|
||||
..
|
||||
} = create_genesis_config(100_123_456_789);
|
||||
let mut bank = Bank::new_for_tests(&genesis_config);
|
||||
bank.feature_set = Arc::new(FeatureSet::all_enabled());
|
||||
|
||||
let (name, id, entrypoint) = solana_bpf_loader_program!();
|
||||
bank.add_builtin(&name, &id, entrypoint);
|
||||
let bank = Arc::new(bank);
|
||||
let bank_client = BankClient::new_shared(&bank);
|
||||
|
||||
let program_id = load_bpf_program(
|
||||
&bank_client,
|
||||
&bpf_loader::id(),
|
||||
&mint_keypair,
|
||||
"solana_bpf_rust_get_minimum_delegation",
|
||||
);
|
||||
|
||||
let account_metas = vec![AccountMeta::new_readonly(stake::program::id(), false)];
|
||||
let instruction = Instruction::new_with_bytes(program_id, &[], account_metas);
|
||||
let result = bank_client.send_and_confirm_instruction(&mint_keypair, instruction);
|
||||
assert!(result.is_ok());
|
||||
}
|
||||
|
|
|
@ -228,8 +228,11 @@ pub enum StakeInstruction {
|
|||
/// # Account references
|
||||
/// None
|
||||
///
|
||||
/// The minimum delegation will be returned via the transaction context's returndata.
|
||||
/// Use `get_return_data()` to retrieve the result.
|
||||
/// Returns the minimum delegation as a little-endian encoded u64 value.
|
||||
/// Programs can use the [`get_minimum_delegation()`] helper function to invoke and
|
||||
/// retrieve the return value for this instruction.
|
||||
///
|
||||
/// [`get_minimum_delegation()`]: super::tools::get_minimum_delegation
|
||||
GetMinimumDelegation,
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
pub mod config;
|
||||
pub mod instruction;
|
||||
pub mod state;
|
||||
pub mod tools;
|
||||
|
||||
pub mod program {
|
||||
crate::declare_id!("Stake11111111111111111111111111111111111111");
|
||||
|
|
|
@ -0,0 +1,38 @@
|
|||
//! Utility functions
|
||||
use crate::program_error::ProgramError;
|
||||
|
||||
/// Helper function for programs to call [`GetMinimumDelegation`] and then fetch the return data
|
||||
///
|
||||
/// This fn handles performing the CPI to call the [`GetMinimumDelegation`] function, and then
|
||||
/// calls [`get_return_data()`] to fetch the return data.
|
||||
///
|
||||
/// [`GetMinimumDelegation`]: super::instruction::StakeInstruction::GetMinimumDelegation
|
||||
/// [`get_return_data()`]: crate::program::get_return_data
|
||||
pub fn get_minimum_delegation() -> Result<u64, ProgramError> {
|
||||
let instruction = super::instruction::get_minimum_delegation();
|
||||
crate::program::invoke_unchecked(&instruction, &[])?;
|
||||
get_minimum_delegation_return_data()
|
||||
}
|
||||
|
||||
/// Helper function for programs to get the return data after calling [`GetMinimumDelegation`]
|
||||
///
|
||||
/// This fn handles calling [`get_return_data()`], ensures the result is from the correct
|
||||
/// program, and returns the correct type.
|
||||
///
|
||||
/// [`GetMinimumDelegation`]: super::instruction::StakeInstruction::GetMinimumDelegation
|
||||
/// [`get_return_data()`]: crate::program::get_return_data
|
||||
fn get_minimum_delegation_return_data() -> Result<u64, ProgramError> {
|
||||
crate::program::get_return_data()
|
||||
.ok_or(ProgramError::InvalidInstructionData)
|
||||
.and_then(|(program_id, return_data)| {
|
||||
(program_id == super::program::id())
|
||||
.then(|| return_data)
|
||||
.ok_or(ProgramError::IncorrectProgramId)
|
||||
})
|
||||
.and_then(|return_data| {
|
||||
return_data
|
||||
.try_into()
|
||||
.or(Err(ProgramError::InvalidInstructionData))
|
||||
})
|
||||
.map(u64::from_le_bytes)
|
||||
}
|
Loading…
Reference in New Issue