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
39 changes: 25 additions & 14 deletions crates/apps_lib/src/client/rpc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ use namada_sdk::governance::pgf::parameters::PgfParameters;
use namada_sdk::governance::pgf::storage::steward::StewardDetail;
use namada_sdk::governance::storage::keys as governance_storage;
use namada_sdk::governance::storage::proposal::{
StoragePgfFunding, StorageProposal,
ContPgfFundings, StorageProposal,
};
use namada_sdk::governance::utils::{ProposalVotes, VotePower};
use namada_sdk::hash::Hash;
Expand Down Expand Up @@ -705,11 +705,11 @@ pub async fn query_pgf(context: &impl Namada, _args: args::QueryPgf) {
true => {
display_line!(
context.io(),
"Pgf stewards: no stewards are currently set."
"PGF stewards: no stewards are currently set."
)
}
false => {
display_line!(context.io(), "Pgf stewards:");
display_line!(context.io(), "PGF stewards:");
for steward in stewards {
display_line!(context.io(), "{:4}- {}", "", steward.address);
display_line!(context.io(), "{:4} Reward distribution:", "");
Expand All @@ -730,19 +730,30 @@ pub async fn query_pgf(context: &impl Namada, _args: args::QueryPgf) {
true => {
display_line!(
context.io(),
"Pgf fundings: no fundings are currently set."
"\nNo continous PGF distributions exist currently."
)
}
false => {
display_line!(context.io(), "Pgf fundings:");
for funding in fundings {
display_line!(
context.io(),
"{:4}- {} for {}",
"",
funding.detail.target(),
funding.detail.amount().to_string_native()
);
display_line!(
context.io(),
"\nContinuous PGF distributions (per epoch):"
);
for (str_addr, targets) in fundings {
display_line!(context.io(), "{:4}- {}", "", str_addr);
for (proposal_id, c_target) in targets {
display_line!(
context.io(),
"{:6}- Prop {}: {} native tokens, end epoch = {}",
"",
proposal_id,
c_target.amount().to_string_native(),
if let Some(ep) = c_target.end_epoch {
ep.to_string()
} else {
"None".to_string()
}
);
}
}
}
}
Expand Down Expand Up @@ -1184,7 +1195,7 @@ pub async fn query_pgf_stewards<C: Client + Sync>(

pub async fn query_pgf_fundings<C: Client + Sync>(
client: &C,
) -> Vec<StoragePgfFunding> {
) -> ContPgfFundings {
unwrap_client_response::<C, _>(RPC.vp().pgf().funding(client).await)
}

Expand Down
9 changes: 7 additions & 2 deletions crates/apps_lib/src/wallet/defaults.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
pub use dev::{
addresses, albert_address, albert_keypair, bertha_address, bertha_keypair,
christel_address, christel_keypair, daewon_address, daewon_keypair,
derive_template_dir, ester_address, ester_keypair, frank_keypair,
get_unencrypted_keypair, is_use_device, keys, tokens,
derive_template_dir, ester_address, ester_keypair, frank_address,
frank_keypair, get_unencrypted_keypair, is_use_device, keys, tokens,
validator_account_keypair, validator_address, validator_keypair,
validator_keys,
};
Expand Down Expand Up @@ -119,6 +119,11 @@ mod dev {
.into_owned()
}

/// An established user address for testing & development
pub fn frank_address() -> Address {
(&frank_keypair().ref_to()).into()
}

/// An implicit user address for testing & development
pub fn daewon_address() -> Address {
(&daewon_keypair().ref_to()).into()
Expand Down
21 changes: 18 additions & 3 deletions crates/governance/src/cli/onchain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ use super::validation::{
is_valid_proposal_period, is_valid_start_epoch,
};
use crate::parameters::GovernanceParameters;
use crate::storage::proposal::PGFTarget;
use crate::storage::proposal::{ContPGFTarget, PGFTarget};

#[derive(
Debug,
Expand Down Expand Up @@ -289,6 +289,15 @@ impl PgfAction {
}
}

impl Display for PgfAction {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
PgfAction::Add => write!(f, "Add"),
PgfAction::Remove => write!(f, "Remove"),
}
}
}

/// PGF funding
#[derive(
Debug,
Expand All @@ -301,7 +310,7 @@ impl PgfAction {
)]
pub struct PgfFunding {
/// PGF continuous funding
pub continuous: Vec<PGFTarget>,
pub continuous: Vec<PgfContinuous>,
/// PGF retro fundings
pub retro: Vec<PGFTarget>,
}
Expand Down Expand Up @@ -336,11 +345,17 @@ impl Display for PgfFunding {
)]
pub struct PgfContinuous {
/// PGF target
pub target: PGFTarget,
pub target: ContPGFTarget,
/// PGF action
pub action: PgfAction,
}

impl Display for PgfContinuous {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "\n{}:\n{}", &self.action, &self.target)
}
}

