Skip to content

GitLab

  • Projects
  • Groups
  • Snippets
  • Help
    • Loading...
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
    • Contribute to GitLab
  • Sign in / Register
zkevm-circuits
zkevm-circuits
  • Project overview
    • Project overview
    • Details
    • Activity
    • Releases
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributors
    • Graph
    • Compare
  • Issues 0
    • Issues 0
    • List
    • Boards
    • Labels
    • Service Desk
    • Milestones
  • Merge Requests 0
    • Merge Requests 0
  • CI / CD
    • CI / CD
    • Pipelines
    • Jobs
    • Schedules
  • Operations
    • Operations
    • Incidents
    • Environments
  • Packages & Registries
    • Packages & Registries
    • Package Registry
  • Analytics
    • Analytics
    • CI / CD
    • Repository
    • Value Stream
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Members
    • Members
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar

新注册的用户请输入邮箱并保存,随后登录邮箱激活账号。后续可直接使用邮箱登录!

  • zkp
  • zkevm-circuitszkevm-circuits
  • Wiki
    • Zkevm docs
    • 4 core
  • core log

Last edited by 桂忠 Aug 07, 2024
Page history

core log

LOG指令

处理流程

LOG0

flowchart LR
    LogBytes --> MEMORY_GAS --> LOG_GAS --> LogTopicNumAddr

LOG1-LOG4

flowchart LR
   LogBytes --> MEMORY_GAS --> LOG_GAS --> LogTopicNumAddr --> LogTopic:topic0 --> LogTopic:topic1 --> ...
  • LogBytes: 处理Log数据拷贝(Copy Lookup Memory->PublicLog)和数据长度记录(Public Lookup)
  • Memory_gas: 计算Log操作需要的memory gas花费;
  • Log_gas: 计算Log操作最终的gas花费;
  • LogTopicNumAddr: 处理Log数据地址(Public Lookup)
  • LogTopic: 处理每一个TopicHash处理(Public Lookup)

主要约束及状态变化

LOG0为例:

指令 状态 State参数 约束 gen witness 状态变化
LOG0 LogBytes state1=offset state_stamp = pre + 2
state2=length log_stamp = pre
next_pc = pc
memory_gas memory_gas = GasCost::MEMORY_EXPANSION_LINEAR_COEFF.expr() * (next_word_size - memory_chunk_prev) * (next_quad_memory_cost - curr_quad_memory_cost)
log_gas gas_cost = memory_gas_cost + GasCost::LOG.expr() + topic_gas + length * GasCost::LOG_DATA_GAS.expr()
LogTopicNumAddr - state_stamp = pre 根据opcode 切换值state.topic_left
log_stamp = pre + (1*topic_left_0) topic_left==0时log_stamp+1
next_pc = pc + (1*topic_left_0)

LOG1为例:

指令 状态 State参数 约束 gen witness 状态变化
LOG1 LogBytes state1=offset state_stamp = pre + 2
state2=length log_stamp = pre
next_pc = pc
memory_gas memory_gas = GasCost::MEMORY_EXPANSION_LINEAR_COEFF.expr() * (next_word_size - memory_chunk_prev) * (next_quad_memory_cost - curr_quad_memory_cost)
log_gas gas_cost = memory_gas_cost + GasCost::LOG.expr() + topic_gas + length * GasCost::LOG_DATA_GAS.expr()
LogTopicNumAddr - state_stamp = pre 根据opcode切换值state.topic_left
log_stamp = pre + (1*topic_left_0) topic_left==0时log_stamp+1
next_pc = pc
LogTopic state1=cur_topic_hash state_stamp = pre+1 state.topic_left -=1
log_stamp = pre + (1*topic_left_0) topic_left==0时log_stamp+1

具体Gadget设计

LogBytesGadget设计

处理memory[offset:offset+length],数据从Memory拷贝到PulbicLog

主要约束:

  • state_stamp = pre + 2
  • log_stamp = pre
  • next_pc = pc

gen_witness状态变化

  • 无
cnt
2 COPY(9) - - PUBLIC(6)
1 STATE1(8) STATE2(8) - LO_INV(1)
0 DYNA_SELECTOR(20) AUX(7) - -

CoreRow2-COPY(9) vers_0~vers_8,负责Copy Lookup(处理Log数据拷贝)

cnt vers_0 vers_1 vers_2 vers_3 vers_4 vers_5 vers_6 vers_7 vers_8
2 src_type=Memory src_id=self.call_id src_pointer=1 src_stamp=2 dst_type=PublicLog dst_id=self.tx_idx dst_pointer=0(PublicLogIndex) dst_stamp=log_stamp len=length

CoreRow2-PUBlIC(6) vers_24~vers_31,负责Public Lookup(处理Log数据长度)

cnt vers_26 vers_27 vers_28 vers_29 vers_30 vers_31
2 tag=TxLog tx_idx=self.tx_idx log_index=self.log_stamp log_tag=DataSize 0 data_len=length

CoreRow1-STATE1(8) vers_0~vers_7,负责从栈中取出的offset

cnt vers_0 vers_1 vers_2 vers_3 vers_4 vers_5 vers_6 vers_7
1 tag=Stack stamp value_hi=0 value_lo=offset call_id_contract_addr=self.call_id - pointer_lo is_write=0

