Polygon zkEVM Prover的 RPC功能

news/2024/11/23 9:40:23/

1. 引言

https://github.com/0xPolygonHermez/zkevm-prover为Polygon zkEVM生成proof,其主要承担3类RPC功能:

  • 1)作为Aggregator RPC client(Prover模块)
  • 2)作为Executor RPC server(Executor模块)
  • 3)作为StateDB RPC server(StateDB模块)

2. 作为Aggregator RPC client

当zkEVM Prover连接某Aggregator server时,其作为Aggregator RPC client:

  • 支持多个zkEVM Prover同时连接同一Aggregator,从而可提供更多的proof generation power。

Channel实现的为Prover client 与 Aggregator server 之间的双向通讯通道,通过Channel函数可获取aggregator messages,并以同一id,通过Channel函数来返回prover messages。详细的RPC接口规范见aggregator.proto

/*** Define all methods implementes by the gRPC* Channel: prover receives aggregator messages and returns prover messages with the same id*/
service AggregatorService {rpc Channel(stream ProverMessage) returns (stream AggregatorMessage) {}
}/*type AggregatorService_ChannelServer interface {Send(*AggregatorMessage) error //发送requestRecv() (*ProverMessage, error) //接收responsegrpc.ServerStream
}*/message AggregatorMessage
{string id = 1;oneof request{GetStatusRequest get_status_request = 2;GenBatchProofRequest gen_batch_proof_request = 3;GenAggregatedProofRequest gen_aggregated_proof_request = 4;GenFinalProofRequest gen_final_proof_request = 5;CancelRequest cancel_request = 6;GetProofRequest get_proof_request = 7;}
}message ProverMessage
{string id = 1;oneof response{GetStatusResponse get_status_response = 2;GenBatchProofResponse gen_batch_proof_response = 3;GenAggregatedProofResponse gen_aggregated_proof_response = 4;GenFinalProofResponse gen_final_proof_response = 5;CancelResponse cancel_response = 6;GetProofResponse get_proof_response = 7;}
}

