Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Maintainer fix #35

Merged
merged 5 commits into from
Apr 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading