memory chunk
memory_chunk 是 auxiliary 中的一个变量,保存了当前 opcode 执行完成之后,memory 的 byte size。与之对应的是常用的 memory_chunk_prev,指的是opcode 执行之前的数值,通常通过读取上一opcode的auxiliary获取。
trace 打印出来,memory 有多少行,memory chunk 就是多少。由于 EVM 生成的 trace 的 memory 是执行前,所以使用preprocess_trace 这个函数,统一处理成,每个 trace step 对应的 memory 是执行之后的。
约束实现
-
首先需要计算出访问到的内存段的右区间 offset_bound = offset + size。
-
使用 memory_expansion 比较 offset_bound 和 memory_chunk_prev,得出当前是否有内存拓展 expansion_tag,和 access_memory_size。
-
跟据上述计算,可以计算出当前步骤执行完之后 memory 的正确数值 memory_chunk_to,那么在get_auxiliary_constraints 传入相关的delta memory_chunk: ExpressionOutcome::To(memory_chunk_to)进行约束。
call 时的 context 转换
因为 call 同时对memory进行两次 access,所以需要两次 memory_expansion,上下文转换和 stack_pointer 类似,不赘述。
需要注意的是 memory_chunk 在call_4 才计算完 memory_expansion 。所以在 current_state 这里跳过前几步的 memory_chunk 更新。
let memory_chunk = match self {
ExecutionState::CALL_1 | ExecutionState::CALL_2 | ExecutionState::CALL_3 => {
current_state.memory_chunk_prev
}
_ => current_state.memory_chunk,
};