Skip to content

Commit

Permalink
tests(app): add voting power assertions to staking tests
Browse files Browse the repository at this point in the history
see #3995.

this addresses points 10b and 11a in #3995. this adds additional
assertions to the `app_can_define_and_delegate_to_a_validator` test,
which ensure that the validator's voting power changes as expected.
  • Loading branch information
cratelyn committed Mar 28, 2024
1 parent 50d1643 commit 0776a0a
Showing 1 changed file with 66 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,7 @@ async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> {
let tx = client.witness_auth_build(&plan).await?;

// Execute the transaction, applying it to the chain state.
let pre_delegate_snapshot = storage.latest_snapshot();
node.block()
.add_tx(tx.encode_to_vec())
.execute()
Expand All @@ -292,7 +293,7 @@ async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> {
// Show that the set of validators still looks correct. We should not see any changes yet.
{
use penumbra_stake::{component::ConsensusIndexRead, validator::State};
let snapshot = post_delegate_snapshot;
let snapshot = post_delegate_snapshot.clone();
info!("checking consensus set in block after delegation");
// The original validator should still be active.
assert_eq!(
Expand All @@ -315,6 +316,30 @@ async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> {
);
}

// Confirm that the new validator's voting power has not changed immeditaly.
let new_validator_original_power = {
use penumbra_sct::component::clock::EpochRead;
let pre_delegate_power = pre_delegate_snapshot
.get_validator_power(&new_validator_id)
.await?
.expect("should have voting power before delegating");
let post_delegate_power = post_delegate_snapshot
.get_validator_power(&new_validator_id)
.await?
.expect("should have voting power after delegating");
debug_assert_eq!(
pre_delegate_snapshot.get_current_epoch().await?,
post_delegate_snapshot.get_current_epoch().await?,
"avoid puzzling errors by confirming that pre- and post-delegation snapshots do not \
sit upon an epoch boundary"
);
assert_eq!(
pre_delegate_power, post_delegate_power,
"a delegated validator"
);
pre_delegate_power
};

// Fast forward to the next epoch.
node.fast_forward(EPOCH_DURATION)
.instrument(error_span!(
Expand All @@ -328,7 +353,7 @@ async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> {
{
use penumbra_stake::{component::ConsensusIndexRead, validator::State};
info!("checking consensus set in epoch after delegation");
let snapshot = post_delegate_next_epoch_snapshot;
let snapshot = post_delegate_next_epoch_snapshot.clone();
// The original validator should still be active.
assert_eq!(
snapshot.get_validator_state(&existing_validator_id).await?,
Expand All @@ -349,6 +374,19 @@ async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> {
);
}

// Show that the new validator's voting power has changed, now that we are in a new epoch
// after the delegation.
let new_validator_epoch_after_delegation_power = post_delegate_next_epoch_snapshot
.get_validator_power(&new_validator_id)
.await?
.expect("should have voting power before delegating")
.tap(|&power| {
assert!(
power > new_validator_original_power,
"new validator should now have more voting power after receiving a delegation"
)
});

// Build a transaction that will now undelegate from the validator.
let plan = {
use {
Expand Down Expand Up @@ -419,7 +457,7 @@ async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> {
// Show that the consensus set has not changed yet.
{
use penumbra_stake::{component::ConsensusIndexRead, validator::State};
let snapshot = post_undelegate_snapshot;
let snapshot = post_undelegate_snapshot.clone();
info!("checking consensus set in block after undelegation");
// The original validator should still be active.
assert_eq!(
Expand All @@ -441,6 +479,18 @@ async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> {
);
}

// Compute the current voting power, confirm that it has not changed yet.
post_undelegate_snapshot
.get_validator_power(&new_validator_id)
.await?
.expect("should have voting power before delegating")
.tap(|&power| {
assert_eq!(
power, new_validator_epoch_after_delegation_power,
"validator power should not change immediately after an undelegation"
)
});

// Fast forward to the next epoch.
node.fast_forward(EPOCH_DURATION)
.instrument(error_span!(
Expand All @@ -454,7 +504,7 @@ async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> {
{
use penumbra_stake::{component::ConsensusIndexRead, validator::State};
info!("checking consensus set in epoch after undelegation");
let snapshot = post_undelegate_next_epoch_snapshot;
let snapshot = post_undelegate_next_epoch_snapshot.clone();
// The original validator should still be active.
assert_eq!(
snapshot.get_validator_state(&existing_validator_id).await?,
Expand All @@ -475,6 +525,18 @@ async fn app_can_define_and_delegate_to_a_validator() -> anyhow::Result<()> {
);
}

// Show that now, the validator's voting power has returned to its original state.
post_undelegate_next_epoch_snapshot
.get_validator_power(&new_validator_id)
.await?
.expect("should have voting power before delegating")
.tap(|&power| {
assert_eq!(
power, new_validator_original_power,
"validator power should not change immediately after an undelegation"
)
});

// The test passed. Free our temporary storage and drop our tracing subscriber.
Ok(())
.tap(|_| drop(node))
Expand Down

0 comments on commit 0776a0a

Please sign in to comment.