/// PGF retro funding
#[derive(
Debug,
Expand Down
53 changes: 30 additions & 23 deletions crates/governance/src/finalize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,7 @@ use crate::event::GovernanceEvent;
use crate::pgf::storage::keys as pgf_keys;
use crate::pgf::storage::steward::StewardDetail;
use crate::pgf::{ADDRESS as PGF_ADDRESS, storage as pgf_storage};
use crate::storage::proposal::{
AddRemove, PGFAction, PGFTarget, ProposalType, StoragePgfFunding,
};
use crate::storage::proposal::{AddRemove, PGFAction, PGFTarget, ProposalType};
use crate::storage::{keys, load_proposals};
use crate::utils::{
ProposalVotes, TallyResult, TallyType, VotePower, compute_proposal_result,
Expand Down Expand Up @@ -449,29 +447,38 @@ where
match funding {
PGFAction::Continuous(action) => match action {
AddRemove::Add(target) => {
pgf_keys::fundings_handle().insert(
storage,
target.target().clone(),
StoragePgfFunding::new(target.clone(), proposal_id),
)?;
tracing::info!(
"Added/Updated Continuous PGF from proposal id {}: \
set {} to {}.",
"Adding Continuous PGF for {} from Proposal {} in the \
amount of {} per epoch, {}.",
target.target.target(),
proposal_id,
target.amount().to_string_native(),
target.target()
target.target.amount().to_string_native(),
if let Some(ep) = target.end_epoch {
format!("until epoch {}", ep)
} else {
"indefinitely".to_string()
}
);
pgf_keys::fundings_handle()
.at(&target.target.target())
.insert(storage, proposal_id, target.clone())?;
}
AddRemove::Remove(target) => {
pgf_keys::fundings_handle()
.remove(storage, &target.target())?;
tracing::info!(
"Removed Continuous PGF from proposal id {}: set {} \
to {}.",
proposal_id,
target.amount().to_string_native(),
target.target()
"Removing Continuous PGF for {} from Proposal {} (set \
to {} native tokens, end epoch: {}).",
target.target.target(),
target.proposal_id,
target.target.amount().to_string_native(),
if let Some(ep) = target.end_epoch {
format!("{}", ep)
} else {
"None".to_string()
}
);
pgf_keys::fundings_handle()
.at(&target.target.target())
.remove(storage, &target.proposal_id)?;
}
},
PGFAction::Retro(target) => {
Expand Down Expand Up @@ -525,16 +532,16 @@ where
match result {
Ok(()) => {
tracing::info!(
"Execute Retroactive PGF from proposal id {}: \
sent {} to {}.",
"Execute Retroactive PGF from Proposal {}: {} \
native tokens transferred to {}.",
proposal_id,
target.amount().to_string_native(),
target.target()
);
}
Err(e) => tracing::warn!(
"Error in Retroactive PGF transfer from proposal id \
{}, amount {} to {}: {}",
"Error in Retroactive PGF transfer from Proposal {}, \
attempt to transfer {} native tokens to {}: {}",
proposal_id,
target.amount().to_string_native(),
target.target(),
Expand Down
105 changes: 67 additions & 38 deletions crates/governance/src/pgf/inflation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,25 @@ use namada_core::address::Address;
use namada_state::{Result, StorageRead, StorageWrite};
use namada_systems::{parameters, trans_token};

use crate::pgf::storage::keys::fundings_handle;
use crate::pgf::storage::{
get_continuous_pgf_payments, get_parameters, get_stewards,
};
use crate::storage::proposal::{PGFIbcTarget, PGFTarget};

/// Apply the PGF inflation.
fn remove_cpgf_target<S>(
storage: &mut S,
id: &u64,
target_address: &String,
) -> Result<()>
where
S: StorageRead + StorageWrite,
{
fundings_handle().at(target_address).remove(storage, id)?;
Ok(())
}

/// Apply the PGF inflation. Also
pub fn apply_inflation<S, Params, TransToken, F>(
storage: &mut S,
transfer_over_ibc: F,
Expand All @@ -26,6 +39,7 @@ where
let epochs_per_year = Params::epochs_per_year(storage)?;
let total_supply = TransToken::get_effective_total_native_supply(storage)?;

// Mint tokens into the PGF address
let pgf_inflation_amount = total_supply
.mul_floor(pgf_parameters.pgf_inflation_rate)?
.checked_div_u64(epochs_per_year)
Expand All @@ -39,46 +53,60 @@ where
)?;

tracing::info!(
"Minting {} tokens for PGF rewards distribution into the PGF account \
(total supply {}).",
"Minting {} native tokens for PGF rewards distribution into the PGF \
account (total supply: {}).",
pgf_inflation_amount.to_string_native(),
total_supply.to_string_native()
);

let mut pgf_fundings = get_continuous_pgf_payments(storage)?;
// prioritize the payments by oldest gov proposal ID
pgf_fundings.sort_by(|a, b| a.id.cmp(&b.id));
// TODO: make sure this is still sorted prioritizing older proposals
let pgf_fundings = get_continuous_pgf_payments(storage)?;

for funding in pgf_fundings {
let result = match &funding.detail {
PGFTarget::Internal(target) => TransToken::transfer(
storage,
&staking_token,
&super::ADDRESS,
&target.target,
target.amount,
),
PGFTarget::Ibc(target) => transfer_over_ibc(
storage,
&staking_token,
&super::ADDRESS,
target,
),
};
match result {
Ok(()) => {
tracing::info!(
"Paying {} tokens for {} project.",
funding.detail.amount().to_string_native(),
&funding.detail.target(),
);
let current_epoch = storage.get_block_epoch()?;

// Act on the continuous PGF fundings in storage: either distribute or
// remove expired ones
for (str_target_address, targets) in pgf_fundings {
for (proposal_id, c_target) in targets {
// Remove expired fundings from storage
if c_target.is_expired(current_epoch) {
remove_cpgf_target(storage, &proposal_id, &str_target_address)?;
continue;
}
Err(_) => {
tracing::warn!(
"Failed to pay {} tokens for {} project.",
funding.detail.amount().to_string_native(),
&funding.detail.target(),
);

// Transfer PGF payment to target
let result = match &c_target.target {
PGFTarget::Internal(target) => TransToken::transfer(
storage,
&staking_token,
&super::ADDRESS,
&target.target,
target.amount,
),
PGFTarget::Ibc(target) => transfer_over_ibc(
storage,
&staking_token,
&super::ADDRESS,
target,
),
};
match result {
// TODO: not hardcode "NAM" below??
Ok(()) => {
tracing::info!(
"Successfully transferred CPGF payment of {} NAM to \
{}.",
c_target.amount().to_string_native(),
&c_target.target(),
);
}
Err(_) => {
tracing::warn!(
"Failed to transfer CPGF payment of {} NAM to {}.",
c_target.amount().to_string_native(),
&c_target.target(),
);
}
}
}
}
Expand All @@ -104,15 +132,16 @@ where
.is_ok()
{
tracing::info!(
"Minting {} tokens for steward {} (total supply {})..",
"Minting {} native tokens for steward {} (total supply: \
{})..",
pgf_steward_reward.to_string_native(),
address,
total_supply.to_string_native()
);
} else {
tracing::warn!(
"Failed minting {} tokens for steward {} (total supply \
{})..",
"Failed minting {} native tokens for steward {} (total \
supply: {})..",
pgf_steward_reward.to_string_native(),
address,
total_supply.to_string_native()
Expand Down
Loading
Loading