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

MASP rewards estimation #3974

Merged
merged 9 commits into from
Nov 14, 2024
Merged
Show file tree
Hide file tree
Changes from 8 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
@@ -0,0 +1,3 @@
- Adds a cli command to estimate the amount of MASP rewards that will be accumulated by the next epoch.
This is done by applying the latest set of conversions for each asset again.
([\#3974](https://github.com/anoma/namada/pull/3974))
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

65 changes: 65 additions & 0 deletions crates/apps_lib/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -273,6 +273,7 @@ pub mod cmds {
.subcommand(QueryMaspRewardTokens::def().display_order(5))
.subcommand(QueryBlock::def().display_order(5))
.subcommand(QueryBalance::def().display_order(5))
.subcommand(QueryRewardsEstimate::def().display_order(5))
.subcommand(QueryBonds::def().display_order(5))
.subcommand(QueryBondedStake::def().display_order(5))
.subcommand(QuerySlashes::def().display_order(5))
Expand Down Expand Up @@ -356,6 +357,8 @@ pub mod cmds {
Self::parse_with_ctx(matches, QueryMaspRewardTokens);
let query_block = Self::parse_with_ctx(matches, QueryBlock);
let query_balance = Self::parse_with_ctx(matches, QueryBalance);
let query_rewards_estimate =
Self::parse_with_ctx(matches, QueryRewardsEstimate);
let query_bonds = Self::parse_with_ctx(matches, QueryBonds);
let query_bonded_stake =
Self::parse_with_ctx(matches, QueryBondedStake);
Expand Down Expand Up @@ -427,6 +430,7 @@ pub mod cmds {
.or(query_masp_reward_tokens)
.or(query_block)
.or(query_balance)
.or(query_rewards_estimate)
.or(query_bonds)
.or(query_bonded_stake)
.or(query_slashes)
Expand Down Expand Up @@ -523,6 +527,7 @@ pub mod cmds {
QueryMaspRewardTokens(QueryMaspRewardTokens),
QueryBlock(QueryBlock),
QueryBalance(QueryBalance),
QueryRewardsEstimate(QueryRewardsEstimate),
QueryBonds(QueryBonds),
QueryBondedStake(QueryBondedStake),
QueryCommissionRate(QueryCommissionRate),
Expand Down Expand Up @@ -1875,6 +1880,31 @@ pub mod cmds {
}
}

#[derive(Clone, Debug)]
pub struct QueryRewardsEstimate(
pub args::QueryRewardsEstimate<args::CliTypes>,
);

impl SubCmd for QueryRewardsEstimate {
const CMD: &'static str = "estimate-rewards";

fn parse(matches: &ArgMatches) -> Option<Self> {
matches.subcommand_matches(Self::CMD).map(|matches| {
QueryRewardsEstimate(args::QueryRewardsEstimate::parse(matches))
})
}

fn def() -> App {
App::new(Self::CMD)
.about(wrap!(
"Estimate the amount of MASP rewards accumulated by the \
next MASP epoch. Please run shielded-sync first for best \
results."
))
.add_args::<args::QueryRewardsEstimate<args::CliTypes>>()
}
}

#[derive(Clone, Debug)]
pub struct QueryBonds(pub args::QueryBonds<args::CliTypes>);

Expand Down Expand Up @@ -6318,6 +6348,41 @@ pub mod args {
}
}

impl CliToSdk<QueryRewardsEstimate<SdkTypes>>
for QueryRewardsEstimate<CliTypes>
{
type Error = std::convert::Infallible;

fn to_sdk(
self,
ctx: &mut Context,
) -> Result<QueryRewardsEstimate<SdkTypes>, Self::Error> {
let query = self.query.to_sdk(ctx)?;
let chain_ctx = ctx.borrow_mut_chain_or_exit();

Ok(QueryRewardsEstimate::<SdkTypes> {
query,
owner: chain_ctx.get_cached(&self.owner),
})
}
}

impl Args for QueryRewardsEstimate<CliTypes> {
fn parse(matches: &ArgMatches) -> Self {
let query = Query::parse(matches);
let owner = VIEWING_KEY.parse(matches);
Self { query, owner }
}

fn def(app: App) -> App {
app.add_args::<Query<CliTypes>>().arg(
VIEWING_KEY
.def()
.help(wrap!("The viewing key whose rewards to estimate.")),
)
}
}

impl CliToSdk<QueryBonds<SdkTypes>> for QueryBonds<CliTypes> {
type Error = std::convert::Infallible;

Expand Down
12 changes: 12 additions & 0 deletions crates/apps_lib/src/cli/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,18 @@ impl CliApi {
let namada = ctx.to_sdk(client, io);
rpc::query_balance(&namada, args).await;
}
Sub::QueryRewardsEstimate(QueryRewardsEstimate(args)) => {
let chain_ctx = ctx.borrow_mut_chain_or_exit();
let ledger_address =
chain_ctx.get(&args.query.ledger_address);
let client = client.unwrap_or_else(|| {
C::from_tendermint_address(&ledger_address)
});
client.wait_until_node_is_synced(&io).await?;
let args = args.to_sdk(&mut ctx)?;
let namada = ctx.to_sdk(client, io);
rpc::query_rewards_estimate(&namada, args).await;
}
Sub::QueryBonds(QueryBonds(args)) => {
let chain_ctx = ctx.borrow_mut_chain_or_exit();
let ledger_address =
Expand Down
22 changes: 22 additions & 0 deletions crates/apps_lib/src/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use masp_primitives::sapling::Node;
use masp_primitives::transaction::components::I128Sum;
use masp_primitives::zip32::ExtendedFullViewingKey;
use namada_core::masp::{BalanceOwner, MaspEpoch};
use namada_core::token::Amount;
use namada_sdk::address::{Address, InternalAddress, MASP};
use namada_sdk::chain::{BlockHeight, Epoch};
use namada_sdk::collections::{HashMap, HashSet};
Expand Down Expand Up @@ -359,6 +360,27 @@ pub async fn query_proposal_by_id<C: Client + Sync>(
namada_sdk::rpc::query_proposal_by_id(client, proposal_id).await
}

/// Estimate MASP rewards for next MASP epoch
pub async fn query_rewards_estimate(
context: &impl Namada,
args: args::QueryRewardsEstimate,
) {
let mut shielded = context.shielded_mut().await;
let _ = shielded.load().await;
let rewards_estimate = shielded
.estimate_next_epoch_rewards(context, &args.owner.as_viewing_key())
.await
.unwrap()
.unsigned_abs();
let rewards_estimate =
DenominatedAmount::new(Amount::from_u128(rewards_estimate), 6.into());
display_line!(
context.io(),
"Estimated nam rewards for the next MASP epoch: {}",
rewards_estimate
);
}

/// Query token shielded balance(s)
async fn query_shielded_balance(
context: &impl Namada,
Expand Down
14 changes: 14 additions & 0 deletions crates/core/src/masp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,11 @@ impl MaspEpoch {
Some(Self(self.0.checked_sub(1)?))
}

/// Change to the next masp epoch.
pub fn next(&self) -> Option<Self> {
Some(Self(self.0.checked_add(1)?))
}

/// Initialize a new masp epoch from the provided one
#[cfg(any(test, feature = "testing"))]
pub const fn new(epoch: u64) -> Self {
Expand Down Expand Up @@ -201,6 +206,15 @@ impl AssetData {
}
}

/// Update the MaspEpoch to the next one
pub fn redate_to_next_epoch(&mut self) {
if let Some(ep) = self.epoch.as_mut() {
if let Some(next) = ep.next() {
*ep = next;
}
}
}

/// Remove the epoch associated with this pre-asset type
pub fn undate(&mut self) {
self.epoch = None;
Expand Down
10 changes: 10 additions & 0 deletions crates/sdk/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1600,6 +1600,16 @@ pub struct QueryBalance<C: NamadaTypes = SdkTypes> {
pub height: Option<C::BlockHeight>,
}

/// Get an estimate for the MASP rewards accumulated by the next
/// MASP epoch.
#[derive(Clone, Debug)]
pub struct QueryRewardsEstimate<C: NamadaTypes = SdkTypes> {
/// Common query args
pub query: Query<C>,
/// Viewing key
pub owner: C::ViewingKey,
}

/// Query historical transfer(s)
#[derive(Clone, Debug)]
pub struct QueryTransfers<C: NamadaTypes = SdkTypes> {
Expand Down
2 changes: 2 additions & 0 deletions crates/shielded_token/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ multicore = ["dep:rayon"]
testing = [
"multicore",
"namada_core/testing",
"namada_tx/testing",
"masp_primitives/test-dependencies",
"proptest",
"std"
Expand Down Expand Up @@ -92,5 +93,6 @@ masp_proofs = { workspace = true, features = ["download-params"] }
proptest.workspace = true
rand_core.workspace = true
rayon.workspace = true
tendermint-rpc.workspace = true
test-log.workspace = true
tokio.workspace = true
Loading