向Aggregator server调用Channel函数,配套的ProverMessage参数 与 AggregatorMessage参数主要有以下六大类:

  • 1)GetStatusRequest VS GetStatusResponse:Aggregator询问Prover client状态:

    /*** @dev GetStatusRequest*/
    message GetStatusRequest {}
    /*** @dev Response GetStatus* @param {status} - server status* - BOOTING: being ready to compute proofs* - COMPUTING: busy computing a proof* - IDLE: waiting for a proof to compute* - HALT: stop* @param {last_computed_request_id} - last proof identifier that has been computed* @param {last_computed_end_time} - last proof timestamp when it was finished* @param {current_computing_request_id} - id of the proof that is being computed* @param {current_computing_start_time} - timestamp when the proof that is being computed started* @param {version_proto} - .proto verion* @param {version_server} - server version* @param {pending_request_queue_ids} - list of identifierss of proof requests that are in the pending queue* @param {prover_name} - id of this prover server, normally specified via config.json, or UNSPECIFIED otherwise; it does not change if prover reboots* @param {prover_id} - id of this prover instance or reboot; it changes if prover reboots; it is a UUID, automatically generated during the initialization* @param {number_of_cores} - number of cores in the system where the prover is running* @param {total_memory} - total memory in the system where the prover is running* @param {free_memory} - free memory in the system where the prover is running*/
    message GetStatusResponse {enum Status {STATUS_UNSPECIFIED = 0;STATUS_BOOTING = 1;STATUS_COMPUTING = 2;STATUS_IDLE = 3;STATUS_HALT = 4;}Status status = 1;string last_computed_request_id = 2;uint64 last_computed_end_time = 3;string current_computing_request_id = 4;uint64 current_computing_start_time = 5;string version_proto = 6;string version_server = 7;repeated string pending_request_queue_ids = 8;string prover_name = 9;string prover_id = 10;uint64 number_of_cores = 11;uint64 total_memory = 12;uint64 free_memory = 13;uint64 fork_id = 14;
    }
    
  • 2)CancelRequest VS CancelResponse:Aggregator向Prover client请求取消指定的proof request。

    /*** @dev CancelRequest* @param {id} - identifier of the proof request to cancel*/
    message CancelRequest {string id = 1;
    }
    /*** @dev CancelResponse* @param {result} - request result*/
    message CancelResponse {Result result = 1;
    }
    /*** @dev Result*  - OK: succesfully completed*  - ERROR: request is not correct, i.e. input data is wrong*  - INTERNAL_ERROR: internal server error when delivering the response*/
    enum Result {RESULT_UNSPECIFIED = 0;RESULT_OK = 1;RESULT_ERROR = 2;RESULT_INTERNAL_ERROR = 3;
    }
    
  • 3)GetProofRequest VS GetProofResponse:Aggregator向Prover client请求获取指定的recursive proof或final proof。

    /*** @dev Request GetProof* @param {id} - proof identifier of the proof request* @param {timeout} - time to wait until the service responds*/
    message GetProofRequest {string id = 1;uint64 timeout = 2;
    }
    /*** @dev GetProofResponse* @param {id} - proof identifier* @param {final_proof} - groth16 proof + public circuit inputs* @param {recursive_proof} - recursive proof json* @param {result} - proof result*  - COMPLETED_OK: proof has been computed successfully and it is valid*  - ERROR: request error*  - COMPLETED_ERROR: proof has been computed successfully and it is not valid*  - PENDING: proof is being computed*  - INTERNAL_ERROR: server error during proof computation*  - CANCEL: proof has been cancelled* @param {result_string} - extends result information*/
    message GetProofResponse {enum Result {RESULT_UNSPECIFIED = 0;RESULT_COMPLETED_OK = 1;RESULT_ERROR = 2;RESULT_COMPLETED_ERROR = 3;RESULT_PENDING = 4;RESULT_INTERNAL_ERROR = 5;RESULT_CANCEL = 6;}string id = 1;oneof proof {FinalProof final_proof = 2;string recursive_proof =3;}Result result = 4;string result_string = 5;
    }
    
  • 4)GenBatchProofRequest VS GenBatchProofResponse:Aggregator向Prover client发送生成batch proof请求。

    /*** @dev GenBatchProofRequest* @param {input} - input prover*/
    message GenBatchProofRequest {InputProver input = 1;
    }
    /*** @dev InputProver* @param {public_inputs} - public inputs* @param {db} - database containing all key-values in smt matching the old state root* @param {contracts_bytecode} - key is the hash(contractBytecode), value is the bytecode itself*/
    message InputProver {PublicInputs public_inputs = 1;map<string, string> db = 4; // For debug/testing purpposes only. Don't fill this on productionmap<string, string> contracts_bytecode = 5; // For debug/testing purpposes only. Don't fill this on production
    }
    /** @dev PublicInputs* @param {old_state_root}* @param {old_acc_input_hash}* @param {old_batch_num}* @param {chain_id}* @param {batch_l2_data}* @param {global_exit_root}* @param {sequencer_addr}* @param {aggregator_addr}*/
    message PublicInputs {bytes old_state_root = 1;bytes old_acc_input_hash = 2;uint64 old_batch_num = 3;uint64 chain_id = 4;uint64 fork_id = 5;bytes batch_l2_data = 6; //输入a batch of EVM transactionsbytes global_exit_root = 7;uint64 eth_timestamp = 8;string sequencer_addr = 9;string aggregator_addr = 10;
    }/*** @dev GenBatchProofResponse* @param {id} - proof identifier, to be used in GetProofRequest()* @param {result} - request result*/
    message GenBatchProofResponse {string id = 1;Result result = 2;
    }
    /*** @dev Result*  - OK: succesfully completed*  - ERROR: request is not correct, i.e. input data is wrong*  - INTERNAL_ERROR: internal server error when delivering the response*/
    enum Result {RESULT_UNSPECIFIED = 0;RESULT_OK = 1;RESULT_ERROR = 2;RESULT_INTERNAL_ERROR = 3;
    }
    
  • 5)GenAggregatedProofRequest VS GenAggregatedProofResponse:Aggregator向Prover client发送生成aggregated proof请求。

    /*** @dev GenAggregatedProofRequest* @param {recursive_proof_1} - proof json of the first batch to aggregate* @param {recursive_proof_2} - proof json of the second batch to aggregate*/
    message GenAggregatedProofRequest {string recursive_proof_1 = 1;string recursive_proof_2 = 2;
    }
    /*** @dev GenAggregatedProofResponse* @param {id} - proof identifier, to be used in GetProofRequest()* @param {result} - request result*/
    message GenAggregatedProofResponse {string id = 1;Result result = 2;
    }
    /*** @dev Result*  - OK: succesfully completed*  - ERROR: request is not correct, i.e. input data is wrong*  - INTERNAL_ERROR: internal server error when delivering the response*/
    enum Result {RESULT_UNSPECIFIED = 0;RESULT_OK = 1;RESULT_ERROR = 2;RESULT_INTERNAL_ERROR = 3;
    }
    
  • 6)GenFinalProofRequest VS GenFinalProofResponse:Aggregator向Prover client发送生成final proof请求。

    /*** @dev GenFinalProofRequest* @param {recursive_proof} - proof json of the batch or aggregated proof to finalise* @param {aggregator_addr} - address of the aggregator*/
    message GenFinalProofRequest {string recursive_proof = 1;string aggregator_addr = 2;
    }
    /*** @dev Response GenFinalProof* @param {id} - proof identifier, to be used in GetProofRequest()* @param {result} - request result*/
    message GenFinalProofResponse {string id = 1;Result result = 2;
    }
    /*** @dev Result*  - OK: succesfully completed*  - ERROR: request is not correct, i.e. input data is wrong*  - INTERNAL_ERROR: internal server error when delivering the response*/
    enum Result {RESULT_UNSPECIFIED = 0;RESULT_OK = 1;RESULT_ERROR = 2;RESULT_INTERNAL_ERROR = 3;
    }
    

