Skip to content

Commit

Permalink
tests(app): use validator_identity_keys accessor
Browse files Browse the repository at this point in the history
this adds a `ValidatorDataRead::validator_identity_keys()` trait method.

frequently, test logic needs to keep track of validators by their
identity keys. this led to a bit of common glue code that would get the
latest snapshot, the set of all validator definitions, assert that only
one validator is present, and then take the identity key of that single
validator.

now we can just get the keys, bind that single entry to a variable, or
return an error if something went wrong.
  • Loading branch information
cratelyn committed Apr 8, 2024
1 parent bf8f4d1 commit 19169b5
Show file tree
Hide file tree
Showing 6 changed files with 40 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
{
Expand Down
17 changes: 5 additions & 12 deletions crates/core/app/tests/app_can_undelegate_from_a_validator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use {
},
rand_core::OsRng,
tap::Tap,
tracing::{error_span, info, Instrument},
tracing::{error_span, Instrument},
};

mod common;
Expand Down Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<Vec<IdentityKey>> {
self.prefix(state_key::validators::definitions::prefix())
.map_ok(|(_key, validator)| validator)
.map_ok(|validator: Validator| validator.identity_key)
.try_collect()
.await
}
}

impl<T: StateRead + ?Sized> ValidatorDataRead for T {}
Expand Down

0 comments on commit 19169b5

Please sign in to comment.