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

tests(app): 🏓 add voting power assertions to staking tests #4133

Merged
merged 1 commit into from
Apr 1, 2024
Merged
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
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
Loading