对应的Aggregator server端代码为:

// Channel implements the bi-directional communication channel between the
// Prover client and the Aggregator server.
func (a *Aggregator) Channel(stream pb.AggregatorService_ChannelServer) error {metrics.ConnectedProver()defer metrics.DisconnectedProver()ctx := stream.Context()var proverAddr net.Addrp, ok := peer.FromContext(ctx)if ok {proverAddr = p.Addr}prover, err := prover.New(stream, proverAddr, a.cfg.ProofStatePollingInterval)if err != nil {return err}log := log.WithFields("prover", prover.Name(),"proverId", prover.ID(),"proverAddr", prover.Addr(),)log.Info("Establishing stream connection with prover")// Check if prover supports the required Fork IDif !prover.SupportsForkID(a.cfg.ForkId) {err := errors.New("prover does not support required fork ID")log.Warn(FirstToUpper(err.Error()))return err}for {select {case <-a.ctx.Done():// server disconnectedreturn a.ctx.Err()case <-ctx.Done():// client disconnectedreturn ctx.Err()default:isIdle, err := prover.IsIdle() //判断GetStatusRequest返回的是否为GetStatusResponse_STATUS_IDLEif err != nil {log.Errorf("Failed to check if prover is idle: %v", err)time.Sleep(a.cfg.RetryTime.Duration)continue}if !isIdle {log.Debug("Prover is not idle")time.Sleep(a.cfg.RetryTime.Duration)continue}_, err = a.tryBuildFinalProof(ctx, prover, nil)if err != nil {log.Errorf("Error checking proofs to verify: %v", err)}proofGenerated, err := a.tryAggregateProofs(ctx, prover)if err != nil {log.Errorf("Error trying to aggregate proofs: %v", err)}if !proofGenerated {proofGenerated, err = a.tryGenerateBatchProof(ctx, prover)if err != nil {log.Errorf("Error trying to generate proof: %v", err)}}if !proofGenerated {// if no proof was generated (aggregated or batch) wait some time before retrytime.Sleep(a.cfg.RetryTime.Duration)} // if proof was generated we retry immediately as probably we have more proofs to process}}
}

Prover client端代码为:

