Skip to content

Commit

Permalink
Merge pull request #35 from Shi-eld/maintainer_fix
Browse files Browse the repository at this point in the history
Maintainer fix
  • Loading branch information
Shi-eld authored Apr 2, 2024
2 parents 7afcb98 + 5a0b9d9 commit 6d63d9f
Show file tree
Hide file tree
Showing 5 changed files with 98 additions and 77 deletions.
31 changes: 23 additions & 8 deletions cli/common/src/snapshot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ use spl_token::solana_program::hash::Hash;
use crate::error::{
self, Error, MissingAccountError, MissingValidatorInfoError, SerializationError,
};
use crate::validator_info_utils::ValidatorInfo;
//use crate::validator_info_utils::ValidatorInfo;

pub enum SnapshotError {
/// We tried to access an account, but it was not present in the snapshot.
Expand Down Expand Up @@ -299,19 +299,33 @@ impl<'a> Snapshot<'a> {

/// Read and parse the vote account at the given address.
pub fn get_vote_account(&mut self, address: &Pubkey) -> crate::Result<VoteState> {
let vote_account = self.get_account(address)?;
let vote_state = VoteState::deserialize(vote_account.data()).map_err(|err| {
let account = self.get_account(address)?;
let mut pubkey_buf: [u8; 32] = Default::default();
// Read 32 bytes for Pubkey.
pubkey_buf.copy_from_slice(&account.data[..32]);
let node_pubkey = Pubkey::new_from_array(pubkey_buf);
let vote_state = VoteState::from(account).ok_or_else(|| {
let wrapped_err = SerializationError {
context: "While deserializing vote account.".to_string(),
cause: Some(err.into()),
cause: None,
address: *address,
};
let result: Error = Box::new(wrapped_err);
result
})?;
})?;
Ok(vote_state)
}

pub fn get_node_pubkey(&mut self, address: &Pubkey) -> crate::Result<Pubkey> {
let account = self.get_account(address)?;
let mut pubkey_buf: [u8; 32] = Default::default();
// Read 32 bytes for Pubkey.
pubkey_buf.copy_from_slice(&account.data[4..36]);
let node_pubkey = Pubkey::new_from_array(pubkey_buf);
Ok(node_pubkey)
}


/// Return the minimum rent-exempt balance for an account with `data_len` bytes of data.
pub fn get_minimum_balance_for_rent_exemption(
&mut self,
Expand All @@ -322,7 +336,7 @@ impl<'a> Snapshot<'a> {
}

/// Return the metadata of the validator with the given identity account.
pub fn get_validator_info(
/* pub fn get_validator_info(
&mut self,
validator_identity: &Pubkey,
) -> crate::Result<ValidatorInfo> {
Expand All @@ -346,7 +360,7 @@ impl<'a> Snapshot<'a> {
// We need to refresh our mapping.
Err(SnapshotError::MissingValidatorIdentity(*validator_identity))
}
}
} */

/// Read the account and deserialize the Solido struct.
pub fn get_solido(&mut self, solido_address: &Pubkey) -> crate::Result<Lido> {
Expand Down Expand Up @@ -646,10 +660,11 @@ impl SnapshotClient {
// account for, so we need to reload those. After we do,
// confirm that the validator identity is there, otherwise
// we would get stuck in an infinite loop.
self.validator_info_addrs =
/* self.validator_info_addrs =
crate::validator_info_utils::get_validator_info_accounts(
&mut self.rpc_client,
)?;
*/

if !self.validator_info_addrs.contains_key(&identity_addr) {
return Err(Box::new(MissingValidatorInfoError {
Expand Down
57 changes: 30 additions & 27 deletions cli/common/src/validator_info_utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ use crate::error::{Error, SerializationError};

type Result<T> = std::result::Result<T, Error>;

/// Validator metadata stored in a config account managed by the config program.
#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
pub struct ValidatorInfo {
// Validator metadata stored in a config account managed by the config program.
//#[derive(Debug, Deserialize, Serialize, Eq, PartialEq)]
/* pub struct ValidatorInfo {
pub name: String,
// Rename the field because this is how Solana stores it, it needs to have
Expand All @@ -24,22 +24,21 @@ pub struct ValidatorInfo {
pub keybase_username: Option<String>,
// Other keys that can be present in the json object are "details" and
// "website", but we have no need for those at this point.
}

/// Deserialize a config account that contains validator info.
///
/// Returns the validator identity account address, and the validator info for
/// that validator. The config address is not related to the validator identity
/// address or any other validator property; to find the config account for a
/// given validator, we have to deserialize all config accounts that exist, and
/// filter for the one that belongs to a given identity account. See
/// [`get_validator_info_accounts`] for that.
pub fn deserialize_validator_info(
} */
// Deserialize a config account that contains validator info.
//
// Returns the validator identity account address, and the validator info for
// that validator. The config address is not related to the validator identity
// address or any other validator property; to find the config account for a
// given validator, we have to deserialize all config accounts that exist, and
// filter for the one that belongs to a given identity account. See
// [`get_validator_info_accounts`] for that.
/* pub fn deserialize_validator_info(
config_address: Pubkey,
account_data: &[u8],
) -> Result<(Pubkey, ValidatorInfo)> {
let key_list: ConfigKeys = bincode::deserialize(account_data)?;
let key_list: ConfigKeys = bincode::deserialize(account_data)?;
// I don't know the meaning of the boolean here, but this is what `solana validator-info get`
// uses to check if a config account contains validator info.
if !key_list.keys.contains(&(validator_info::id(), false)) {
Expand All @@ -48,9 +47,9 @@ pub fn deserialize_validator_info(
cause: None,
address: config_address,
};
println!("ERROR {}", config_address);
return Err(Box::new(err));
}

// The validator identity pubkey lives at index 1.
let (validator_identity, identity_signed_config) = key_list.keys[1];
Expand All @@ -72,22 +71,21 @@ pub fn deserialize_validator_info(
as usize;
let json_data: String = bincode::deserialize(&account_data[key_list_len..])?;
let validator_info: ValidatorInfo = serde_json::from_str(&json_data)?;

Ok((validator_identity, validator_info))
}
/// Return a map from validator identity account to config account.
///
/// To get the validator info (the validator metadata, such as name and Keybase
/// username), we have to extract that from the config account that stores the
/// validator info for a particular validator. But there is no way a priori to
/// know the address of the config account for a given validator; the only way
/// is to enumerate all config accounts and then find the one you are looking
/// for. This function builds a map from identity account to config account, so
/// we only have to enumerate once.
// Return a map from validator identity account to config account.
//
// To get the validator info (the validator metadata, such as name and Keybase
// username), we have to extract that from the config account that stores the
// validator info for a particular validator. But there is no way a priori to
// know the address of the config account for a given validator; the only way
// is to enumerate all config accounts and then find the one you are looking
// for. This function builds a map from identity account to config account, so
// we only have to enumerate once.
pub fn get_validator_info_accounts(rpc_client: &mut RpcClient) -> Result<HashMap<Pubkey, Pubkey>> {
use solana_sdk::config::program as config_program;

println!("get_validator_info_accounts");
let all_config_accounts = rpc_client.get_program_accounts(&config_program::id())?;
let mut mapping = HashMap::new();
Expand All @@ -107,9 +105,12 @@ pub fn get_validator_info_accounts(rpc_client: &mut RpcClient) -> Result<HashMap
// we can read it atomically together with other accounts.
let old_config_addr = mapping.insert(validator_identity, *config_addr);
if old_config_addr.is_some() {
println!("BAD {}", validator_identity);
bad_identities.insert(validator_identity);
}
} else {
println!("ERR");
// We ignore errors here: not all config accounts need to contain
// validator info, so if we fail to deserialize the config account,
// that is not fatal, it just means this is not an account that
Expand All @@ -118,6 +119,7 @@ pub fn get_validator_info_accounts(rpc_client: &mut RpcClient) -> Result<HashMap
}
for bad_identity in &bad_identities {
println!("BAD REMOVED {}", bad_identity);
mapping.remove(bad_identity);
}
Expand Down Expand Up @@ -159,3 +161,4 @@ mod test {
)
}
}
*/
35 changes: 18 additions & 17 deletions cli/maintainer/src/commands_solido.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ use solana_stake_program::stake_state::StakeState;
use solido_cli_common::{
error::{CliError, Error},
snapshot::{SnapshotClientConfig, SnapshotConfig},
validator_info_utils::ValidatorInfo,
//validator_info_utils::ValidatorInfo,
};

use crate::{
Expand Down Expand Up @@ -441,7 +441,7 @@ pub struct ShowSolidoOutput {
pub validator_identities: Vec<Pubkey>,

/// Contains validator info in the same order as `solido.validators`.
pub validator_infos: Vec<ValidatorInfo>,
//pub validator_infos: Vec<ValidatorInfo>,

/// Contains validator fees in the same order as `solido.validators`.
pub validator_commission_percentages: Vec<u8>,
Expand Down Expand Up @@ -586,31 +586,31 @@ impl fmt::Display for ShowSolidoOutput {
self.validators.len(),
self.validators.header.max_entries
)?;
for (((pe, identity), info), commission) in self
for ((pe, identity), commission) in self
.validators
.entries
.iter()
.zip(&self.validator_identities)
.zip(&self.validator_infos)
//.zip(&self.validator_infos)
.zip(&self.validator_commission_percentages)
{
writeln!(
f,
"\n - \
Name: {}\n \
Keybase username: {}\n \
Name: \n \
Keybase username: \n \
Vote account: {}\n \
Identity account: {}\n \
Commission: {}%\n \
Active: {}\n \
Stake in all accounts: {}\n \
Stake in stake accounts: {}\n \
Stake in unstake accounts: {}",
info.name,
match &info.keybase_username {
Some(username) => &username[..],
None => "not set",
},
// info.name,
// match &info.keybase_username {
// Some(username) => &username[..],
// None => "not set",
// },
pe.pubkey(),
identity,
commission,
Expand Down Expand Up @@ -694,13 +694,14 @@ pub fn command_show_solido(
.get_account_list::<Maintainer>(&lido.maintainer_list)?;

let mut validator_identities = Vec::new();
let mut validator_infos = Vec::new();
//let mut validator_infos = Vec::new();
let mut validator_commission_percentages = Vec::new();
for validator in validators.entries.iter() {
let vote_state = config.client.get_vote_account(validator.pubkey())?;
validator_identities.push(vote_state.node_pubkey);
let info = config.client.get_validator_info(&vote_state.node_pubkey)?;
validator_infos.push(info);
let node_pubkey = config.client.get_node_pubkey(validator.pubkey())?;
validator_identities.push(node_pubkey);
// let info = config.client.get_validator_info(&node_pubkey)?;

// validator_infos.push(info);
let vote_account = config.client.get_account(validator.pubkey())?;
let commission = get_vote_account_commission(&vote_account.data)
.ok()
Expand All @@ -713,7 +714,7 @@ pub fn command_show_solido(
solido_address: *opts.solido_address(),
solido: lido,
validator_identities,
validator_infos,
//validator_infos,
validator_commission_percentages,
reserve_account,
stake_authority,
Expand Down
13 changes: 8 additions & 5 deletions cli/maintainer/src/daemon.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ struct MaintenanceMetrics {

impl MaintenanceMetrics {
/// Serialize metrics in Prometheus text format.
/*
pub fn write_prometheus<W: io::Write>(&self, out: &mut W) -> io::Result<()> {
write_metric(
out,
Expand Down Expand Up @@ -115,6 +116,7 @@ impl MaintenanceMetrics {
)?;
Ok(())
}
*/

/// Increment the counter for a maintenance operation.
pub fn observe_maintenance(&mut self, maintenance_output: &MaintenanceOutput) {
Expand Down Expand Up @@ -146,7 +148,7 @@ impl MaintenanceMetrics {
/// Snapshot of metrics and Solido state.
struct Snapshot {
/// Metrics about what the daemon has done so far.
metrics: MaintenanceMetrics,
//metrics: MaintenanceMetrics,

/// The current state of on-chain accounts, and the time at which we obtained
/// that data.
Expand Down Expand Up @@ -324,7 +326,7 @@ impl<'a, 'b> Daemon<'a, 'b> {
}

let snapshot = Snapshot {
metrics: self.metrics.clone(),
// metrics: self.metrics.clone(),
solido,
};
self.snapshot_mutex
Expand Down Expand Up @@ -469,11 +471,12 @@ fn serve_request(request: Request, snapshot_mutex: &SnapshotMutex) -> Result<(),

// We don't even look at the request, for now we always serve the metrics.

let mut out: Vec<u8> = Vec::new();
let mut is_ok = snapshot.metrics.write_prometheus(&mut out).is_ok();
let out: Vec<u8> = Vec::new();
let mut is_ok = true;
//snapshot.metrics.write_prometheus(&mut out).is_ok();

if let Some(ref solido) = snapshot.solido {
is_ok = is_ok && solido.write_prometheus(&mut out).is_ok();
is_ok = is_ok;// && solido.write_prometheus(&mut out).is_ok();
}

if is_ok {
Expand Down
Loading

0 comments on commit 6d63d9f

Please sign in to comment.