CoreRow1-STATE2(8) vers_8~vers_15,负责从栈中取出的length

cnt vers_0 vers_1 vers_2 vers_3 vers_4 vers_5 vers_6 vers_7
1 tag=Stack stamp value_hi=0 value_lo=length call_id_contract_addr=self.call_id - pointer_lo is_write=0

CoreRow1-LO_INV(1) vers_24

cnt vers_24
1 len_lo_inv

MEMORY_GAS

cnt
1 MEMORY_EXPANSION(2..6) U64DIV(7..11) U64DIV(12..16) SELECTOR(17..30)
0 DYNAMIC(0..17) AUX(18..24) MEMORY_GAS(26) NEXT_IS_LOG_GAS(29) NEXT_IS_PURE_MEMORY_GAS(30) NEXT_IS_MEMORY_COPIER_GAS(31)

主要约束:

  • memory_gas = GasCost::MEMORY_EXPANSION_LINEAR_COEFF.expr() * (next_word_size - memory_chunk_prev) * (next_quad_memory_cost - curr_quad_memory_cost)
    • next_word_size = (new_memory_size + 31) / 32,new_memory_size是通过stack中的offset+length;
    • next_quad_memory_cost = next_word_size * next_word_size / 512;

cnt = 0行:

  • 预留vers_26为计算出的memory_gas,提供给下一个状态使用,vers_29, vers_30, vers_31 为下一个状态约束需要的条件。

cnt = 1行:

  • MEMORY_EXPANSION为Max(cur_memory_size, memory_size)
  • 第一个U64Div为 cur_memory_size * cur_memory_size / 512 = curr_quad_memory_cost
  • 第二个U64Div为 next_memory_size * next_memory_size / 512 = next_quad_memory_cost
  • SELECTOR为opcode选择器。

LOG_GAS

cnt
1 U64OVERFLOW SELECTOR(7..11)
0 DYNAMIC(0..17) AUX(18..24)

主要约束:

  • gas_cost = memory_gas_cost + GasCost::LOG.expr() + topic_gas + length * GasCost::LOG_DATA_GAS.expr(),其中:
    • topic_gas = n * GasCost::LOG.expr(), n为LOG_n;
    • length 为 stack中的参数;

cnt = 1 行:

  • U64OVERFLOW 为gas_left u64的约束;
  • SELECTOR为LOG0-4的选择器。

LogTopicNumAddrGadget设计

主要约束:

  • state_stamp = pre
  • log_stamp = pre + (1 * topic_left_0)
  • next_pc = pc + (1 * topic_left_0)

gen_witness状态变化

  • 根据opcode初始化state.topic_left
  • state.topic_left==0时 log_stamp += 1
cnt
2 - - - PUBLIC(6)
1 - LOG_LEFT_X(5) - -
0 DYNA_SELECTOR(20) AUX(7) - -

CoreRow2-PUBlIC(6) vers_24~vers_31,负责Public Lookup(处理Topic数目和地址)

cnt vers_26 vers_27 vers_28 vers_29 vers_30 vers_31
2 tag=TxLog tx_idx=self.tx_idx log_index=self.log_stamp topic_log_tag=AddrWithLogX address[..4] address[4..]

CoreRow1-LOG_LEFT_X(5) vers_8~vers_12,选择器LOG_LEFT_4~LOG_LEFT_0

cnt vers_8 vers_9 vers_10 vers_11 vers_12
1 LOG_LEFT_4 LOG_LEFT_3 LOG_LEFT_2 LOG_LEFT_1 LOG_LEFT_0

LogTopicGadget设计

主要约束:

  • state_stamp = pre
  • log_stamp = pre + (1 * topic_left_0)
  • next_pc = pc + (1 * topic_left_0)

gen_witness状态变化

  • state.topic_left -= 1
  • state.topic_left==0时 log_stamp += 1
cnt
2 - - - PUBLIC(6)
1 STATE1(8) LOG_LEFT_X(5) - -
0 DYNA_SELECTOR(20) AUX(7) - -

CoreRow2-PUBlIC(6) vers_24~vers_31,负责Public Lookup(处理Topic哈希数据)

cnt vers_26 vers_27 vers_28 vers_29 vers_30 vers_31
2 tag=TxLog tx_idx=self.tx_idx log_index=self.log_stamp topic_log_tag=TopicX topic hash[..16] topic hash[16..]

CoreRow1-STATE1(8) vers_0~vers_7,负责从栈中取出的topic_hash

cnt vers_0 vers_1 vers_2 vers_3 vers_4 vers_5 vers_6 vers_7
1 tag=Stack stamp=0 value_hi=0 value_lo=topic_hash call_id_contract_addr=self.call_id - pointer_lo=2 is_write=0

CoreRow1-LOG_LEFT_X(5) vers_8~vers_12,选择器LOG_LEFT_4~LOG_LEFT_0

cnt vers_8 vers_9 vers_10 vers_11 vers_12
1 LOG_LEFT_4 LOG_LEFT_3 LOG_LEFT_2 LOG_LEFT_1 LOG_LEFT_0
Clone repository

Copyright © 2024 ChainWeaver Org. All Rights Reserved. 版权所有。

京ICP备2023035722号-3

京公网安备 11010802044225号