void* aggregatorClientThread(void* arg)
{cout << "aggregatorClientThread() started" << endl;string uuid;AggregatorClient *pAggregatorClient = (AggregatorClient *)arg;while (true){::grpc::ClientContext context;std::unique_ptr<grpc::ClientReaderWriter<aggregator::v1::ProverMessage, aggregator::v1::AggregatorMessage>> readerWriter;readerWriter = pAggregatorClient->stub->Channel(&context);bool bResult;while (true){::aggregator::v1::AggregatorMessage aggregatorMessage;::aggregator::v1::ProverMessage proverMessage;// Read a new aggregator messagebResult = readerWriter->Read(&aggregatorMessage);if (!bResult){cerr << "Error: aggregatorClientThread() failed calling readerWriter->Read(&aggregatorMessage)" << endl;break;}switch (aggregatorMessage.request_case()){case aggregator::v1::AggregatorMessage::RequestCase::kGetProofRequest:break;case aggregator::v1::AggregatorMessage::RequestCase::kGetStatusRequest:case aggregator::v1::AggregatorMessage::RequestCase::kGenBatchProofRequest:case aggregator::v1::AggregatorMessage::RequestCase::kCancelRequest:cout << "aggregatorClientThread() got: " << aggregatorMessage.ShortDebugString() << endl;break;case aggregator::v1::AggregatorMessage::RequestCase::kGenAggregatedProofRequest:cout << "aggregatorClientThread() got genAggregatedProof() request" << endl;break;case aggregator::v1::AggregatorMessage::RequestCase::kGenFinalProofRequest:cout << "aggregatorClientThread() got genFinalProof() request" << endl;break;default:break;}// We return the same ID we got in the aggregator messageproverMessage.set_id(aggregatorMessage.id());string filePrefix = pAggregatorClient->config.outputPath + "/" + getTimestamp() + "_" + aggregatorMessage.id() + ".";if (pAggregatorClient->config.saveRequestToFile){string2file(aggregatorMessage.DebugString(), filePrefix + "aggregator_request.txt");}switch (aggregatorMessage.request_case()){case aggregator::v1::AggregatorMessage::RequestCase::kGetStatusRequest:{// Allocate a new get status responseaggregator::v1::GetStatusResponse * pGetStatusResponse = new aggregator::v1::GetStatusResponse();zkassert(pGetStatusResponse != NULL);// Call GetStatuspAggregatorClient->GetStatus(*pGetStatusResponse);// Set the get status responseproverMessage.set_allocated_get_status_response(pGetStatusResponse);break;}case aggregator::v1::AggregatorMessage::RequestCase::kGenBatchProofRequest:{// Allocate a new gen batch proof responseaggregator::v1::GenBatchProofResponse * pGenBatchProofResponse = new aggregator::v1::GenBatchProofResponse();zkassert(pGenBatchProofResponse != NULL);// Call GenBatchProofpAggregatorClient->GenBatchProof(aggregatorMessage.gen_batch_proof_request(), *pGenBatchProofResponse);// Set the gen batch proof responseproverMessage.set_allocated_gen_batch_proof_response(pGenBatchProofResponse);break;}case aggregator::v1::AggregatorMessage::RequestCase::kGenAggregatedProofRequest:{// Allocate a new gen aggregated proof responseaggregator::v1::GenAggregatedProofResponse * pGenAggregatedProofResponse = new aggregator::v1::GenAggregatedProofResponse();zkassert(pGenAggregatedProofResponse != NULL);// Call GenAggregatedProofpAggregatorClient->GenAggregatedProof(aggregatorMessage.gen_aggregated_proof_request(), *pGenAggregatedProofResponse);// Set the gen aggregated proof responseproverMessage.set_allocated_gen_aggregated_proof_response(pGenAggregatedProofResponse);break;}case aggregator::v1::AggregatorMessage::RequestCase::kGenFinalProofRequest:{// Allocate a new gen final proof responseaggregator::v1::GenFinalProofResponse * pGenFinalProofResponse = new aggregator::v1::GenFinalProofResponse();zkassert(pGenFinalProofResponse != NULL);// Call GenFinalProofpAggregatorClient->GenFinalProof(aggregatorMessage.gen_final_proof_request(), *pGenFinalProofResponse);// Set the gen final proof responseproverMessage.set_allocated_gen_final_proof_response(pGenFinalProofResponse);break;}case aggregator::v1::AggregatorMessage::RequestCase::kCancelRequest:{// Allocate a new cancel responseaggregator::v1::CancelResponse * pCancelResponse = new aggregator::v1::CancelResponse();zkassert(pCancelResponse != NULL);// Call CancelpAggregatorClient->Cancel(aggregatorMessage.cancel_request(), *pCancelResponse);// Set the cancel responseproverMessage.set_allocated_cancel_response(pCancelResponse);break;}case aggregator::v1::AggregatorMessage::RequestCase::kGetProofRequest:{// Allocate a new cancel responseaggregator::v1::GetProofResponse * pGetProofResponse = new aggregator::v1::GetProofResponse();zkassert(pGetProofResponse != NULL);// Call GetProofpAggregatorClient->GetProof(aggregatorMessage.get_proof_request(), *pGetProofResponse);// Set the get proof responseproverMessage.set_allocated_get_proof_response(pGetProofResponse);break;}default:{cerr << "Error: aggregatorClientThread() received an invalid type=" << aggregatorMessage.request_case() << endl;break;}}// Write the prover messagebResult = readerWriter->Write(proverMessage);if (!bResult){cerr << "Error: aggregatorClientThread() failed calling readerWriter->Write(proverMessage)" << endl;break;}switch (aggregatorMessage.request_case()){case aggregator::v1::AggregatorMessage::RequestCase::kGetStatusRequest:case aggregator::v1::AggregatorMessage::RequestCase::kGenBatchProofRequest:case aggregator::v1::AggregatorMessage::RequestCase::kGenAggregatedProofRequest:case aggregator::v1::AggregatorMessage::RequestCase::kGenFinalProofRequest:case aggregator::v1::AggregatorMessage::RequestCase::kCancelRequest:cout << "aggregatorClientThread() sent: " << proverMessage.ShortDebugString() << endl;break;case aggregator::v1::AggregatorMessage::RequestCase::kGetProofRequest:if (proverMessage.get_proof_response().result() != aggregator::v1::GetProofResponse_Result_RESULT_PENDING)cout << "aggregatorClientThread() getProof() response sent; result=" << proverMessage.get_proof_response().result_string() << endl;break;default:break;}if (pAggregatorClient->config.saveResponseToFile){string2file(proverMessage.DebugString(), filePrefix + "aggregator_response.txt");}}cout << "aggregatorClientThread() channel broken; will retry in 5 seconds" << endl;sleep(5);}return NULL;
}

2.1 生成batch proof

当Aggregator调用Prover请求生成batch proof时,Prover会:

  • 1)执行input data(a batch of EVM transactions)
  • 2)calculate the resulting state
  • 3)基于PIL polynomials definition和PIL polynomial constraints,为该calculation 生成proof。
    • Executor模块(即Executor RPC server)中结合了14个状态机来处理input data,以 生成 生成proof 所需的 committed polynomials的evaluations。每个状态机会生成自己的computation evidence data,并将更复杂的证明计算委托给下一状态机。
    • Prover模块(即Aggregator RPC client)会调用Stark模块,来为 Executor状态机的committed polynomials 生成proof。

