Skip to content

Commit

Permalink
Merge remote-tracking branch 'namada/fraccaman+grarco/genesis-wrapper…
Browse files Browse the repository at this point in the history
…-fees' (#972) into main

* namada/fraccaman+grarco/genesis-wrapper-fees:
  changelog: add #972
  chore: clippy/fmt
  ledger: remove/changed some logs
  ledger: use genesis fees
  genesis: added parameter to control wrapper tx fees amount
  • Loading branch information
juped committed Jan 10, 2023
2 parents 30c2841 + 2785ad0 commit 7e47053
Show file tree
Hide file tree
Showing 11 changed files with 118 additions and 10 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Add genesis parameter to control wrapper transaction fees.
([#972](https://github.com/anoma/namada/pull/972))
17 changes: 14 additions & 3 deletions apps/src/lib/client/signing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
//! wallet.
use borsh::BorshSerialize;
use namada::ledger::parameters::storage as parameter_storage;
use namada::proto::Tx;
use namada::types::address::{Address, ImplicitAddress};
use namada::types::key::*;
Expand Down Expand Up @@ -185,11 +186,19 @@ pub async fn sign_wrapper(
keypair: &common::SecretKey,
#[cfg(not(feature = "mainnet"))] requires_pow: bool,
) -> TxBroadcastData {
let fee_amount = Amount::from(MIN_FEE);
let client = HttpClient::new(args.ledger_address.clone()).unwrap();

let fee_amount = if cfg!(feature = "mainnet") {
Amount::from(MIN_FEE)
} else {
let wrapper_tx_fees_key = parameter_storage::get_wrapper_tx_fees_key();
rpc::query_storage_value::<token::Amount>(&client, &wrapper_tx_fees_key)
.await
.unwrap_or_default()
};
let fee_token = ctx.get(&args.fee_token);
let source = Address::from(&keypair.ref_to());
let balance_key = token::balance_key(&fee_token, &source);
let client = HttpClient::new(args.ledger_address.clone()).unwrap();
let balance =
rpc::query_storage_value::<token::Amount>(&client, &balance_key)
.await
Expand All @@ -210,7 +219,9 @@ pub async fn sign_wrapper(
// If the address derived from the keypair doesn't have enough balance
// to pay for the fee, allow to find a PoW solution instead.
if requires_pow || balance < fee_amount {
println!("The transaction requires to a PoW challenge.");
println!(
"The transaction requires the completion of a PoW challenge."
);
// Obtain a PoW challenge for faucet withdrawal
let challenge = rpc::get_testnet_pow_challenge(
source,
Expand Down
8 changes: 8 additions & 0 deletions apps/src/lib/config/genesis.rs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,9 @@ pub mod genesis_config {
pub pos_gain_p: Decimal,
/// PoS gain d
pub pos_gain_d: Decimal,
#[cfg(not(feature = "mainnet"))]
/// Fix wrapper tx fees
pub wrapper_tx_fees: Option<token::Amount>,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
Expand Down Expand Up @@ -613,6 +616,7 @@ pub mod genesis_config {
pos_gain_d: parameters.pos_gain_d,
staked_ratio: Decimal::ZERO,
pos_inflation_amount: 0,
wrapper_tx_fees: parameters.wrapper_tx_fees,
};

let GovernanceParamsConfig {
Expand Down Expand Up @@ -858,6 +862,9 @@ pub struct Parameters {
pub staked_ratio: Decimal,
/// PoS inflation amount from the last epoch (read + write for every epoch)
pub pos_inflation_amount: u64,
/// Fixed Wrapper tx fees
#[cfg(not(feature = "mainnet"))]
pub wrapper_tx_fees: Option<token::Amount>,
}

#[cfg(not(feature = "dev"))]
Expand Down Expand Up @@ -918,6 +925,7 @@ pub fn genesis() -> Genesis {
pos_gain_d: dec!(0.1),
staked_ratio: dec!(0.0),
pos_inflation_amount: 0,
wrapper_tx_fees: Some(token::Amount::whole(0)),
};
let albert = EstablishedAccount {
address: wallet::defaults::albert_address(),
Expand Down
18 changes: 12 additions & 6 deletions apps/src/lib/node/ledger/shell/finalize_block.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ where
execute_governance_proposals(self, &mut response)?;
}

let wrapper_fees = self.get_wrapper_tx_fees();

// Tracks the accepted transactions
self.storage.block.results = BlockResults::default();
for (tx_index, processed_tx) in req.txs.iter().enumerate() {
Expand Down Expand Up @@ -179,13 +181,12 @@ where
}
};

let balance: u64 = balance.into();
match balance.checked_sub(MIN_FEE) {
Some(v) => {
match balance.checked_sub(wrapper_fees) {
Some(amount) => {
self.write_log
.write(
&balance_key,
Amount::from(v).try_to_vec().unwrap(),
amount.try_to_vec().unwrap(),
)
.unwrap();
}
Expand Down Expand Up @@ -264,7 +265,7 @@ where
{
Ok(result) => {
if result.is_accepted() {
tracing::info!(
tracing::trace!(
"all VPs accepted transaction {} storage \
modification {:#?}",
tx_event["hash"],
Expand Down Expand Up @@ -296,7 +297,7 @@ where
}
}
} else {
tracing::info!(
tracing::trace!(
"some VPs rejected transaction {} storage \
modification {:#?}",
tx_event["hash"],
Expand Down Expand Up @@ -325,6 +326,11 @@ where
}
response.events.push(tx_event);
}
tracing::info!(
"Applied {} txs at height {}",
response.events.len(),
self.storage.last_height
);

if new_epoch {
self.update_epoch(&mut response);
Expand Down
3 changes: 3 additions & 0 deletions apps/src/lib/node/ledger/shell/init_chain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ where
pos_gain_d,
staked_ratio,
pos_inflation_amount,
wrapper_tx_fees,
} = genesis.parameters;
// borrow necessary for release build, annoys clippy on dev build
#[allow(clippy::needless_borrow)]
Expand Down Expand Up @@ -131,6 +132,8 @@ where
pos_inflation_amount,
#[cfg(not(feature = "mainnet"))]
faucet_account,
#[cfg(not(feature = "mainnet"))]
wrapper_tx_fees,
};
parameters.init_storage(&mut self.storage);

Expand Down
11 changes: 11 additions & 0 deletions apps/src/lib/node/ledger/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -719,6 +719,17 @@ where
false
}

#[cfg(not(feature = "mainnet"))]
/// Get fixed amount of fees for wrapper tx
fn get_wrapper_tx_fees(&self) -> token::Amount {
let (fees, _gas) =
namada::ledger::parameters::read_wrapper_tx_fees_parameter(
&self.storage,
)
.expect("Must be able to read wrapper tx fees parameter");
fees.unwrap_or_default()
}

#[cfg(not(feature = "mainnet"))]
/// Check if the tx has a valid PoW solution and if so invalidate it to
/// prevent replay.
Expand Down
47 changes: 47 additions & 0 deletions core/src/ledger/parameters/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ use crate::types::address::{Address, InternalAddress};
use crate::types::chain::ProposalBytes;
use crate::types::storage::Key;
use crate::types::time::DurationSecs;
use crate::types::token;

const ADDRESS: Address = Address::Internal(InternalAddress::Parameters);

Expand Down Expand Up @@ -54,6 +55,9 @@ pub struct Parameters {
#[cfg(not(feature = "mainnet"))]
/// Faucet account for free token withdrawal
pub faucet_account: Option<Address>,
#[cfg(not(feature = "mainnet"))]
/// Fixed fees for a wrapper tx to be accepted
pub wrapper_tx_fees: Option<token::Amount>,
}

/// Epoch duration. A new epoch begins as soon as both the `min_num_of_blocks`
Expand Down Expand Up @@ -118,6 +122,8 @@ impl Parameters {
pos_inflation_amount,
#[cfg(not(feature = "mainnet"))]
faucet_account,
#[cfg(not(feature = "mainnet"))]
wrapper_tx_fees,
} = self;

// write max proposal bytes parameter
Expand Down Expand Up @@ -218,6 +224,18 @@ impl Parameters {
genesis block, if any",
);
}

#[cfg(not(feature = "mainnet"))]
{
let wrapper_tx_fees_key = storage::get_wrapper_tx_fees_key();
let wrapper_tx_fees_val =
encode(&wrapper_tx_fees.unwrap_or(token::Amount::whole(100)));
storage
.write(&wrapper_tx_fees_key, wrapper_tx_fees_val)
.expect(
"Wrapper tx fees must be initialized in the genesis block",
);
}
}
}
/// Update the max_expected_time_per_block parameter in storage. Returns the
Expand Down Expand Up @@ -423,6 +441,25 @@ where
Ok((address, gas_faucet_account))
}

#[cfg(not(feature = "mainnet"))]
/// Read the wrapper tx fees amount, if any
pub fn read_wrapper_tx_fees_parameter<DB, H>(
storage: &Storage<DB, H>,
) -> std::result::Result<(Option<token::Amount>, u64), ReadError>
where
DB: ledger_storage::DB + for<'iter> ledger_storage::DBIter<'iter>,
H: ledger_storage::StorageHasher,
{
let wrapper_tx_fees_key = storage::get_wrapper_tx_fees_key();
let (value, gas_wrapper_tx_fees) = storage
.read(&wrapper_tx_fees_key)
.map_err(ReadError::StorageError)?;
let address: Option<token::Amount> = value
.map(|value| decode(value).map_err(ReadError::StorageTypeError))
.transpose()?;
Ok((address, gas_wrapper_tx_fees))
}

// Read the all the parameters from storage. Returns the parameters and gas
/// cost.
pub fn read<DB, H>(
Expand Down Expand Up @@ -532,6 +569,13 @@ where
#[cfg(feature = "mainnet")]
let gas_faucet_account = 0;

// read faucet account
#[cfg(not(feature = "mainnet"))]
let (wrapper_tx_fees, gas_wrapper_tx_fees) =
read_wrapper_tx_fees_parameter(storage)?;
#[cfg(feature = "mainnet")]
let gas_wrapper_tx_fees = 0;

let total_gas_cost = [
gas_epoch,
gas_tx,
Expand All @@ -545,6 +589,7 @@ where
gas_reward,
gas_proposal_bytes,
gas_faucet_account,
gas_wrapper_tx_fees,
]
.into_iter()
.fold(0u64, |accum, gas| {
Expand All @@ -568,6 +613,8 @@ where
pos_inflation_amount,
#[cfg(not(feature = "mainnet"))]
faucet_account,
#[cfg(not(feature = "mainnet"))]
wrapper_tx_fees,
},
total_gas_cost,
))
Expand Down
11 changes: 11 additions & 0 deletions core/src/ledger/parameters/storage.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ struct Keys {
vp_whitelist: &'static str,
max_proposal_bytes: &'static str,
faucet_account: &'static str,
wrapper_tx_fees: &'static str,
}

/// Returns if the key is a parameter key.
Expand Down Expand Up @@ -249,3 +250,13 @@ pub fn get_faucet_account_key() -> Key {
],
}
}

/// Storage key used for staked ratio parameter.
pub fn get_wrapper_tx_fees_key() -> Key {
Key {
segments: vec![
DbKeySeg::AddressSeg(ADDRESS),
DbKeySeg::StringSeg(Keys::VALUES.wrapper_tx_fees.to_string()),
],
}
}
2 changes: 2 additions & 0 deletions core/src/ledger/storage/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1242,6 +1242,8 @@ mod tests {
pos_inflation_amount: 0,
#[cfg(not(feature = "mainnet"))]
faucet_account: None,
#[cfg(not(feature = "mainnet"))]
wrapper_tx_fees: None,
};
parameters.init_storage(&mut storage);

Expand Down
7 changes: 7 additions & 0 deletions core/src/types/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,13 @@ impl Amount {
Self { micro: u64::MAX }
}

/// Checked subtraction
pub fn checked_sub(&self, amount: Amount) -> Option<Self> {
self.micro
.checked_sub(amount.micro)
.map(|result| Self { micro: result })
}

/// Create amount from Change
///
/// # Panics
Expand Down
2 changes: 1 addition & 1 deletion shared/src/ledger/queries/router.rs
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ macro_rules! try_match_segments {
$end = $request.path.len();
match $request.path[$start..$end].parse::<$arg_ty>() {
Ok(parsed) => {
println!("Parsed {}", parsed);
// println!("Parsed {}", parsed);
$arg = parsed
},
Err(_) =>
Expand Down

0 comments on commit 7e47053

Please sign in to comment.