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

genesis: add wrapper_tx_fees parameter #972

Merged
merged 5 commits into from
Jan 10, 2023
Merged
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
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