Skip to content

Commit

Permalink
feat: return actual gas charged to the transaction caller for zkVM tr…
Browse files Browse the repository at this point in the history
…ansactions (#592)
  • Loading branch information
elfedy authored Sep 26, 2024
1 parent 22871de commit d1b59e9
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 53 deletions.
104 changes: 56 additions & 48 deletions crates/cheatcodes/src/inspector.rs
Original file line number Diff line number Diff line change
Expand Up @@ -990,9 +990,7 @@ impl Cheatcodes {
gas_limit: input.gas_limit(),
};

// We currently exhaust the entire gas for the call as zkEVM returns a very high
// amount of gas that OOGs revm.
let gas = Gas::new(input.gas_limit());
let mut gas = Gas::new(input.gas_limit());
match foundry_zksync_core::vm::create::<_, DatabaseError>(
&create_inputs,
zk_contract,
Expand Down Expand Up @@ -1034,32 +1032,38 @@ impl Cheatcodes {
}

match result.execution_result {
ExecutionResult::Success { output, .. } => match output {
Output::Create(bytes, address) => Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Return,
output: bytes,
gas,
},
address,
}),
_ => Some(CreateOutcome {
ExecutionResult::Success { output, gas_used, .. } => {
let _ = gas.record_cost(gas_used);
match output {
Output::Create(bytes, address) => Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Return,
output: bytes,
gas,
},
address,
}),
_ => Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output: Bytes::new(),
gas,
},
address: None,
}),
}
}
ExecutionResult::Revert { output, gas_used, .. } => {
let _ = gas.record_cost(gas_used);
Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output: Bytes::new(),
output,
gas,
},
address: None,
}),
},
ExecutionResult::Revert { output, .. } => Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output,
gas,
},
address: None,
}),
})
}
ExecutionResult::Halt { .. } => Some(CreateOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
Expand Down Expand Up @@ -1575,9 +1579,7 @@ impl Cheatcodes {
paymaster_data: self.paymaster_params.take(),
};

// We currently exhaust the entire gas for the call as zkEVM returns a very high amount
// of gas that OOGs revm.
let gas = Gas::new(call.gas_limit);
let mut gas = Gas::new(call.gas_limit);
match foundry_zksync_core::vm::call::<_, DatabaseError>(call, factory_deps, ecx, ccx) {
Ok(result) => {
// append console logs from zkEVM to the current executor's LogTracer
Expand Down Expand Up @@ -1616,32 +1618,38 @@ impl Cheatcodes {
}

match result.execution_result {
ExecutionResult::Success { output, .. } => match output {
Output::Call(bytes) => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Return,
output: bytes,
gas,
},
memory_offset: call.return_memory_offset.clone(),
}),
_ => Some(CallOutcome {
ExecutionResult::Success { output, gas_used, .. } => {
let _ = gas.record_cost(gas_used);
match output {
Output::Call(bytes) => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Return,
output: bytes,
gas,
},
memory_offset: call.return_memory_offset.clone(),
}),
_ => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output: Bytes::new(),
gas,
},
memory_offset: call.return_memory_offset.clone(),
}),
}
}
ExecutionResult::Revert { output, gas_used, .. } => {
let _ = gas.record_cost(gas_used);
Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output: Bytes::new(),
output,
gas,
},
memory_offset: call.return_memory_offset.clone(),
}),
},
ExecutionResult::Revert { output, .. } => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
output,
gas,
},
memory_offset: call.return_memory_offset.clone(),
}),
})
}
ExecutionResult::Halt { .. } => Some(CallOutcome {
result: InterpreterResult {
result: InstructionResult::Revert,
Expand Down
16 changes: 11 additions & 5 deletions crates/zksync/core/src/vm/inspect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,6 @@ where
.map(|factory_deps| (*factory_deps).clone())
.unwrap_or_default();

let env_tx_gas_limit = ecx.env.tx.gas_limit;
let mut era_db = ZKVMData::new_with_system_contracts(ecx, chain_id)
.with_extra_factory_deps(persisted_factory_deps)
.with_storage_accesses(ccx.accesses.take());
Expand Down Expand Up @@ -199,7 +198,7 @@ where
} = inspect_inner(tx, storage_ptr, chain_id, ccx, call_ctx);

info!(
limit=?gas_usage.limit, execution=?gas_usage.execution, pubdata=?gas_usage.pubdata, refunded=?gas_usage.refunded,
reserved=?gas_usage.bootloader_debug.reserved_gas, limit=?gas_usage.limit, execution=?gas_usage.execution, pubdata=?gas_usage.pubdata, refunded=?gas_usage.refunded,
"gas usage",
);

Expand Down Expand Up @@ -260,7 +259,7 @@ where
call_traces,
execution_result: rExecutionResult::Success {
reason: SuccessReason::Return,
gas_used: tx_result.statistics.gas_used,
gas_used: gas_usage.gas_used(),
gas_refunded: tx_result.refunds.gas_refunded,
logs,
output,
Expand All @@ -278,7 +277,7 @@ where
logs,
call_traces,
execution_result: rExecutionResult::Revert {
gas_used: env_tx_gas_limit - tx_result.refunds.gas_refunded,
gas_used: gas_usage.gas_used(),
output: Bytes::from(output),
},
}
Expand All @@ -295,7 +294,7 @@ where
call_traces,
execution_result: rExecutionResult::Halt {
reason: mapped_reason,
gas_used: env_tx_gas_limit - tx_result.refunds.gas_refunded,
gas_used: gas_usage.gas_used(),
},
}
}
Expand Down Expand Up @@ -391,6 +390,13 @@ struct ZkVmGasUsage {
pub bootloader_debug: BootloaderDebug,
}

impl ZkVmGasUsage {
pub fn gas_used(&self) -> u64 {
// Gas limit is capped by the environment so gas should never reach max u64
self.execution.saturating_add(self.pubdata).as_u64()
}
}

struct InnerZkVmResult {
tx_result: VmExecutionResultAndLogs,
bytecodes: HashMap<U256, Vec<U256>>,
Expand Down

0 comments on commit d1b59e9

Please sign in to comment.