From 90740a64fbf6f08c79d9b94823424c606e47b3e8 Mon Sep 17 00:00:00 2001 From: Marco Granelli Date: Tue, 30 May 2023 11:36:01 +0200 Subject: [PATCH] Improves gas logging in dry-run --- apps/src/lib/node/ledger/shell/mod.rs | 111 ++++++++++++++++---------- shared/src/ledger/queries/shell.rs | 23 +++++- 2 files changed, 91 insertions(+), 43 deletions(-) diff --git a/apps/src/lib/node/ledger/shell/mod.rs b/apps/src/lib/node/ledger/shell/mod.rs index e0393a36990..d6bc48079cb 100644 --- a/apps/src/lib/node/ledger/shell/mod.rs +++ b/apps/src/lib/node/ledger/shell/mod.rs @@ -809,6 +809,7 @@ where .expect("Error while reading from storage") .expect("Missing gas table in storage"); let mut write_log = WriteLog::default(); + let mut cumulated_gas = 0; let mut vp_wasm_cache = self.vp_wasm_cache.read_only(); let mut tx_wasm_cache = self.tx_wasm_cache.read_only(); let raw_tx = match Tx::try_from(tx_bytes) { @@ -829,34 +830,36 @@ where }; // Wrapper dry run to allow estimating the gas cost of a transaction - let mut tx_gas_meter = if let TxType::Wrapper(wrapper) = &tx { - let mut tx_gas_meter = - TxGasMeter::new(wrapper.gas_limit.to_owned().into()); - if let Err(e) = protocol::apply_tx( - tx.clone(), - tx_bytes, - TxIndex::default(), - &mut tx_gas_meter, - &gas_table, - &mut write_log, - &self.wl_storage.storage, - &mut self.vp_wasm_cache.clone(), - &mut self.tx_wasm_cache.clone(), - None, - #[cfg(not(feature = "mainnet"))] - false, - ) { - response.code = 1; - response.log = format!("{}", e); - return response; - }; + let mut tx_gas_meter = match tx { + TxType::Wrapper(ref wrapper) => { + let mut tx_gas_meter = + TxGasMeter::new(wrapper.gas_limit.to_owned().into()); + if let Err(e) = protocol::apply_tx( + tx.clone(), + tx_bytes, + TxIndex::default(), + &mut tx_gas_meter, + &gas_table, + &mut write_log, + &self.wl_storage.storage, + &mut self.vp_wasm_cache.clone(), + &mut self.tx_wasm_cache.clone(), + None, + #[cfg(not(feature = "mainnet"))] + false, + ) { + response.code = 1; + response.log = format!("{}", e); + return response; + }; - write_log.commit_tx(); + write_log.commit_tx(); + cumulated_gas = tx_gas_meter.get_current_transaction_gas(); - // NOTE: the encryption key for a dry-run should always be an hardcoded, dummy one - let privkey = + // NOTE: the encryption key for a dry-run should always be an hardcoded, dummy one + let privkey = ::G2Affine::prime_subgroup_generator(); - tx = TxType::Decrypted(DecryptedTx::Decrypted { + tx = TxType::Decrypted(DecryptedTx::Decrypted { tx: wrapper .decrypt(privkey) .expect("Could not decrypt the inner tx"), @@ -865,20 +868,39 @@ where // that we got a valid PoW has_valid_pow: true, }); - TxGasMeter::new( - tx_gas_meter - .tx_gas_limit - .checked_sub(tx_gas_meter.get_current_transaction_gas()) - .unwrap_or_default(), - ) - } else { - // If dry run only the inner tx, use the max block gas as the gas limit - TxGasMeter::new( - self.wl_storage - .read(¶meters::storage::get_max_block_gas_key()) - .expect("Error while reading storage key") - .expect("Missing parameter in storage"), - ) + TxGasMeter::new( + tx_gas_meter + .tx_gas_limit + .checked_sub(tx_gas_meter.get_current_transaction_gas()) + .unwrap_or_default(), + ) + } + TxType::Protocol(_) | TxType::Decrypted(_) => { + // If dry run only the inner tx, use the max block gas as the gas limit + TxGasMeter::new( + self.wl_storage + .read(¶meters::storage::get_max_block_gas_key()) + .expect("Error while reading storage key") + .expect("Missing parameter in storage"), + ) + } + TxType::Raw(raw) => { + // Cast tx to a decrypted for execution + tx = TxType::Decrypted(DecryptedTx::Decrypted { + tx: raw, + + #[cfg(not(feature = "mainnet"))] + has_valid_pow: true, + }); + + // If dry run only the inner tx, use the max block gas as the gas limit + TxGasMeter::new( + self.wl_storage + .read(¶meters::storage::get_max_block_gas_key()) + .expect("Error while reading storage key") + .expect("Missing parameter in storage"), + ) + } }; match protocol::apply_tx( @@ -897,7 +919,12 @@ where ) .map_err(Error::TxApply) { - Ok(result) => response.info = result.to_string(), + Ok(mut result) => { + cumulated_gas += tx_gas_meter.get_current_transaction_gas(); + // Account gas for both inner and wrapper (if available) + result.gas_used = cumulated_gas; + response.info = format!("{}", result.to_string(),); + } Err(error) => { response.code = 1; response.log = format!("{}", error); @@ -991,7 +1018,7 @@ where /// Check that the Wrapper's signer has enough funds to pay fees. /// /// For security reasons, the `chain_id` and `expiration` fields should come - /// from the serialized wrapper, not from the Shell. + /// from the serialized wrapper, not from the Shell. //FIXME: remove this and check it remove from other places #[allow(clippy::too_many_arguments)] pub fn wrapper_fee_check( &self, @@ -1065,8 +1092,10 @@ where .expect("Missing fee unshielding gas limit in storage"); // Runtime check + tracing::error!("WAL content: {:?}", temp_wl_storage.write_log); //FIXME: remove match apply_tx( TxType::Decrypted(DecryptedTx::Decrypted { + //FIXME: I can already build this correctly? tx: unshield, #[cfg(not(feature = "mainnet"))] has_valid_pow: false, diff --git a/shared/src/ledger/queries/shell.rs b/shared/src/ledger/queries/shell.rs index 30a50814fad..92cbc551490 100644 --- a/shared/src/ledger/queries/shell.rs +++ b/shared/src/ledger/queries/shell.rs @@ -93,6 +93,7 @@ where let mut tx = process_tx(tx.clone()).into_storage_result()?; let mut write_log = WriteLog::default(); + let mut cumulated_gas = 0; // Wrapper dry run to allow estimating the gas cost of a transaction let mut tx_gas_meter = match tx { @@ -116,6 +117,7 @@ where .into_storage_result()?; write_log.commit_tx(); + cumulated_gas = tx_gas_meter.get_current_transaction_gas(); // NOTE: the encryption key for a dry-run should always be an hardcoded, dummy one let privkey = @@ -136,7 +138,15 @@ where .unwrap_or_default(), ) } - TxType::Protocol(_) | TxType::Decrypted(_) => TxGasMeter::new(u64::MAX), + TxType::Protocol(_) | TxType::Decrypted(_) => { + // If dry run only the inner tx, use the max block gas as the gas limit + TxGasMeter::new( + ctx.wl_storage + .read(¶meters::storage::get_max_block_gas_key()) + .expect("Error while reading storage") + .expect("Missing parameter in storage"), + ) + } TxType::Raw(raw) => { // Cast tx to a decrypted for execution tx = TxType::Decrypted(DecryptedTx::Decrypted { @@ -146,7 +156,13 @@ where has_valid_pow: true, }); - TxGasMeter::new(u64::MAX) + // If dry run only the inner tx, use the max block gas as the gas limit + TxGasMeter::new( + ctx.wl_storage + .read(¶meters::storage::get_max_block_gas_key()) + .expect("Error while reading storage") + .expect("Missing parameter in storage"), + ) } }; @@ -165,6 +181,9 @@ where false, ) .into_storage_result()?; + cumulated_gas += tx_gas_meter.get_current_transaction_gas(); + // Account gas for both inner and wrapper (if available) + data.gas_used = cumulated_gas; // NOTE: the keys changed by the wrapper transaction (if any) are not returned from this function let data = data.try_to_vec().into_storage_result()?; Ok(EncodedResponseQuery {