diff --git a/crates/core/app/tests/app_can_define_and_delegate_to_a_validator.rs b/crates/core/app/tests/app_can_define_and_delegate_to_a_validator.rs index fa44dc55af..a3b26cfa52 100644 --- a/crates/core/app/tests/app_can_define_and_delegate_to_a_validator.rs +++ b/crates/core/app/tests/app_can_define_and_delegate_to_a_validator.rs @@ -59,17 +59,12 @@ async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> { let snapshot_end = storage.latest_snapshot(); // Retrieve the validator definition from the latest snapshot. - let existing_validator = match snapshot_end - .validator_definitions() - .tap(|_| info!("getting validator definitions")) + let [existing_validator_id] = storage + .latest_snapshot() + .validator_identity_keys() .await? - .as_slice() - { - [v] => v.clone(), - unexpected => panic!("there should be one validator, got: {unexpected:?}"), - }; - - let existing_validator_id = existing_validator.identity_key; + .try_into() + .map_err(|keys| anyhow::anyhow!("expected one key, got: {keys:?}"))?; // Check that we are now in a new epoch. { diff --git a/crates/core/app/tests/app_can_undelegate_from_a_validator.rs b/crates/core/app/tests/app_can_undelegate_from_a_validator.rs index a7f972b6e4..1f7f2c7573 100644 --- a/crates/core/app/tests/app_can_undelegate_from_a_validator.rs +++ b/crates/core/app/tests/app_can_undelegate_from_a_validator.rs @@ -13,10 +13,7 @@ use { penumbra_num::fixpoint::U128x128, penumbra_proto::DomainType, penumbra_sct::component::clock::EpochRead as _, - penumbra_stake::{ - component::validator_handler::ValidatorDataRead as _, validator::Validator, - UndelegateClaimPlan, - }, + penumbra_stake::{component::validator_handler::ValidatorDataRead as _, UndelegateClaimPlan}, penumbra_transaction::{ memo::MemoPlaintext, plan::MemoPlan, TransactionParameters, TransactionPlan, }, @@ -77,16 +74,12 @@ async fn app_can_undelegate_from_a_validator() -> anyhow::Result<()> { }?; // Retrieve the validator definition from the latest snapshot. - let Validator { identity_key, .. } = match storage + let [identity_key] = storage .latest_snapshot() - .validator_definitions() - .tap(|_| info!("getting validator definitions")) + .validator_identity_keys() .await? - .as_slice() - { - [v] => v.clone(), - unexpected => panic!("there should be one validator, got: {unexpected:?}"), - }; // ..and note the asset id for delegation tokens tied to this validator. + .try_into() + .map_err(|keys| anyhow::anyhow!("expected one key, got: {keys:?}"))?; let delegate_token_id = penumbra_stake::DelegationToken::new(identity_key).id(); // Sync the mock client, using the test wallet's spend key, to the latest snapshot. diff --git a/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_missing_blocks.rs b/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_missing_blocks.rs index e5a76d2e41..126888c365 100644 --- a/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_missing_blocks.rs +++ b/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_missing_blocks.rs @@ -6,11 +6,9 @@ use { cnidarium::TempStorage, penumbra_app::{genesis::AppState, server::consensus::Consensus}, penumbra_mock_consensus::TestNode, - penumbra_stake::{ - component::validator_handler::validator_store::ValidatorDataRead, validator::Validator, - }, + penumbra_stake::component::validator_handler::validator_store::ValidatorDataRead, tap::Tap, - tracing::{error_span, info, trace, Instrument}, + tracing::{error_span, trace, Instrument}, }; #[tokio::test] @@ -31,16 +29,12 @@ async fn app_tracks_uptime_for_genesis_validator_missing_blocks() -> anyhow::Res }?; // Retrieve the validator definition from the latest snapshot. - let Validator { identity_key, .. } = match storage + let [identity_key] = storage .latest_snapshot() - .validator_definitions() - .tap(|_| info!("getting validator definitions")) + .validator_identity_keys() .await? - .as_slice() - { - [v] => v.clone(), - unexpected => panic!("there should be one validator, got: {unexpected:?}"), - }; + .try_into() + .map_err(|keys| anyhow::anyhow!("expected one key, got: {keys:?}"))?; let get_uptime = || async { storage .latest_snapshot() diff --git a/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_signing_blocks.rs b/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_signing_blocks.rs index 7d0e3ba9c4..8c9be9a2d2 100644 --- a/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_signing_blocks.rs +++ b/crates/core/app/tests/app_tracks_uptime_for_genesis_validator_signing_blocks.rs @@ -1,18 +1,16 @@ -mod common; - use { self::common::BuilderExt, anyhow::Context, cnidarium::TempStorage, penumbra_app::{genesis::AppState, server::consensus::Consensus}, penumbra_mock_consensus::TestNode, - penumbra_stake::{ - component::validator_handler::validator_store::ValidatorDataRead, validator::Validator, - }, + penumbra_stake::component::validator_handler::validator_store::ValidatorDataRead, tap::Tap, - tracing::{error_span, info, Instrument}, + tracing::{error_span, Instrument}, }; +mod common; + #[tokio::test] async fn app_tracks_uptime_for_genesis_validator_missing_blocks() -> anyhow::Result<()> { // Install a test logger, acquire some temporary storage, and start the test node. @@ -31,16 +29,12 @@ async fn app_tracks_uptime_for_genesis_validator_missing_blocks() -> anyhow::Res }?; // Retrieve the validator definition from the latest snapshot. - let Validator { identity_key, .. } = match storage + let [identity_key] = storage .latest_snapshot() - .validator_definitions() - .tap(|_| info!("getting validator definitions")) + .validator_identity_keys() .await? - .as_slice() - { - [v] => v.clone(), - unexpected => panic!("there should be one validator, got: {unexpected:?}"), - }; + .try_into() + .map_err(|keys| anyhow::anyhow!("expected one key, got: {keys:?}"))?; let get_uptime = || async { storage .latest_snapshot() diff --git a/crates/core/app/tests/app_tracks_uptime_for_validators_only_once_active.rs b/crates/core/app/tests/app_tracks_uptime_for_validators_only_once_active.rs index 6418dc2220..8a4553e786 100644 --- a/crates/core/app/tests/app_tracks_uptime_for_validators_only_once_active.rs +++ b/crates/core/app/tests/app_tracks_uptime_for_validators_only_once_active.rs @@ -17,7 +17,7 @@ use { }, rand_core::OsRng, tap::Tap, - tracing::{error_span, info, Instrument}, + tracing::{error_span, Instrument}, }; mod common; @@ -70,19 +70,12 @@ async fn app_tracks_uptime_for_validators_only_once_active() -> anyhow::Result<( }; // Get the identity key of the genesis validator, before we go further. - // Retrieve the validator definition from the latest snapshot. - let existing_validator_id = { - use penumbra_stake::component::validator_handler::validator_store::ValidatorDataRead; - let validators = &storage - .latest_snapshot() - .validator_definitions() - .tap(|_| info!("getting validator definitions")) - .await?; - match validators.as_slice() { - [Validator { identity_key, .. }] => *identity_key, - unexpected => panic!("there should be one validator, got: {unexpected:?}"), - } - }; + let [existing_validator_id] = storage + .latest_snapshot() + .validator_identity_keys() + .await? + .try_into() + .map_err(|keys| anyhow::anyhow!("expected one key, got: {keys:?}"))?; // To define a validator, we need to define two keypairs: an identity key // for the Penumbra application and a consensus key for cometbft. diff --git a/crates/core/component/stake/src/component/validator_handler/validator_store.rs b/crates/core/component/stake/src/component/validator_handler/validator_store.rs index 89abf01686..3f30895d12 100644 --- a/crates/core/component/stake/src/component/validator_handler/validator_store.rs +++ b/crates/core/component/stake/src/component/validator_handler/validator_store.rs @@ -235,6 +235,15 @@ pub trait ValidatorDataRead: StateRead { .try_collect() .await } + + /// Returns a list of **all** known validators identity keys. + async fn validator_identity_keys(&self) -> Result> { + self.prefix(state_key::validators::definitions::prefix()) + .map_ok(|(_key, validator)| validator) + .map_ok(|validator: Validator| validator.identity_key) + .try_collect() + .await + } } impl ValidatorDataRead for T {}