2.2 生成aggregated proof

当Aggregator调用Prover请求生成aggregated proof时,Prover会:

  • 将Aggregator所提供的之前的2个calculated batch proofs或aggregated proofs合并,生成一个aggregated proof。

2.3 生成 final proof

当Aggregator调用Prover请求生成final proof时,Prover会:

  • 1)将Aggregator所提供的之前的一个calculated aggregated proof,生成一个可验证的final proof。

3. 作为Executor RPC server

作为Executor RPC server,其并不生成proof,(生成proof的工作由Aggregator RPC client模块完成),Executor会:

  • 执行input data(a batch of EVM transactions),并计算the resulting state。
  • 提供了一种快速的方式来检查:
    • 所提议的batch of transactions是否正确构建,且其工作量是否适合在单个batch内进行证明。
  • 当被Executor service调用时,Executor模块仅使用Main状态机。因此时不需要生成proof,也就不需要committed polynomials。

由其它节点服务(包括但不限于Aggregator)调用ProcessBatch函数,详细的接口规范见executor.proto

service ExecutorService {/// Processes a batchrpc ProcessBatch(ProcessBatchRequest) returns (ProcessBatchResponse) {}
}message ProcessBatchRequest {bytes old_state_root = 1;bytes old_acc_input_hash = 2;uint64 old_batch_num = 3;uint64 chain_id = 4;uint64 fork_id = 5;bytes batch_l2_data = 6;bytes global_exit_root = 7;uint64 eth_timestamp = 8;string coinbase = 9;uint32 update_merkle_tree = 10;// flag to indicate that counters should not be taken into accountuint64 no_counters = 11;// from is used for unsigned transactions with senderstring from = 12;// For testing purposes onlymap<string, string> db = 13;map<string, string> contracts_bytecode = 14; // For debug/testing purpposes only. Don't fill this on productionTraceConfig trace_config = 15;
}message ProcessBatchResponse {bytes new_state_root = 1;bytes new_acc_input_hash = 2;bytes new_local_exit_root = 3;uint64 new_batch_num = 4;uint32 cnt_keccak_hashes = 5;uint32 cnt_poseidon_hashes = 6;uint32 cnt_poseidon_paddings = 7;uint32 cnt_mem_aligns = 8;uint32 cnt_arithmetics = 9;uint32 cnt_binaries = 10;uint32 cnt_steps = 11;uint64 cumulative_gas_used = 12;repeated ProcessTransactionResponse responses = 13;ExecutorError error = 14;map<string, InfoReadWrite> read_write_addresses = 15;
}
message ProcessTransactionResponse {// Hash of the transactionbytes tx_hash = 1;// RLP encoded transaction// [nonce, gasPrice, gasLimit, to, value, data, v, r, s]bytes rlp_tx = 2;// Type indicates legacy transaction// It will be always 0 (legacy) in the executoruint32 type = 3;// Returned data from the runtime (function result or data supplied with revert opcode)bytes return_value = 4;// Total gas left as result of executionuint64 gas_left = 5;// Total gas used as result of execution or gas estimationuint64 gas_used = 6;// Total gas refunded as result of executionuint64 gas_refunded = 7;// Any error encountered during the executionRomError error = 8;// New SC Address in case of SC creationstring create_address = 9;// State Rootbytes state_root = 10;// Logs emited by LOG opcoderepeated Log logs = 11;// Tracerepeated ExecutionTraceStep execution_trace = 13;CallTrace call_trace = 14;
}

