diff --git a/.changelog/unreleased/improvements/3391-parameterize-gas-scale.md b/.changelog/unreleased/improvements/3391-parameterize-gas-scale.md new file mode 100644 index 0000000000..2729821cb7 --- /dev/null +++ b/.changelog/unreleased/improvements/3391-parameterize-gas-scale.md @@ -0,0 +1,3 @@ +- Include the gas scale as a protocol parameter that is + mutable via governance rather than as a hard-coded constant. + ([\#3391](https://github.com/anoma/namada/pull/3391)) \ No newline at end of file diff --git a/crates/apps_lib/src/config/genesis.rs b/crates/apps_lib/src/config/genesis.rs index cbd89f1130..dcf193ca4b 100644 --- a/crates/apps_lib/src/config/genesis.rs +++ b/crates/apps_lib/src/config/genesis.rs @@ -311,6 +311,8 @@ pub struct Parameters { pub masp_epoch_multiplier: u64, /// Fee unshielding gas limit pub fee_unshielding_gas_limit: u64, + /// Gas scale + pub gas_scale: u64, /// Map of the cost per gas unit for every token allowed for fee payment pub minimum_gas_price: BTreeMap, } diff --git a/crates/apps_lib/src/config/genesis/chain.rs b/crates/apps_lib/src/config/genesis/chain.rs index 827d7df9ad..a7bd75a22c 100644 --- a/crates/apps_lib/src/config/genesis/chain.rs +++ b/crates/apps_lib/src/config/genesis/chain.rs @@ -303,6 +303,7 @@ impl Finalized { epochs_per_year, masp_epoch_multiplier, fee_unshielding_gas_limit, + gas_scale, max_block_gas, minimum_gas_price, max_tx_bytes, @@ -344,6 +345,7 @@ impl Finalized { masp_epoch_multiplier, max_proposal_bytes, fee_unshielding_gas_limit, + gas_scale, max_block_gas, minimum_gas_price: minimum_gas_price .iter() diff --git a/crates/apps_lib/src/config/genesis/templates.rs b/crates/apps_lib/src/config/genesis/templates.rs index e21e1fc1c7..377bb8ba70 100644 --- a/crates/apps_lib/src/config/genesis/templates.rs +++ b/crates/apps_lib/src/config/genesis/templates.rs @@ -296,6 +296,8 @@ pub struct ChainParams { pub max_block_gas: u64, /// Fee unshielding gas limit pub fee_unshielding_gas_limit: u64, + /// Gas scale + pub gas_scale: u64, /// Map of the cost per gas unit for every token allowed for fee payment pub minimum_gas_price: T::GasMinimums, } @@ -318,6 +320,7 @@ impl ChainParams { masp_epoch_multiplier, max_block_gas, fee_unshielding_gas_limit, + gas_scale, minimum_gas_price, } = self; let mut min_gas_prices = BTreeMap::default(); @@ -362,6 +365,7 @@ impl ChainParams { masp_epoch_multiplier, max_block_gas, fee_unshielding_gas_limit, + gas_scale, minimum_gas_price: min_gas_prices, }) } diff --git a/crates/core/src/parameters.rs b/crates/core/src/parameters.rs index e1faea6885..8e4a1d779d 100644 --- a/crates/core/src/parameters.rs +++ b/crates/core/src/parameters.rs @@ -49,6 +49,8 @@ pub struct Parameters { pub masp_epoch_multiplier: u64, /// Fee unshielding gas limit pub fee_unshielding_gas_limit: u64, + /// Gas scale + pub gas_scale: u64, /// Map of the cost per gas unit for every token allowed for fee payment pub minimum_gas_price: BTreeMap, /// Enable the native token transfer if it is true diff --git a/crates/gas/src/lib.rs b/crates/gas/src/lib.rs index 89e24209ff..dc9c4c0a20 100644 --- a/crates/gas/src/lib.rs +++ b/crates/gas/src/lib.rs @@ -113,9 +113,6 @@ pub const MASP_PARALLEL_GAS_DIVIDER: u64 = PARALLEL_GAS_DIVIDER / 2; /// Gas module result for functions that may fail pub type Result = std::result::Result; -/// Decimal scale of Gas units -const SCALE: u64 = 100_000_000; - /// Representation of gas in sub-units. This effectively decouples gas metering /// from fee payment, allowing higher resolution when accounting for gas while, /// at the same time, providing a contained gas value when paying fees. @@ -155,9 +152,17 @@ impl Gas { /// Converts the sub gas units to whole ones. If the sub units are not a /// multiple of the `SCALE` than ceil the quotient - fn get_whole_gas_units(&self) -> u64 { - let quotient = self.sub / SCALE; - if self.sub % SCALE == 0 { + pub fn get_whole_gas_units(&self, scale: u64) -> u64 { + let quotient = self + .sub + .checked_div(scale) + .expect("Gas quotient should not overflow on checked division"); + if self + .sub + .checked_rem(scale) + .expect("Gas quotient remainder should not overflow") + == 0 + { quotient } else { quotient @@ -167,8 +172,8 @@ impl Gas { } /// Generates a `Gas` instance from a whole amount - pub fn from_whole_units(whole: u64) -> Option { - let sub = whole.checked_mul(SCALE)?; + pub fn from_whole_units(whole: u64, scale: u64) -> Option { + let sub = whole.checked_mul(scale)?; Some(Self { sub }) } } @@ -187,8 +192,9 @@ impl From for u64 { impl Display for Gas { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - // Display the gas in whole amounts - write!(f, "{}", self.get_whole_gas_units()) + // Need to do this now that the gas scale is a parameter. Should + // manually scale gas first before calling this + write!(f, "{}", self.sub) } } @@ -197,8 +203,7 @@ impl FromStr for Gas { fn from_str(s: &str) -> std::result::Result { let raw: u64 = s.parse().map_err(GasParseError::Parse)?; - let gas = Gas::from_whole_units(raw).ok_or(GasParseError::Overflow)?; - Ok(gas) + Ok(Self { sub: raw }) } } diff --git a/crates/namada/src/ledger/mod.rs b/crates/namada/src/ledger/mod.rs index b9c81a2ed6..11a6e59348 100644 --- a/crates/namada/src/ledger/mod.rs +++ b/crates/namada/src/ledger/mod.rs @@ -23,7 +23,6 @@ pub use { mod dry_run_tx { use std::cell::RefCell; - use namada_gas::Gas; use namada_sdk::queries::{EncodedResponseQuery, RequestCtx, RequestQuery}; use namada_state::{DBIter, ResultExt, StorageHasher, DB}; use namada_tx::data::{GasLimit, TxResult}; @@ -54,43 +53,47 @@ mod dry_run_tx { let tx = Tx::try_from(&request.data[..]).into_storage_result()?; tx.validate_tx().into_storage_result()?; - // Wrapper dry run to allow estimating the gas cost of a transaction - let (wrapper_hash, mut tx_result, tx_gas_meter) = match tx - .header() - .tx_type - { - TxType::Wrapper(wrapper) => { - let gas_limit = - Gas::try_from(wrapper.gas_limit).into_storage_result()?; - let tx_gas_meter = RefCell::new(TxGasMeter::new(gas_limit)); - let tx_result = protocol::apply_wrapper_tx( - &tx, - &wrapper, - &request.data, - &tx_gas_meter, - &mut temp_state, - None, - ) - .into_storage_result()?; + let gas_scale = namada_parameters::get_gas_scale(ctx.state)?; - temp_state.write_log_mut().commit_tx(); - let available_gas = tx_gas_meter.borrow().get_available_gas(); - ( - Some(tx.header_hash()), - tx_result, - TxGasMeter::new_from_sub_limit(available_gas), - ) - } - _ => { - // If dry run only the inner tx, use the max block gas as - // the gas limit - let max_block_gas = - namada_parameters::get_max_block_gas(ctx.state)?; - let gas_limit = Gas::try_from(GasLimit::from(max_block_gas)) + // Wrapper dry run to allow estimating the gas cost of a transaction + let (wrapper_hash, mut tx_result, tx_gas_meter) = + match tx.header().tx_type { + TxType::Wrapper(wrapper) => { + let gas_limit = wrapper + .gas_limit + .as_scaled_gas(gas_scale) + .into_storage_result()?; + let tx_gas_meter = RefCell::new(TxGasMeter::new(gas_limit)); + let tx_result = protocol::apply_wrapper_tx( + &tx, + &wrapper, + &request.data, + &tx_gas_meter, + &mut temp_state, + None, + ) .into_storage_result()?; - (None, TxResult::default(), TxGasMeter::new(gas_limit)) - } - }; + + temp_state.write_log_mut().commit_tx(); + let available_gas = + tx_gas_meter.borrow().get_available_gas(); + ( + Some(tx.header_hash()), + tx_result, + TxGasMeter::new_from_sub_limit(available_gas), + ) + } + _ => { + // If dry run only the inner tx, use the max block gas as + // the gas limit + let max_block_gas = + namada_parameters::get_max_block_gas(ctx.state)?; + let gas_limit = GasLimit::from(max_block_gas) + .as_scaled_gas(gas_scale) + .into_storage_result()?; + (None, TxResult::default(), TxGasMeter::new(gas_limit)) + } + }; let tx_gas_meter = RefCell::new(tx_gas_meter); for cmt in tx.commitments() { @@ -195,6 +198,12 @@ mod test { .expect( "Max block gas parameter must be initialized in storage", ); + // Initialize mock gas scale + let gas_scale_key = namada_parameters::storage::get_gas_scale_key(); + state + .db_write(&gas_scale_key, 100_000_000_u64.serialize_to_vec()) + .expect("Gas scale parameter must be initialized in storage"); + let event_log = EventLog::default(); let (vp_wasm_cache, vp_cache_dir) = wasm::compilation_cache::common::testing::cache(); diff --git a/crates/namada/src/ledger/protocol/mod.rs b/crates/namada/src/ledger/protocol/mod.rs index b66cb28c2b..f459822dde 100644 --- a/crates/namada/src/ledger/protocol/mod.rs +++ b/crates/namada/src/ledger/protocol/mod.rs @@ -266,6 +266,7 @@ where tx_wasm_cache, }, )?; + Ok(TxResult { gas_used: tx_gas_meter.borrow().get_tx_consumed_gas(), batch_results: { diff --git a/crates/node/src/shell/finalize_block.rs b/crates/node/src/shell/finalize_block.rs index baa91e6b76..df19a749b5 100644 --- a/crates/node/src/shell/finalize_block.rs +++ b/crates/node/src/shell/finalize_block.rs @@ -29,6 +29,7 @@ use namada::tx::event::{Batch, Code}; use namada::tx::new_tx_event; use namada::vote_ext::ethereum_events::MultiSignedEthEvent; use namada::vote_ext::ethereum_tx_data_variants; +use parameters::get_gas_scale; use super::*; use crate::facade::tendermint::abci::types::VoteInfo; @@ -385,9 +386,17 @@ where .unwrap_or(""), msg, ); + let gas_scale = get_gas_scale(&self.state) + .expect("Failed to get gas scale from parameters"); + let scaled_gas = Gas::from( + tx_data + .tx_gas_meter + .get_tx_consumed_gas() + .get_whole_gas_units(gas_scale), + ); tx_logs .tx_event - .extend(GasUsed(tx_data.tx_gas_meter.get_tx_consumed_gas())) + .extend(GasUsed(scaled_gas)) .extend(Info(msg.to_string())) .extend(Code(ResultCode::InvalidTx)); // Make sure to clean the write logs for the next transaction @@ -410,9 +419,18 @@ where msg ); + let gas_scale = get_gas_scale(&self.state) + .expect("Failed to get gas scale from parameters"); + let scaled_gas = Gas::from( + tx_data + .tx_gas_meter + .get_tx_consumed_gas() + .get_whole_gas_units(gas_scale), + ); + tx_logs .tx_event - .extend(GasUsed(tx_data.tx_gas_meter.get_tx_consumed_gas())) + .extend(GasUsed(scaled_gas)) .extend(Info(msg.to_string())) .extend(Code(ResultCode::WasmRuntimeError)); @@ -487,9 +505,18 @@ where self.commit_batch_hash(tx_data.replay_protection_hashes); } + let gas_scale = get_gas_scale(&self.state) + .expect("Failed to get gas scale from parameters"); + let scaled_gas = Gas::from( + tx_data + .tx_gas_meter + .get_tx_consumed_gas() + .get_whole_gas_units(gas_scale), + ); + tx_logs .tx_event - .extend(GasUsed(extended_tx_result.tx_result.gas_used)) + .extend(GasUsed(scaled_gas)) .extend(Info("Check batch for result.".to_string())) .extend(Batch(&extended_tx_result.tx_result.to_result_string())); } @@ -667,22 +694,25 @@ where TxType::Wrapper(wrapper) => { stats.increment_wrapper_txs(); - let gas_limit = match Gas::try_from(wrapper.gas_limit) { - Ok(value) => value, - Err(_) => { - response.events.emit( - new_tx_event(&tx, height.0) - .with(Code(ResultCode::InvalidTx)) - .with(Info( - "The wrapper gas limit overflowed gas \ - representation" - .to_owned(), - )) - .with(GasUsed(0.into())), - ); - continue; - } - }; + let gas_scale = get_gas_scale(&self.state) + .expect("Failed to get gas scale from parameters"); + let gas_limit = + match wrapper.gas_limit.as_scaled_gas(gas_scale) { + Ok(value) => value, + Err(_) => { + response.events.emit( + new_tx_event(&tx, height.0) + .with(Code(ResultCode::InvalidTx)) + .with(Info( + "The wrapper gas limit overflowed \ + gas representation" + .to_owned(), + )) + .with(GasUsed(0.into())), + ); + continue; + } + }; let tx_gas_meter = TxGasMeter::new(gas_limit); for cmt in tx.commitments() { if let Some(code_sec) = tx diff --git a/crates/node/src/shell/mod.rs b/crates/node/src/shell/mod.rs index 4f9eae585e..ca388843ec 100644 --- a/crates/node/src/shell/mod.rs +++ b/crates/node/src/shell/mod.rs @@ -50,7 +50,7 @@ use namada::ledger::pos::namada_proof_of_stake::types::{ }; use namada::ledger::protocol::ShellParams; use namada::ledger::{parameters, protocol}; -use namada::parameters::validate_tx_bytes; +use namada::parameters::{get_gas_scale, validate_tx_bytes}; use namada::proof_of_stake::storage::read_pos_params; use namada::state::tx_queue::ExpiredTx; use namada::state::{ @@ -1095,9 +1095,22 @@ where } }, TxType::Wrapper(wrapper) => { + // Get the gas scale first + let gas_scale = match get_gas_scale(&self.state) { + Ok(scale) => scale, + Err(_) => { + response.code = ResultCode::InvalidTx.into(); + response.log = "The gas scale could not be found in \ + the parameters storage" + .to_string(); + return response; + } + }; + // Validate wrapper first // Tx gas limit - let gas_limit = match Gas::try_from(wrapper.gas_limit) { + let gas_limit = match wrapper.gas_limit.as_scaled_gas(gas_scale) + { Ok(value) => value, Err(_) => { response.code = ResultCode::InvalidTx.into(); @@ -1119,6 +1132,7 @@ where // Max block gas let block_gas_limit: Gas = Gas::from_whole_units( namada::parameters::get_max_block_gas(&self.state).unwrap(), + gas_scale, ) .expect("Gas limit from parameter must not overflow"); if gas_meter.tx_gas_limit > block_gas_limit { diff --git a/crates/node/src/shell/prepare_proposal.rs b/crates/node/src/shell/prepare_proposal.rs index 6cc2f22392..aa6fe39b5f 100644 --- a/crates/node/src/shell/prepare_proposal.rs +++ b/crates/node/src/shell/prepare_proposal.rs @@ -4,9 +4,10 @@ use std::cell::RefCell; use namada::core::address::Address; use namada::core::key::tm_raw_hash_to_string; -use namada::gas::{Gas, TxGasMeter}; +use namada::gas::TxGasMeter; use namada::hash::Hash; use namada::ledger::protocol::{self, ShellParams}; +use namada::parameters::get_gas_scale; use namada::proof_of_stake::storage::find_validator_by_raw_hash; use namada::state::{DBIter, StorageHasher, TempWlState, DB}; use namada::token::{Amount, DenominatedAmount}; @@ -288,7 +289,9 @@ where tx.validate_tx().map_err(|_| ())?; if let TxType::Wrapper(wrapper) = tx.header().tx_type { // Check tx gas limit for tx size - let gas_limit = Gas::try_from(wrapper.gas_limit).map_err(|_| ())?; + let gas_scale = get_gas_scale(temp_state).map_err(|_| ())?; + let gas_limit = + wrapper.gas_limit.as_scaled_gas(gas_scale).map_err(|_| ())?; let mut tx_gas_meter = TxGasMeter::new(gas_limit); tx_gas_meter.add_wrapper_gas(tx_bytes).map_err(|_| ())?; diff --git a/crates/node/src/shell/process_proposal.rs b/crates/node/src/shell/process_proposal.rs index f226097c11..7554be9e50 100644 --- a/crates/node/src/shell/process_proposal.rs +++ b/crates/node/src/shell/process_proposal.rs @@ -410,7 +410,17 @@ where let allocated_gas = metadata.user_gas.try_dump(u64::from(wrapper.gas_limit)); - let gas_limit = match Gas::try_from(wrapper.gas_limit) { + let gas_scale = match get_gas_scale(temp_state) { + Ok(scale) => scale, + Err(_) => { + return TxResult { + code: ResultCode::TxGasLimit.into(), + info: "Failed to get gas scale".to_owned(), + }; + } + }; + let gas_limit = match wrapper.gas_limit.as_scaled_gas(gas_scale) + { Ok(value) => value, Err(_) => { return TxResult { diff --git a/crates/node/src/storage/mod.rs b/crates/node/src/storage/mod.rs index 5b084133ee..569bb7cbe7 100644 --- a/crates/node/src/storage/mod.rs +++ b/crates/node/src/storage/mod.rs @@ -174,6 +174,7 @@ mod tests { epochs_per_year: 365, masp_epoch_multiplier: 2, fee_unshielding_gas_limit: 0, + gas_scale: 100_000_000, minimum_gas_price: Default::default(), is_native_token_transferable: true, }; diff --git a/crates/parameters/src/lib.rs b/crates/parameters/src/lib.rs index fe6424d843..9a82ab4d70 100644 --- a/crates/parameters/src/lib.rs +++ b/crates/parameters/src/lib.rs @@ -29,7 +29,7 @@ use namada_core::storage::{BlockHeight, Key}; use namada_core::time::DurationSecs; use namada_core::{hints, token}; use namada_storage::{ResultExt, StorageRead, StorageWrite}; -pub use storage::get_max_block_gas; +pub use storage::{get_gas_scale, get_max_block_gas}; use thiserror::Error; pub use wasm_allowlist::{is_tx_allowed, is_vp_allowed}; @@ -77,6 +77,7 @@ where masp_epoch_multiplier, minimum_gas_price, fee_unshielding_gas_limit, + gas_scale, is_native_token_transferable, } = parameters; @@ -101,6 +102,10 @@ where storage::get_fee_unshielding_gas_limit_key(); storage.write(&fee_unshielding_gas_limit_key, fee_unshielding_gas_limit)?; + // write the gas scale + let gas_scale_key = storage::get_gas_scale_key(); + storage.write(&gas_scale_key, gas_scale)?; + // write vp allowlist parameter let vp_allowlist_key = storage::get_vp_allowlist_storage_key(); let vp_allowlist = vp_allowlist @@ -333,6 +338,13 @@ where .ok_or(ReadError::ParametersMissing) .into_storage_result()?; + // read gas scale + let gas_scale_key = storage::get_gas_scale_key(); + let value = storage.read(&gas_scale_key)?; + let gas_scale: u64 = value + .ok_or(ReadError::ParametersMissing) + .into_storage_result()?; + // read epochs per year let epochs_per_year_key = storage::get_epochs_per_year_key(); let value = storage.read(&epochs_per_year_key)?; @@ -376,6 +388,7 @@ where masp_epoch_multiplier, minimum_gas_price, fee_unshielding_gas_limit, + gas_scale, is_native_token_transferable, }) } @@ -419,6 +432,7 @@ where epochs_per_year: 365, masp_epoch_multiplier: 2, fee_unshielding_gas_limit: 0, + gas_scale: 100_000_000, minimum_gas_price: Default::default(), is_native_token_transferable: true, }; diff --git a/crates/parameters/src/storage.rs b/crates/parameters/src/storage.rs index 19caeb0114..500aa1ff6c 100644 --- a/crates/parameters/src/storage.rs +++ b/crates/parameters/src/storage.rs @@ -38,6 +38,7 @@ struct Keys { max_block_gas: &'static str, minimum_gas_price: &'static str, fee_unshielding_gas_limit: &'static str, + gas_scale: &'static str, native_token_transferable: &'static str, } @@ -114,6 +115,11 @@ pub fn get_fee_unshielding_gas_limit_key() -> Key { get_fee_unshielding_gas_limit_key_at_addr(ADDRESS) } +/// Storage key used for the gas scale +pub fn get_gas_scale_key() -> Key { + get_gas_scale_key_at_addr(ADDRESS) +} + /// Storage key used for implicit VP parameter. pub fn get_implicit_vp_key() -> Key { get_implicit_vp_key_at_addr(ADDRESS) @@ -161,6 +167,18 @@ pub fn get_max_block_gas( ) } +/// Helper function to retrieve the `gas_scale` protocol parameter from +/// storage +pub fn get_gas_scale( + storage: &impl StorageRead, +) -> std::result::Result { + storage.read(&get_gas_scale_key())?.ok_or( + namada_storage::Error::SimpleMessage( + "Missing gas_scale parameter from storage", + ), + ) +} + /// Storage key used for the flag to enable the native token transfer pub fn get_native_token_transferable_key() -> Key { get_native_token_transferable_key_at_addr(ADDRESS) diff --git a/crates/proof_of_stake/src/lib.rs b/crates/proof_of_stake/src/lib.rs index 5c5a6b43c7..ca8b0a36ab 100644 --- a/crates/proof_of_stake/src/lib.rs +++ b/crates/proof_of_stake/src/lib.rs @@ -2725,6 +2725,7 @@ pub mod test_utils { epochs_per_year: 10000000, masp_epoch_multiplier: 2, fee_unshielding_gas_limit: 10000, + gas_scale: 100_000_000, minimum_gas_price: BTreeMap::new(), is_native_token_transferable: true, }; diff --git a/crates/sdk/src/rpc.rs b/crates/sdk/src/rpc.rs index 989ae6ace1..4c3a6f80c1 100644 --- a/crates/sdk/src/rpc.rs +++ b/crates/sdk/src/rpc.rs @@ -559,6 +559,7 @@ pub async fn dry_run_tx( )? .data; let result_str = format!("Transaction consumed {} gas", result.gas_used); + let mut cmt_result_str = String::new(); for (inner_hash, cmt_result) in result.batch_results.iter() { match cmt_result { diff --git a/crates/sdk/src/tx.rs b/crates/sdk/src/tx.rs index 6f60c069ba..d84814a25b 100644 --- a/crates/sdk/src/tx.rs +++ b/crates/sdk/src/tx.rs @@ -420,9 +420,11 @@ pub fn display_batch_resp(context: &impl Namada, resp: &TxResponse) { InnerTxResult::Success(_) => { display_line!( context.io(), - "Transaction {} was successfully applied at height {}.", + "Transaction {} was successfully applied at height {}, \ + consuming {} gas units.", inner_hash, resp.height, + resp.gas_used ); } InnerTxResult::VpsRejected(inner) => { diff --git a/crates/state/src/lib.rs b/crates/state/src/lib.rs index 37832d46e5..071a8d1a19 100644 --- a/crates/state/src/lib.rs +++ b/crates/state/src/lib.rs @@ -755,6 +755,7 @@ mod tests { epochs_per_year: 100, masp_epoch_multiplier: 2, fee_unshielding_gas_limit: 20_000, + gas_scale: 100_000_000, minimum_gas_price: BTreeMap::default(), is_native_token_transferable: true, }; diff --git a/crates/tests/src/e2e/ibc_tests.rs b/crates/tests/src/e2e/ibc_tests.rs index 4e8dc13a2a..92124cfca9 100644 --- a/crates/tests/src/e2e/ibc_tests.rs +++ b/crates/tests/src/e2e/ibc_tests.rs @@ -2215,13 +2215,13 @@ fn transfer_from_gaia( fn check_tx_height(test: &Test, client: &mut NamadaCmd) -> Result { let (_unread, matched) = client.exp_regex(r"height .*")?; - // Expecting e.g. "height 1337." + // Expecting e.g. "height 1337, consuming x gas units." let height_str = matched .trim() .split_once(' ') .unwrap() .1 - .split_once('.') + .split_once(',') .unwrap() .0; let height: u32 = height_str.parse().unwrap(); diff --git a/crates/tx/src/data/mod.rs b/crates/tx/src/data/mod.rs index 6792acc83c..8c6c1b4095 100644 --- a/crates/tx/src/data/mod.rs +++ b/crates/tx/src/data/mod.rs @@ -496,7 +496,7 @@ pub struct VpsResult { impl fmt::Display for TxResult { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { if f.alternate() { - write!(f, "Transaction is valid. Gas used: {}", self.gas_used,) + write!(f, "Transaction is valid. Gas used: {}", self.gas_used) } else { write!(f, "{}", serde_json::to_string(self).unwrap()) } diff --git a/crates/tx/src/data/wrapper.rs b/crates/tx/src/data/wrapper.rs index 23bd4c53f1..3a2f1ebcc7 100644 --- a/crates/tx/src/data/wrapper.rs +++ b/crates/tx/src/data/wrapper.rs @@ -111,13 +111,10 @@ impl From for Amount { } } -impl TryFrom for Gas { - type Error = std::io::Error; - - /// Derive a Gas instance with a sub amount which is exactly a whole - /// amount since the limit represents gas in whole units - fn try_from(value: GasLimit) -> Result { - Self::from_whole_units(u64::from(value)).ok_or_else(|| { +impl GasLimit { + /// Convert the gas limit into scaled gas + pub fn as_scaled_gas(&self, scale: u64) -> Result { + Gas::from_whole_units(u64::from(*self), scale).ok_or_else(|| { std::io::Error::new( std::io::ErrorKind::InvalidInput, "gas overflow", diff --git a/genesis/localnet/parameters.toml b/genesis/localnet/parameters.toml index 17c03b9c62..f2d16129d2 100644 --- a/genesis/localnet/parameters.toml +++ b/genesis/localnet/parameters.toml @@ -22,6 +22,8 @@ masp_epoch_multiplier = 2 max_block_gas = 20000000 # Fee unshielding gas limit fee_unshielding_gas_limit = 20000 +# Gas scale +gas_scale = 100_000_000 # Map of the cost per gas unit for every token allowed for fee payment [parameters.minimum_gas_price] diff --git a/genesis/starter/parameters.toml b/genesis/starter/parameters.toml index 6889b8125e..1541779cd0 100644 --- a/genesis/starter/parameters.toml +++ b/genesis/starter/parameters.toml @@ -24,6 +24,8 @@ max_signatures_per_transaction = 15 max_block_gas = 20000000 # Fee unshielding gas limit fee_unshielding_gas_limit = 20000 +# Gas scale +gas_scale = 100_000_000 # Map of the cost per gas unit for every token allowed for fee payment [parameters.minimum_gas_price]