Skip to content

Commit

Permalink
handle errors for unjail-validator tx in the client
Browse files Browse the repository at this point in the history
  • Loading branch information
brentstone committed Jul 11, 2023
1 parent fc528cc commit a5d2237
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 7 deletions.
12 changes: 12 additions & 0 deletions shared/src/ledger/queries/vp/pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ use std::collections::{BTreeMap, BTreeSet, HashMap, HashSet};
use borsh::{BorshDeserialize, BorshSchema, BorshSerialize};
use namada_core::ledger::storage_api::collections::lazy_map;
use namada_core::ledger::storage_api::OptionExt;
use namada_proof_of_stake::parameters::PosParams;
use namada_proof_of_stake::types::{
BondId, BondsAndUnbondsDetail, BondsAndUnbondsDetails, CommissionPair,
Slash, ValidatorState, WeightedValidator,
Expand Down Expand Up @@ -60,6 +61,8 @@ router! {POS,
// TODO: add "below_threshold"
},

( "pos_params") -> PosParams = pos_params,

( "total_stake" / [epoch: opt Epoch] )
-> token::Amount = total_stake,

Expand Down Expand Up @@ -141,6 +144,15 @@ impl<T> Enriched<T> {

// Handlers that implement the functions via `trait StorageRead`:

/// Get the PoS parameters
fn pos_params<D, H>(ctx: RequestCtx<'_, D, H>) -> storage_api::Result<PosParams>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
H: 'static + StorageHasher + Sync,
{
read_pos_params(ctx.wl_storage)
}

/// Find if the given address belongs to a validator account.
fn is_validator<D, H>(
ctx: RequestCtx<'_, D, H>,
Expand Down
26 changes: 25 additions & 1 deletion shared/src/ledger/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ use namada_core::types::storage::Key;
use namada_core::types::token::{
Amount, DenominatedAmount, Denomination, MaspDenom, TokenAddress,
};
use namada_proof_of_stake::types::{BondsAndUnbondsDetails, CommissionPair};
use namada_proof_of_stake::parameters::PosParams;
use namada_proof_of_stake::types::{
BondsAndUnbondsDetails, CommissionPair, ValidatorState,
};
use serde::Serialize;

use crate::ledger::args::InputAmount;
Expand Down Expand Up @@ -696,6 +699,13 @@ pub async fn get_proposal_votes<C: crate::ledger::queries::Client + Sync>(
}
}

/// Get the PoS parameters
pub async fn get_pos_params<C: crate::ledger::queries::Client + Sync>(
client: &C,
) -> PosParams {
unwrap_client_response::<C, _>(RPC.vp().pos().pos_params(client).await)
}

/// Get all validators in the given epoch
pub async fn get_all_validators<C: crate::ledger::queries::Client + Sync>(
client: &C,
Expand Down Expand Up @@ -736,6 +746,20 @@ pub async fn get_validator_stake<C: crate::ledger::queries::Client + Sync>(
.unwrap_or_default()
}

/// Query and return a validator's state
pub async fn get_validator_state<C: crate::ledger::queries::Client + Sync>(
client: &C,
validator: &Address,
epoch: Option<Epoch>,
) -> Option<ValidatorState> {
unwrap_client_response::<C, Option<ValidatorState>>(
RPC.vp()
.pos()
.validator_state(client, validator, &epoch)
.await,
)
}

/// Get the delegator's delegation
pub async fn get_delegators_delegation<
C: crate::ledger::queries::Client + Sync,
Expand Down
63 changes: 57 additions & 6 deletions shared/src/ledger/tx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use namada_core::types::dec::Dec;
use namada_core::types::storage::Key;
use namada_core::types::token::MaspDenom;
use namada_proof_of_stake::parameters::PosParams;
use namada_proof_of_stake::types::CommissionPair;
use namada_proof_of_stake::types::{CommissionPair, ValidatorState};
use prost::EncodeError;
use thiserror::Error;

Expand Down Expand Up @@ -110,6 +110,18 @@ pub enum Error {
/// Invalid validator address
#[error("The address {0} doesn't belong to any known validator account.")]
InvalidValidatorAddress(Address),
/// Not jailed at pipeline epoch
#[error(
"The validator address {0} is not jailed at epoch when it would be \
restored."
)]
ValidatorNotCurrentlyJailed(Address),
/// Validator still frozen and ineligible to be unjailed
#[error(
"The validator address {0} is currently frozen and ineligible to be \
unjailed."
)]
ValidatorFrozenFromUnjailing(Address),
/// Rate of epoch change too large for current epoch
#[error(
"New rate, {0}, is too large of a change with respect to the \
Expand Down Expand Up @@ -631,11 +643,7 @@ pub async fn build_validator_commission_change<
.await
.unwrap();

// TODO: put following two let statements in its own function
let params_key = crate::ledger::pos::params_key();
let params = rpc::query_storage_value::<C, PosParams>(client, &params_key)
.await
.expect("Parameter should be defined.");
let params: PosParams = rpc::get_pos_params(client).await;

let validator = args.validator.clone();
if rpc::is_validator(client, &validator).await {
Expand Down Expand Up @@ -771,6 +779,49 @@ pub async fn submit_unjail_validator<
}
}

let params: PosParams = rpc::get_pos_params(client).await;
let current_epoch = rpc::query_epoch(client).await;
let pipeline_epoch = current_epoch + params.pipeline_len;

let validator_state_at_pipeline =
rpc::get_validator_state(client, &args.validator, Some(pipeline_epoch))
.await
.expect("Validator state should be defined.");
if validator_state_at_pipeline != ValidatorState::Jailed {
eprintln!(
"The given validator address {} is not jailed at the pipeline \
epoch when it would be restored to one of the validator sets.",
&args.validator
);
if !args.tx.force {
return Err(Error::ValidatorNotCurrentlyJailed(
args.validator.clone(),
));
}
}

let last_slash_epoch_key =
crate::ledger::pos::validator_last_slash_key(&args.validator);
let last_slash_epoch =
rpc::query_storage_value::<C, Epoch>(client, &last_slash_epoch_key)
.await;
if let Some(last_slash_epoch) = last_slash_epoch {
let eligible_epoch =
last_slash_epoch + params.slash_processing_epoch_offset();
if current_epoch < eligible_epoch {
eprintln!(
"The given validator address {} is currently frozen and not \
yet eligible to be unjailed.",
&args.validator
);
if !args.tx.force {
return Err(Error::ValidatorNotCurrentlyJailed(
args.validator.clone(),
));
}
}
}

let tx_code_hash =
query_wasm_code_hash(client, args.tx_code_path.to_str().unwrap())
.await
Expand Down

0 comments on commit a5d2237

Please sign in to comment.