appliedzkp的zkevm(4)Call context

1. 引言

曾用名为call_id,即将重命名为call_text。
call_context用于:告知EVM proof,which is the correct context the memory, storage and stack operations should be applied inside,如:

  • 1)During a call, stack和memory context变了,而storage context保持未变。
  • 2)During a call_data_copy,会根据calling contract 调整the source memory context。
  • 3)During a return_data_copy,会根据最后返回的call_context调整the source memory context。(This is not tracked inside the call_context but is good to note)

call_context用于track the correct call context that the memory, storage and stack ops are applied to。

2. call_context内容

call_context中包含的元素有:

struct CallContext {
    msg_sender: EthAddress
    gas_available: u256
    gas_used_before_this_call: u256
    // tells us if this transaction will throw or revert in the future 
    is_persistant: bool
    is_static_call: bool
    // a count of the number of storage updates that need to be undone. 
    revert_todo: u256
    // This is the global counter minimum global counter that needs to be reverted.
    gc_to_revert_to: u256
    call_depth: u256
}

impl Commitable for CallContext {
    fn commit(){
        return (
            msg_sender + 
            gas_available * r + 
            gas_used_before_this_call * r**2 +
            is_persistant * r**3 +
            is_static_call * r**4 +
            revert_todo * r**5 +
            gc_to_revert_to * r**6 +
            call_depth * r**7
        )
    }
}

即call_context为a random linear combination of:

  • 1)msg.sender
  • 2)gas_available
  • 3)gas_used_before_this_call
  • 4)is_persistant:为binary flag,用于标记该交易未来是否将revert或throw。
  • 5)is_static_call
  • 6)revert_todo:为计数器,表示undone对应所需的storage updates数。
  • 7)gc_to_revert_to:为revert所需的最小global counter。
  • 8)call_depth

其中 r = h a s h ( m s g . s e n d e r . . . c a l l _ d e p t h ) r=hash(msg.sender...call\_depth) r=hash(msg.sender...call_depth),相应的call_context commitment值表示为: C o m ( c a l l _ c o n t e x t ) = m s g . s e n d e r + g a s _ a v a i l a b l e ∗ r . . . + c a l l _ d e p t h ∗ r 7 Com(call\_context)=msg.sender+gas\_available * r ...+ call\_depth*r^7 Com(call_context)=msg.sender+gas_availabler...+call_depthr7

3. 其它相关条款

3.1 Reverts/throws

若Reverts/throws,需做如下动作:

  • 1)Find how far back we need to revert:
  • 2)revert all storage operations until that point
  • 3)若为REVERT op,其为一种特殊的错误场景,除以上2个动作外,还需额外refund left gas。而其它错误场景会consume all left gas。

3.2 Storage

is_persist = 1时,正常进行storage updates操作即可。
is_persist = 0时,进行storage updates操作时,需做好revert every storage we do的准备。需要对每次storage update进行计数。我们根据职能合约中的定义执行所有storage updates。当遇到revert操作时,需undo all these updates。

通常会强制Prover展示在gcgc_to_revert_to之间发生的todo_revert storage writes。
为了简化,在storage write bus mapping中会包含 写入前的值 和 写入后的值。当revert时,当gc <= gc_to_revert_to时,将该list中的每个storage value设为写入前的值,依次回退。

对于STATICCALL op,若满足以下情况,将revert to snapshot,同时consume all gas_available:

  • 1)op可修改状态 (SSTORE, LOGX, CREATEX)
  • 2)CALL with value

revert操作会revert整条调用链。

throw是revert的特例情况,throw没有gas剩余,会消耗所有gas。在solidity 0.5中已移除了throw操作。

对同一子合约的调用应在同一call context下,以保证storage的一致性。如合约A多次触发 B.counter++ ,若每次调用在不同的call context,结果将不正确。

call_context也可用作a digest of parent call and last child call,因此所需记忆的所有内容应包含在call context 内部。

对于每一个op_lookup(addr, pc, op), 需要Prover明确告知是否可进行lookup操作,若可以,则lookup for correct op;若不可以,则知道其已pad STOP,并switch到parent context。

参考资料

[1] https://hackmd.io/HfCsKWfWRT-B_k5j3LjIVw
[2] https://hackmd.io/0Z3N9gniRAmOg8X1RN6VAg

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值