4. 作为StateDB RPC server

StateDB服务:

  • 提供了访问system state(为a Merkle tree)的接口,以及访问该state所存储database的接口
  • 供Executor和Prover模块使用,作为state的唯一源。可用于获取state details,如account balances。

详细的接口规范见statedb.proto

/*** Define all methods implementes by the gRPC* Get: get the value for a specific key* Set: set the value for a specific key* SetProgram: set the byte data for a specific key* GetProgram: get the byte data for a specific key* Flush: wait for all the pendings writes to the DB are done*/
service StateDBService {rpc Set(SetRequest) returns (SetResponse) {}rpc Get(GetRequest) returns (GetResponse) {}rpc SetProgram(SetProgramRequest) returns (SetProgramResponse) {}rpc GetProgram(GetProgramRequest) returns (GetProgramResponse) {}rpc LoadDB(LoadDBRequest) returns (google.protobuf.Empty) {}rpc LoadProgramDB(LoadProgramDBRequest) returns (google.protobuf.Empty) {}rpc Flush (google.protobuf.Empty) returns (FlushResponse) {}
}

其提供了6个RPC接口:

  • 1)rpc Set(SetRequest) returns (SetResponse) {}:

    /*** @dev SetRequest* @param {old_root} - merkle-tree root* @param {key} - key to set* @param {value} - scalar value to set (HEX string format)* @param {persistent} - indicates if it should be stored in the SQL database (true) or only in the memory cache (false)* @param {details} - indicates if it should return all response parameters (true) or just the new root (false)* @param {get_db_read_log} - indicates if it should return the DB reads generated during the execution of the request*/
    message SetRequest {Fea old_root = 1;Fea key = 2;string value = 3;bool persistent = 4;bool details = 5;bool get_db_read_log = 6;
    }
    /*** @dev SetResponse* @param {old_root} - merkle-tree root* @param {new_root} - merkle-tree new root* @param {key} - key to look for* @param {siblings} - array of siblings* @param {ins_key} - key found* @param {ins_value} - value found (HEX string format)* @param {is_old0} - is new insert or delete* @param {old_value} - old value (HEX string format)* @param {new_value} - new value (HEX string format)* @param {mode}* @param {proof_hash_counter}* @param {db_read_log} - list of db records read during the execution of the request* @param {result} - result code*/
    message SetResponse {Fea old_root = 1;Fea new_root = 2;Fea key = 3;map<uint64, SiblingList> siblings = 4;Fea ins_key = 5;string ins_value = 6;bool is_old0 = 7;string old_value = 8;string new_value = 9;string mode = 10;uint64 proof_hash_counter = 11;map<string, FeList> db_read_log = 12;ResultCode result = 13;
    }
    
  • 2)rpc Get(GetRequest) returns (GetResponse) {}:

    /*** @dev GetRequest* @param {root} - merkle-tree root* @param {key} - key to look for* @param {details} - indicates if it should return all response parameters (true) or just the new root (false)* @param {get_db_read_log} - indicates if it should return the DB reads generated during the execution of the request*/
    message GetRequest {Fea root = 1;Fea key = 2;bool details = 3;bool get_db_read_log = 4;
    }
    /*** @dev GetResponse* @param {root} - merkle-tree root* @param {key} - key to look for* @param {siblings} - array of siblings* @param {ins_key} - key found* @param {ins_value} - value found (HEX string format)* @param {is_old0} - is new insert or delete* @param {value} - value retrieved (HEX string format)* @param {proof_hash_counter}* @param {db_read_log} - list of db records read during the execution of the request* @param {result} - result code*/
    message GetResponse {Fea root = 1;Fea key = 2;map<uint64, SiblingList> siblings = 3;Fea ins_key = 4;string ins_value = 5;bool is_old0 = 6;string value = 7;uint64 proof_hash_counter = 8;map<string, FeList> db_read_log = 9;ResultCode result = 10;
    }
    
  • 3)rpc SetProgram(SetProgramRequest) returns (SetProgramResponse) {}:

    /*** @dev SetProgramRequest* @param {key} - key to set* @param {data} - Program data to store* @param {persistent} - indicates if it should be stored in the SQL database (true) or only in the memory cache (false)*/
    message SetProgramRequest {Fea key = 1;bytes data = 2;bool persistent = 3;
    }
    /*** @dev SetProgramResponse* @param {result} - result code*/
    message SetProgramResponse {ResultCode result = 1;
    }
    
  • 4)rpc GetProgram(GetProgramRequest) returns (GetProgramResponse) {}:

