Skip to content

Commit

Permalink
Improves gas logging in dry-run
Browse files Browse the repository at this point in the history
  • Loading branch information
grarco committed May 31, 2023
1 parent 2fde40c commit 9ae71ad
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 43 deletions.
111 changes: 70 additions & 41 deletions apps/src/lib/node/ledger/shell/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand All @@ -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 =
<EllipticCurve as PairingEngine>::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"),
Expand All @@ -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(&parameters::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(&parameters::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(&parameters::storage::get_max_block_gas_key())
.expect("Error while reading storage key")
.expect("Missing parameter in storage"),
)
}
};

match protocol::apply_tx(
Expand All @@ -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);
Expand Down Expand Up @@ -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<CA>(
&self,
Expand Down Expand Up @@ -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,
Expand Down
23 changes: 21 additions & 2 deletions shared/src/ledger/queries/shell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 =
Expand All @@ -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(&parameters::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 {
Expand All @@ -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(&parameters::storage::get_max_block_gas_key())
.expect("Error while reading storage")
.expect("Missing parameter in storage"),
)
}
};

Expand All @@ -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 {
Expand Down

0 comments on commit 9ae71ad

Please sign in to comment.