diff --git a/README.md b/README.md index efb6ae2..2b786b6 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,6 @@ # solana-rpc-v2 A new repo to replace existing solana json rpc implementation, which will work on geyser plugins. + +geyser plugin conf modification: + - "channel_capacity": "100_000_000", + - "account_include_any": true, diff --git a/stake_aggregate/Cargo.toml b/stake_aggregate/Cargo.toml index ceb89b5..aa78e55 100644 --- a/stake_aggregate/Cargo.toml +++ b/stake_aggregate/Cargo.toml @@ -3,6 +3,10 @@ name = "stake_aggregate" version = "0.1.0" edition = "2021" +[[bin]] +name = "readsa" +path = "bin/readsa.rs" + # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] diff --git a/stake_aggregate/bin/readsa.rs b/stake_aggregate/bin/readsa.rs new file mode 100644 index 0000000..1034497 --- /dev/null +++ b/stake_aggregate/bin/readsa.rs @@ -0,0 +1,57 @@ +//cargo run --bin readsa HT9SLHiq4ARRUS7EsCK3EZh3MutRR73ts1fojzHwJYvh + +use anyhow::bail; +use borsh::de::BorshDeserialize; +use solana_client::nonblocking::rpc_client::RpcClient; +use solana_sdk::commitment_config::CommitmentConfig; +use solana_sdk::pubkey::Pubkey; +use solana_sdk::stake::state::Delegation; +use solana_sdk::stake::state::StakeState; +use std::env; +use std::str::FromStr; + +const RPC_URL: &str = "http://localhost:8899"; + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + tracing_subscriber::fmt::init(); + + let args: Vec = env::args().collect(); + + println!("args:{args:?}"); + + if args.len() <= 1 { + eprintln!("Please provide account pubkey"); + std::process::exit(1); + } + + let pk_str: String = args[1].parse().expect("First argument should be a String"); + + let rpc_client = + RpcClient::new_with_commitment(RPC_URL.to_string(), CommitmentConfig::confirmed()); + + // Fetch current epoch + let account = rpc_client + .get_account(&Pubkey::from_str(&pk_str).expect("invalid pubkey")) + .await?; + + let stake = read_stake_from_account_data(account.data.as_slice())?; + + println!("account:{pk_str} stake:{:?}", stake); + + Ok(()) +} + +fn read_stake_from_account_data(mut data: &[u8]) -> anyhow::Result> { + if data.is_empty() { + log::warn!("Stake account with empty data. Can't read stake."); + bail!("Error: read Stake account with empty data"); + } + match StakeState::deserialize(&mut data)? { + StakeState::Stake(_, stake) => Ok(Some(stake.delegation)), + StakeState::Initialized(_) => Ok(None), + other => { + bail!("read stake from account not a stake account. read:{other:?}"); + } + } +} diff --git a/stake_aggregate/src/stakestore.rs b/stake_aggregate/src/stakestore.rs index 73c0602..7429ca1 100644 --- a/stake_aggregate/src/stakestore.rs +++ b/stake_aggregate/src/stakestore.rs @@ -46,7 +46,12 @@ fn stake_map_insert_stake( std::collections::hash_map::Entry::Occupied(occupied) => { let strstake = occupied.into_mut(); // <-- get mut reference to existing value if strstake.last_update_slot < stake.last_update_slot { - log::info!("Stake updated for: {stake_account} stake:{stake:?}"); + if strstake.stake.stake != stake.stake.stake { + log::info!( + "Stake updated for: {stake_account} old_stake:{} stake:{stake:?}", + stake.stake.stake + ); + } *strstake = stake; } }