/*** @dev GetProgramRequest* @param {key} - key to get program data*/
message GetProgramRequest {Fea key = 1;
}
/*** @dev GetProgramResponse* @param {data} - program data retrieved* @param {result} - result code*/
message GetProgramResponse {bytes data = 1;ResultCode result = 2;
}
  • 5)rpc LoadDB(LoadDBRequest) returns (google.protobuf.Empty) {}:

    /*** @dev LoadDBRequest* @param {input_db} - list of db records (MT) to load in the database* @param {persistent} - indicates if it should be stored in the SQL database (true) or only in the memory cache (false)*/
    message LoadDBRequest {map<string, FeList> input_db = 1;bool persistent = 2;
    }
    
  • 6)rpc LoadProgramDB(LoadProgramDBRequest) returns (google.protobuf.Empty) {}:

    /*** @dev LoadProgramDBRequest* @param {input_program_db} - list of db records (program) to load in the database* @param {persistent} - indicates if it should be stored in the SQL database (true) or only in the memory cache (false)*/
    message LoadProgramDBRequest {map<string, bytes> input_program_db = 1;bool persistent = 2;
    }
    
  • 7)rpc Flush (google.protobuf.Empty) returns (FlushResponse) {}:

    /*** @dev FlushResponse* @param {result} - result code*/
    message FlushResponse {ResultCode result = 1;
    }
    

其中:


