Skip to content

Commit

Permalink
Add get_stake_minimum_delegation() to rpc_client
Browse files Browse the repository at this point in the history
  • Loading branch information
brooksprumo committed May 13, 2022
1 parent 6cfa19e commit 990d7e0
Show file tree
Hide file tree
Showing 2 changed files with 80 additions and 2 deletions.
39 changes: 38 additions & 1 deletion client/src/nonblocking/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ use {
epoch_schedule::EpochSchedule,
fee_calculator::{FeeCalculator, FeeRateGovernor},
hash::Hash,
instruction::InstructionError,
message::Message,
pubkey::Pubkey,
signature::Signature,
transaction::{self, uses_durable_nonce, Transaction},
transaction::{self, uses_durable_nonce, Transaction, TransactionError},
},
solana_transaction_status::{
EncodedConfirmedBlock, EncodedConfirmedTransactionWithStatusMeta, TransactionStatus,
Expand Down Expand Up @@ -4507,6 +4508,42 @@ impl RpcClient {
parse_keyed_accounts(accounts, RpcRequest::GetProgramAccounts)
}

/// Returns the stake minimum delegation, in lamports.
pub async fn get_stake_minimum_delegation(&self) -> ClientResult<u64> {
let instruction = solana_sdk::stake::instruction::get_minimum_delegation();
let payer = None;
let transaction = Transaction::new_with_payer(&[instruction], payer);
let response = self.simulate_transaction(&transaction).await?;
let return_data = response
.value
.return_data
.ok_or_else(|| ClientErrorKind::Custom("return data was empty".to_string()))?;
let (program_id, data) = (return_data.program_id, return_data.data);
if Pubkey::from_str(&program_id) != Ok(solana_sdk::stake::program::id()) {
return Err(TransactionError::InstructionError(
0,
InstructionError::IncorrectProgramId,
)
.into());
}
if data.1 != ReturnDataEncoding::Base64 {
return Err(
ClientErrorKind::Custom("return data encoding is invalid".to_string()).into(),
);
}
let data = base64::decode(data.0).map_err(|err| {
ClientErrorKind::Custom(format!("failed to decode return data: {}", err))
})?;
let minimum_delegation = u64::from_le_bytes(data.try_into().map_err(|data: Vec<u8>| {
ClientErrorKind::Custom(format!(
"return data cannot be represented as a u64: expected size: {}, actual size: {}",
std::mem::size_of::<u64>(),
data.len()
))
})?);
Ok(minimum_delegation)
}

/// Request the transaction count.
pub async fn get_transaction_count(&self) -> ClientResult<u64> {
self.get_transaction_count_with_commitment(self.commitment())
Expand Down
43 changes: 42 additions & 1 deletion client/src/rpc_client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3711,6 +3711,11 @@ impl RpcClient {
)
}

/// Returns the stake minimum delegation, in lamports.
pub fn get_stake_minimum_delegation(&self) -> ClientResult<u64> {
self.invoke(self.rpc_client.get_stake_minimum_delegation())
}

/// Request the transaction count.
pub fn get_transaction_count(&self) -> ClientResult<u64> {
self.invoke(self.rpc_client.get_transaction_count())
Expand Down Expand Up @@ -4097,7 +4102,7 @@ mod tests {
system_transaction,
transaction::TransactionError,
},
std::{io, thread},
std::{collections::HashMap, io, thread},
};

#[test]
Expand Down Expand Up @@ -4313,4 +4318,40 @@ mod tests {
let is_err = rpc_client.get_latest_blockhash().is_err();
assert!(is_err);
}

#[test]
fn test_get_stake_minimum_delegation() {
let expected_minimum_delegation: u64 = 123_456_789;
let rpc_client = {
let mocks = {
let rpc_response = {
let program_id = solana_sdk::stake::program::id().to_string();
let data = (
base64::encode(expected_minimum_delegation.to_le_bytes()),
ReturnDataEncoding::Base64,
);
serde_json::to_value(Response {
context: RpcResponseContext { slot: 1 },
value: RpcSimulateTransactionResult {
err: None,
logs: None,
accounts: None,
units_consumed: None,
return_data: Some(RpcTransactionReturnData { program_id, data }),
},
})
.unwrap()
};
let mut mocks = HashMap::new();
mocks.insert(RpcRequest::SimulateTransaction, rpc_response);
mocks
};
RpcClient::new_mock_with_mocks("succeeds".to_string(), mocks)
};

let client_result = rpc_client.get_stake_minimum_delegation();
assert!(client_result.is_ok());
let actual_minimum_delegation = client_result.unwrap();
assert_eq!(actual_minimum_delegation, expected_minimum_delegation);
}
}

0 comments on commit 990d7e0

Please sign in to comment.