Skip to content
Open
Show file tree
Hide file tree
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
14 changes: 14 additions & 0 deletions crates/apps_lib/src/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1508,6 +1508,20 @@ pub async fn query_rewards<C: Client + Sync>(
)
}

/// Query validator rewards products for a given validator and epoch.
pub async fn query_validator_rewards_product<C: Client + Sync>(
client: &C,
validator: &Address,
epoch: Option<Epoch>,
) -> Vec<(Epoch, Dec)> {
unwrap_client_response::<C, _>(
RPC.vp()
.pos()
.rewards_products(client, validator, &epoch)
.await,
)
}

/// Query token total supply.
pub async fn query_total_supply<N: Namada>(
context: &N,
Expand Down
40 changes: 40 additions & 0 deletions crates/proof_of_stake/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2874,6 +2874,46 @@ where
Ok(res)
}

/// Query the validator's reward product for a given epoch.
pub fn query_validator_rewards_products<S, Gov>(
storage: &S,
validator: &Address,
epoch: Option<Epoch>,
) -> Result<Vec<(Epoch, Dec)>>
where
S: StorageRead,
Gov: governance::Read<S>,
{
let rewards_products = validator_rewards_products_handle(validator);
// Query for a specific epoch or all epochs
let result = if let Some(epoch) = epoch {
tracing::debug!("Querying rewards product for epoch {:?}", epoch);
rewards_products
.get(storage, &epoch)?
.map(|product| vec![(epoch, product)])
.unwrap_or_else(|| {
tracing::debug!(
"No rewards product found for epoch {:?}",
epoch
);
vec![]
})
} else {
tracing::debug!("Querying rewards products for all epochs");
rewards_products
.iter(storage)?
.filter_map(|res| match res {
Ok((epoch, product)) => Some(Ok((epoch, product))),
Err(e) => {
tracing::error!("Failed to read rewards product: {:?}", e);
None
}
})
.collect::<Result<Vec<_>>>()?
};
Ok(result)
}

/// Jail a validator by removing it from and updating the validator sets and
/// changing a its state to `Jailed`. Validators are jailed for liveness and for
/// misbehaving.
Expand Down
19 changes: 19 additions & 0 deletions crates/sdk/src/queries/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,9 @@ router! {SHELL,
// First block height of the current epoch
( "first_block_height_of_current_epoch" ) -> BlockHeight = first_block_height_of_current_epoch,

// First block height of the current epoch
( "first_block_height_by_epoch" / [epoch: Epoch] ) -> Option<BlockHeight> = first_block_height_by_epoch,

// Raw storage access - read value
( "value" / [storage_key: storage::Key] )
-> Vec<u8> = (with_options storage_value),
Expand Down Expand Up @@ -427,6 +430,22 @@ where
.cloned()
}

fn first_block_height_by_epoch<D, H, V, T>(
ctx: RequestCtx<'_, D, H, V, T>,
epoch: Epoch,
) -> namada_storage::Result<Option<BlockHeight>>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
H: 'static + StorageHasher + Sync,
{
Ok(ctx
.state
.in_mem()
.block
.pred_epochs
.get_start_height_of_epoch(epoch))
}

/// Returns data with `vec![]` when the storage key is not found. For all
/// borsh-encoded types, it is safe to check `data.is_empty()` to see if the
/// value was found, except for unit - see `fn query_storage_value` in
Expand Down
22 changes: 21 additions & 1 deletion crates/sdk/src/queries/vp/pos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use namada_core::address::Address;
use namada_core::arith::{self, checked};
use namada_core::chain::Epoch;
use namada_core::collections::{HashMap, HashSet};
use namada_core::dec::Dec;
use namada_core::key::{common, tm_consensus_key_raw_hash};
use namada_core::token;
use namada_proof_of_stake::parameters::PosParams;
Expand Down Expand Up @@ -34,7 +35,9 @@ use namada_proof_of_stake::types::{
LivenessInfo, Slash, ValidatorLiveness, ValidatorMetaData,
WeightedValidator,
};
use namada_proof_of_stake::{bond_amount, query_reward_tokens};
use namada_proof_of_stake::{
bond_amount, query_reward_tokens, query_validator_rewards_products,
};
use namada_state::{DB, DBIter, KeySeg, StorageHasher, StorageRead};
use namada_storage::collections::lazy_map;
use namada_storage::{OptionExt, ResultExt};
Expand Down Expand Up @@ -105,6 +108,9 @@ router! {POS,
( "bond" / [source: Address] / [validator: Address] / [epoch: opt Epoch] )
-> token::Amount = bond,

( "rewards_products" / [validator: Address] / [epoch: opt Epoch])
-> Vec<(Epoch, Dec)> = rewards_products,

( "rewards" / [validator: Address] / [source: opt Address] / [epoch: opt Epoch] )
-> token::Amount = rewards,

Expand Down Expand Up @@ -586,6 +592,20 @@ where
Ok(total)
}

fn rewards_products<D, H, V, T>(
ctx: RequestCtx<'_, D, H, V, T>,
validator: Address,
epoch: Option<Epoch>,
) -> namada_storage::Result<Vec<(Epoch, Dec)>>
where
D: 'static + DB + for<'iter> DBIter<'iter> + Sync,
H: 'static + StorageHasher + Sync,
{
query_validator_rewards_products::<_, governance::Store<_>>(
ctx.state, &validator, epoch,
)
}

fn rewards<D, H, V, T>(
ctx: RequestCtx<'_, D, H, V, T>,
validator: Address,
Expand Down
Loading