Skip to content
This repository has been archived by the owner on Jul 5, 2024. It is now read-only.

insufficient balance error circuit #919

Closed
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
13 changes: 5 additions & 8 deletions bus-mapping/src/evm/opcodes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ mod stackonlyop;
mod stop;
mod swap;

mod error_insufficient_balance;
mod error_invalid_jump;

#[cfg(test)]
Expand All @@ -71,6 +72,7 @@ use codecopy::Codecopy;
use codesize::Codesize;
use create::DummyCreate;
use dup::Dup;
use error_insufficient_balance::InsufficientBalance;
use error_invalid_jump::ErrorInvalidJump;
use exp::Exponentiation;
use extcodecopy::Extcodecopy;
Expand Down Expand Up @@ -261,6 +263,7 @@ fn fn_gen_associated_ops(opcode_id: &OpcodeId) -> FnGenAssociatedOps {
fn fn_gen_error_state_associated_ops(error: &ExecError) -> FnGenAssociatedOps {
match error {
ExecError::InvalidJump => ErrorInvalidJump::gen_associated_ops,
ExecError::InsufficientBalance => InsufficientBalance::gen_associated_ops,
// more future errors place here
_ => {
warn!("Using dummy gen_associated_ops for error state {:?}", error);
Expand Down Expand Up @@ -309,14 +312,8 @@ pub fn gen_associated_ops(
if exec_step.oog_or_stack_error() {
state.gen_restore_context_ops(&mut exec_step, geth_steps)?;
} else {
if geth_step.op.is_call_or_create() {
let call = state.parse_call(geth_step)?;
// Switch to callee's call context
state.push_call(call);
} else {
let fn_gen_error_associated_ops = fn_gen_error_state_associated_ops(&exec_error);
return fn_gen_error_associated_ops(state, geth_steps);
}
let fn_gen_error_associated_ops = fn_gen_error_state_associated_ops(&exec_error);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what is done whith this new variable. Which seems to be dropped immediately and does nothing and is not passed anywhere.

Copy link
Collaborator Author

@DreamWuGit DreamWuGit Dec 2, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@CPerezz trying to merge this error state into CallOp code as found many of code shares with it especially for gas cost related stuff. if it works, will update spec accordingly.

return fn_gen_error_associated_ops(state, geth_steps);
}

state.handle_return(geth_step)?;
Expand Down
73 changes: 73 additions & 0 deletions bus-mapping/src/evm/opcodes/error_insufficient_balance.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
use super::Opcode;
use crate::{
circuit_input_builder::{CircuitInputStateRef, ExecStep},
operation::{AccountField, CallContextField},
Error,
};
use eth_types::{GethExecStep, ToWord};

/// Placeholder structure used to implement [`Opcode`] trait over it
/// corresponding to the `OpcodeId::CALL` `OpcodeId`.
#[derive(Debug, Copy, Clone)]
pub(crate) struct InsufficientBalance;

impl Opcode for InsufficientBalance {
fn gen_associated_ops(
state: &mut CircuitInputStateRef,
geth_steps: &[GethExecStep],
) -> Result<Vec<ExecStep>, Error> {
let geth_step = &geth_steps[0];
let mut exec_step = state.new_step(geth_step)?;
let next_step = if geth_steps.len() > 1 {
Some(&geth_steps[1])
} else {
None
};
exec_step.error = state.get_step_err(geth_step, next_step).unwrap();

let args_offset = geth_step.stack.nth_last(3)?.as_usize();
let args_length = geth_step.stack.nth_last(4)?.as_usize();
let ret_offset = geth_step.stack.nth_last(5)?.as_usize();
let ret_length = geth_step.stack.nth_last(6)?.as_usize();

state.call_expand_memory(args_offset, args_length, ret_offset, ret_length)?;

let call = state.parse_call(geth_step).unwrap();
let current_call = state.call()?.clone();

for i in 0..7 {
state.stack_read(
&mut exec_step,
geth_step.stack.nth_last_filled(i),
geth_step.stack.nth_last(i)?,
)?;
}

state.stack_write(
&mut exec_step,
geth_step.stack.nth_last_filled(6),
(0u64).into(), // must fail
)?;

state.call_context_read(
&mut exec_step,
current_call.call_id,
CallContextField::CalleeAddress,
current_call.address.to_word(),
);

let (_, callee_account) = state.sdb.get_account(&current_call.address);

state.account_read(
&mut exec_step,
current_call.address,
AccountField::Balance,
callee_account.balance,
callee_account.balance,
)?;

state.push_call(call);
state.handle_return(geth_step)?;
Ok(vec![exec_step])
}
}
4 changes: 3 additions & 1 deletion zkevm-circuits/src/evm_circuit/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ mod dummy;
mod dup;
mod end_block;
mod end_tx;
mod error_insufficient_balance;
mod error_invalid_jump;
mod error_oog_constant;
mod error_oog_static_memory;
Expand Down Expand Up @@ -108,6 +109,7 @@ use dummy::DummyGadget;
use dup::DupGadget;
use end_block::EndBlockGadget;
use end_tx::EndTxGadget;
use error_insufficient_balance::ErrorInsufficientBalance;
use error_invalid_jump::ErrorInvalidJumpGadget;
use error_oog_constant::ErrorOOGConstantGadget;
use exp::ExponentiationGadget;
Expand Down Expand Up @@ -268,7 +270,7 @@ pub(crate) struct ExecutionConfig<F> {
error_oog_static_call: DummyGadget<F, 0, 0, { ExecutionState::ErrorOutOfGasSTATICCALL }>,
error_oog_self_destruct: DummyGadget<F, 0, 0, { ExecutionState::ErrorOutOfGasSELFDESTRUCT }>,
error_oog_code_store: DummyGadget<F, 0, 0, { ExecutionState::ErrorOutOfGasCodeStore }>,
error_insufficient_balance: DummyGadget<F, 0, 0, { ExecutionState::ErrorInsufficientBalance }>,
error_insufficient_balance: ErrorInsufficientBalance<F>,
error_invalid_jump: ErrorInvalidJumpGadget<F>,
error_depth: DummyGadget<F, 0, 0, { ExecutionState::ErrorDepth }>,
error_write_protection: DummyGadget<F, 0, 0, { ExecutionState::ErrorWriteProtection }>,
Expand Down
18 changes: 0 additions & 18 deletions zkevm-circuits/src/evm_circuit/execution/callop.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,24 +530,6 @@ mod test {
use mock::TestContext;
use std::default::Default;

#[test]
fn callop_insufficient_balance() {
let opcodes = [OpcodeId::CALL, OpcodeId::STATICCALL];
let stacks = [Stack {
// this value is bigger than caller's balance
value: Word::from(11).pow(18.into()),
..Default::default()
}];
let callees = [callee(bytecode! {}), callee(bytecode! { STOP })];
for ((opcode, stack), callee) in opcodes
.into_iter()
.cartesian_product(stacks.into_iter())
.cartesian_product(callees.into_iter())
{
test_ok(caller_for_insufficient_balance(opcode, stack), callee);
}
}

#[test]
fn callop_nested() {
for opcode in [OpcodeId::CALL, OpcodeId::STATICCALL] {
Expand Down
Loading