/*** @dev Array of 4 FE* @param {fe0} - Field Element value for pos 0* @param {fe1} - Field Element value for pos 1* @param {fe2} - Field Element value for pos 2* @param {fe3} - Field Element value for pos 3
*/
message Fea {uint64 fe0 = 1;uint64 fe1 = 2;uint64 fe2 = 3;uint64 fe3 = 4;
}/*** @dev FE (Field Element) List* @param {fe} - list of Fe
*/
message FeList {repeated uint64 fe = 1;
}/*** @dev Siblings List* @param {sibling} - list of siblings
*/
message SiblingList {repeated uint64 sibling = 1;
}/*** @dev Result code* @param {code} - result code
*/
message ResultCode {enum Code {CODE_UNSPECIFIED = 0;CODE_SUCCESS = 1;CODE_DB_KEY_NOT_FOUND = 2; // Requested key was not found in databaseCODE_DB_ERROR = 3; // Error connecting to database, or processing requestCODE_INTERNAL_ERROR = 4;CODE_SMT_INVALID_DATA_SIZE = 14; // Invalid size for the data of MT node}Code code = 1;
}

参考资料

[1] zkEVM Prover说明

附录:Polygon Hermez 2.0 zkEVM系列博客

  • ZK-Rollups工作原理
  • Polygon zkEVM——Hermez 2.0简介
  • Polygon zkEVM网络节点
  • Polygon zkEVM 基本概念
  • Polygon zkEVM Prover
  • Polygon zkEVM工具——PIL和CIRCOM
  • Polygon zkEVM节点代码解析
  • Polygon zkEVM的pil-stark Fibonacci状态机初体验
  • Polygon zkEVM的pil-stark Fibonacci状态机代码解析
  • Polygon zkEVM PIL编译器——pilcom 代码解析
  • Polygon zkEVM Arithmetic状态机
  • Polygon zkEVM中的常量多项式
  • Polygon zkEVM Binary状态机
  • Polygon zkEVM Memory状态机
  • Polygon zkEVM Memory Align状态机
  • Polygon zkEVM zkASM编译器——zkasmcom
  • Polygon zkEVM哈希状态机——Keccak-256和Poseidon
  • Polygon zkEVM zkASM语法
  • Polygon zkEVM可验证计算简单状态机示例
  • Polygon zkEVM zkASM 与 以太坊虚拟机opcode 对应集合
  • Polygon zkEVM zkROM代码解析(1)
  • Polygon zkEVM zkASM中的函数集合
  • Polygon zkEVM zkROM代码解析(2)
  • Polygon zkEVM zkROM代码解析(3)
  • Polygon zkEVM公式梳理
  • Polygon zkEVM中的Merkle tree
  • Polygon zkEVM中Goldilocks域元素circom约束
  • Polygon zkEVM Merkle tree的circom约束
  • Polygon zkEVM FFT和多项式evaluate计算的circom约束
  • Polygon zkEVM R1CS与Plonk电路转换
  • Polygon zkEVM中的子约束系统
  • Polygon zkEVM交易解析
  • Polygon zkEVM 审计及递归证明
  • Polygon zkEVM发布公开测试网2.0
  • Polygon zkEVM测试集——创建合约交易
  • Polygon zkEVM中的Recursive STARKs
  • Polygon zkEVM的gas定价
  • Polygon zkEVM zkProver基本设计原则 以及 Storage状态机
  • Polygon zkEVM bridge技术文档
  • Polygon zkEVM Trustless L2 State Management 技术文档
  • Polygon zkEVM中的自定义errors
  • Polygon zkEVM RPC服务

http://www.ppmy.cn/news/102628.html

相关文章

如何将数据从旧电脑传输到新电脑,哪种文件传输方式更好

迁移到新的Windows 10 电脑是一个令人兴奋的时刻&#xff0c;尤其是如果您有幸从我们现在可用的最佳Windows笔记本电脑列表中选择一个选项。问题是您熟悉的文件位于旧电脑上&#xff0c;并且您不想重新开始。为了简化电脑之间的转换&#xff0c;可以使用以下七种方式进行文件传…

䲟鱼优化算法(ROA)(含MATLAB代码)

先做一个声明&#xff1a;文章是由我的个人公众号中的推送直接复制粘贴而来&#xff0c;因此对智能优化算法感兴趣的朋友&#xff0c;可关注我的个人公众号&#xff1a;启发式算法讨论。我会不定期在公众号里分享不同的智能优化算法&#xff0c;经典的&#xff0c;或者是近几年…

CompletableFuture与多线程结合使用

公众号请关注"果酱桑", 一起学习,一起进步! 前言 在Java 8中&#xff0c;引入了CompletableFuture类&#xff0c;它是Future的增强版&#xff0c;提供了更加灵活的异步编程方式&#xff0c;能够更好地利用多线程的优势。本文将详细讲解CompletableFuture的使用方法…

【运维】speedtest测试

目录 docker 布署 布署云端 docker布署 云端放置于已有容器里 librespeed/speedtest: Self-hosted Speedtest for HTML5 and more. Easy setup, examples, configurable, mobile friendly. Supports PHP, Node, Multiple servers, and more (github.com) docker 布署 获取…

Hadoop3.1.4分布式搭建

Hadoop3.1.4分布式搭建 1. 基础环境准备 1.1 实验网络规划 hostnameip addrroleotherk8s-m13310.10.10.133NameNode, DataNode, NodeManageerk8s-m13410.10.10.134SecondaryNameNode, DataNode, NodeManageerk8s-m13510.10.10.135ResourceManager, DataNode, NodeManageerk8…

链表反转方法汇总

反转范围之前有节点&#xff0c;prev就指向该节点&#xff0c;没有就prevnull&#xff1b; 一、头插法 class Solution {public ListNode reverseList(ListNode head) {ListNode header new ListNode(-1);ListNode cur head;while(cur ! null) {ListNode tmp cur.next;cur.…

香豆素荧光标记652966-03-5,ATTO425 acid,ATTO 425 羧酸,进行简析说明

中文名称&#xff1a;ATTO 425 羧酸 英文名称&#xff1a;ATTO425 COOH&#xff0c;ATTO-425 carboxylic acid 规格标准&#xff1a;10mg&#xff0c;25mg&#xff0c;50mg CAS&#xff1a;652966-03-5 分子式&#xff1a;C22H27NO6 分子量&#xff1a;401.46结构式&#xff1a…

Git——三大分区【工作区 / 暂存区 / 版本区】

前言&#xff1a;Git作为一个版本管理工具&#xff0c;最核心组成思想是它的三个分区&#xff1a;工作区、暂存区和工作区。 1. 工作区 Git的工作区也就是我们平时编辑代码的目录文件夹。 2. 暂存区 暂存区就是一个暂时放置修改文件记录的地方。以往仓库中放货物为例&#xf…