diff --git a/src/main_sm/fork_1/main/full_tracer.hpp b/src/main_sm/fork_1/main/full_tracer.hpp index 7af0c4ddc..38cd56b1f 100644 --- a/src/main_sm/fork_1/main/full_tracer.hpp +++ b/src/main_sm/fork_1/main/full_tracer.hpp @@ -120,6 +120,13 @@ class FullTracer: public FullTracerInterface { return finalTrace.responses; } + vector emptyBlocks; + vector & get_block_responses(void) + { + zklog.error("FullTracer::get_block_responses() called in fork 1"); + exitProcess(); + return emptyBlocks; + } vector & get_info(void) { return full_trace; diff --git a/src/main_sm/fork_2/main/full_tracer.hpp b/src/main_sm/fork_2/main/full_tracer.hpp index 12fde837f..87135eb59 100644 --- a/src/main_sm/fork_2/main/full_tracer.hpp +++ b/src/main_sm/fork_2/main/full_tracer.hpp @@ -120,6 +120,13 @@ class FullTracer: public FullTracerInterface { return finalTrace.responses; } + vector emptyBlocks; + vector & get_block_responses(void) + { + zklog.error("FullTracer::get_block_responses() called in fork 2"); + exitProcess(); + return emptyBlocks; + } vector & get_info(void) { return full_trace; diff --git a/src/main_sm/fork_3/main/full_tracer.hpp b/src/main_sm/fork_3/main/full_tracer.hpp index aef1e3419..db3964a27 100644 --- a/src/main_sm/fork_3/main/full_tracer.hpp +++ b/src/main_sm/fork_3/main/full_tracer.hpp @@ -120,6 +120,13 @@ class FullTracer: public FullTracerInterface { return finalTrace.responses; } + vector emptyBlocks; + vector & get_block_responses(void) + { + zklog.error("FullTracer::get_block_responses() called in fork 3"); + exitProcess(); + return emptyBlocks; + } vector & get_info(void) { return full_trace; diff --git a/src/main_sm/fork_4/main/full_tracer.hpp b/src/main_sm/fork_4/main/full_tracer.hpp index d94f60a9f..dad50b4e6 100644 --- a/src/main_sm/fork_4/main/full_tracer.hpp +++ b/src/main_sm/fork_4/main/full_tracer.hpp @@ -120,6 +120,13 @@ class FullTracer: public FullTracerInterface { return finalTrace.responses; } + vector emptyBlocks; + vector & get_block_responses(void) + { + zklog.error("FullTracer::get_block_responses() called in fork 4"); + exitProcess(); + return emptyBlocks; + } vector & get_info(void) { return full_trace; diff --git a/src/main_sm/fork_5/main/full_tracer.hpp b/src/main_sm/fork_5/main/full_tracer.hpp index 8f39f0ce4..1538386b7 100644 --- a/src/main_sm/fork_5/main/full_tracer.hpp +++ b/src/main_sm/fork_5/main/full_tracer.hpp @@ -131,6 +131,13 @@ class FullTracer: public FullTracerInterface { return finalTrace.responses; } + vector emptyBlocks; + vector & get_block_responses(void) + { + zklog.error("FullTracer::get_block_responses() called in fork 5"); + exitProcess(); + return emptyBlocks; + } vector & get_info(void) { return full_trace; diff --git a/src/main_sm/fork_6/main/full_tracer.hpp b/src/main_sm/fork_6/main/full_tracer.hpp index ed2336039..b66dc43f1 100644 --- a/src/main_sm/fork_6/main/full_tracer.hpp +++ b/src/main_sm/fork_6/main/full_tracer.hpp @@ -131,6 +131,13 @@ class FullTracer: public FullTracerInterface { return finalTrace.responses; } + vector emptyBlocks; + vector & get_block_responses(void) + { + zklog.error("FullTracer::get_block_responses() called in fork 6"); + exitProcess(); + return emptyBlocks; + } vector & get_info(void) { return full_trace; diff --git a/src/main_sm/fork_7/main/full_tracer.cpp b/src/main_sm/fork_7/main/full_tracer.cpp index bd834a46e..21385349e 100644 --- a/src/main_sm/fork_7/main/full_tracer.cpp +++ b/src/main_sm/fork_7/main/full_tracer.cpp @@ -64,7 +64,10 @@ set responseErrors = { "intrinsic_invalid_balance", "intrinsic_invalid_batch_gas_limit", "intrinsic_invalid_sender_code", - "invalidRLP" }; + "invalid_change_l2_block", + "invalidRLP", + "invalidDecodeChangeL2Block", + "invalidNotFirstTxChangeL2Block" }; set oocErrors = { "OOCS", @@ -379,19 +382,19 @@ zkresult FullTracer::onError(Context &ctx, const RomCommand &cmd) if ( (responseErrors.find(lastError) != responseErrors.end()) || (full_trace.size() == 0) ) { - if (finalTrace.responses.size() > txCount) + if (currentBlock.responses.size() > txIndex) { - finalTrace.responses[txCount].error = lastError; + currentBlock.responses[txIndex].error = lastError; } - else if (finalTrace.responses.size() == txCount) + else if (currentBlock.responses.size() == txIndex) { - Response response; + ResponseV2 response; response.error = lastError; - finalTrace.responses.push_back(response); + currentBlock.responses.push_back(response); } else { - zklog.error("FullTracer::onError() got error=" + lastError + " with txCount=" + to_string(txCount) + " but finalTrace.responses.size()=" + to_string(finalTrace.responses.size())); + zklog.error("FullTracer::onError() got error=" + lastError + " with txIndex=" + to_string(txIndex) + " but currentBlock.responses.size()=" + to_string(currentBlock.responses.size())); exitProcess(); } } @@ -443,19 +446,19 @@ zkresult FullTracer::onError(ContextC &ctxc, const string &error) if ( (responseErrors.find(lastError) != responseErrors.end()) || (full_trace.size() == 0) ) { - if (finalTrace.responses.size() > txCount) + if (currentBlock.responses.size() > txIndex) { - finalTrace.responses[txCount].error = lastError; + currentBlock.responses[txIndex].error = lastError; } - else if (finalTrace.responses.size() == txCount) + else if (currentBlock.responses.size() == txIndex) { - Response response; + ResponseV2 response; response.error = lastError; - finalTrace.responses.push_back(response); + currentBlock.responses.push_back(response); } else { - zklog.error("FullTracer::onError() got error=" + lastError + " with txCount=" + to_string(txCount) + " but finalTrace.responses.size()=" + to_string(finalTrace.responses.size())); + zklog.error("FullTracer::onError() got error=" + lastError + " with txIndex=" + to_string(txIndex) + " but currentBlock.responses.size()=" + to_string(currentBlock.responses.size())); exitProcess(); } } @@ -514,23 +517,23 @@ zkresult FullTracer::onStoreLog (Context &ctx, const RomCommand &cmd) // Init logs[CTX][indexLog], if required uint64_t CTX = ctx.fr.toU64(ctx.pols.CTX[*ctx.pStep]); - map>::iterator itCTX; + map>::iterator itCTX; itCTX = logs.find(CTX); if (itCTX == logs.end()) { - map aux; - Log log; + map aux; + LogV2 log; aux[indexLog] = log; logs[CTX] = aux; itCTX = logs.find(CTX); zkassert(itCTX != logs.end()); } - map::iterator it; + map::iterator it; it = itCTX->second.find(indexLog); if (it == itCTX->second.end()) { - Log log; + LogV2 log; logs[CTX][indexLog] = log; it = itCTX->second.find(indexLog); zkassert(it != itCTX->second.end()); @@ -556,15 +559,16 @@ zkresult FullTracer::onStoreLog (Context &ctx, const RomCommand &cmd) return zkr; } it->second.address = NormalizeTo0xNFormat(auxScalar.get_str(16), 40); - zkr = getVarFromCtx(ctx, true, ctx.rom.newNumBatchOffset, auxScalar); + zkr = getVarFromCtx(ctx, true, ctx.rom.blockNumOffset, auxScalar); if (zkr != ZKR_SUCCESS) { - zklog.error("FullTracer::onStoreLog() failed calling getVarFromCtx(ctx.rom.newNumBatchOffset)"); + zklog.error("FullTracer::onStoreLog() failed calling getVarFromCtx(ctx.rom.blockNumOffset)"); return zkr; } - it->second.batch_number = auxScalar.get_ui(); - it->second.tx_hash = finalTrace.responses[txCount].tx_hash; - it->second.tx_index = txCount; + it->second.block_number = auxScalar.get_ui(); + it->second.tx_hash = currentBlock.responses[txIndex].tx_hash; + it->second.tx_hash_l2 = currentBlock.responses[txIndex].tx_hash_l2; + it->second.tx_index = txIndex; it->second.index = indexLog; #ifdef LOG_FULL_TRACER @@ -662,16 +666,187 @@ zkresult FullTracer::onStoreLog (ContextC &ctxc) return ZKR_SUCCESS; } + +// Triggered when a change L2 block transaction is detected +zkresult FullTracer::onStartBlock (Context &ctx) +{ + // If it's not the frist change L2 block transaction, we must finish previous block + if (!currentBlock.parent_hash.empty()) + { + onFinishBlock(ctx); + } + + // Get prvious block hash + mpz_class auxScalar; + zkresult zkr = getVarFromCtx(ctx, true, ctx.rom.previousBlockHashOffset, auxScalar); + if (zkr != ZKR_SUCCESS) + { + zklog.error("FullTracer::onStartBlock() failed calling getVarFromCtx(ctx.rom.sequencerAddrOffset)"); + return zkr; + } + currentBlock.parent_hash = NormalizeTo0xNFormat(auxScalar.get_str(16), 64); + + // Get sequencer address + zkr = getVarFromCtx(ctx, true, ctx.rom.sequencerAddrOffset, auxScalar); + if (zkr != ZKR_SUCCESS) + { + zklog.error("FullTracer::onStartBlock() failed calling getVarFromCtx(ctx.rom.sequencerAddrOffset)"); + return zkr; + } + currentBlock.coinbase = NormalizeTo0xNFormat(auxScalar.get_str(16), 40); + + // Get gas limit + currentBlock.gas_limit = ctx.rom.constants.BLOCK_GAS_LIMIT; + + // Clear transactions + currentBlock.responses.clear(); + + return ZKR_SUCCESS; +} + +/** + * Triggered when a block is finished (at begining of next block or after finishing processing last tx of the batch) + * @param {Object} ctx Current context object + */ +zkresult FullTracer::onFinishBlock (Context &ctx) +{ + mpz_class auxScalar; + zkresult zkr; + + // Get block number + zkr = getVarFromCtx(ctx, true, ctx.rom.blockNumOffset, auxScalar); + if (zkr != ZKR_SUCCESS) + { + zklog.error("FullTracer::onFinishBlock() failed calling getVarFromCtx(ctx.rom.blockNumOffset)"); + return zkr; + } + currentBlock.block_number = auxScalar.get_ui(); + + // Get timestamp + zkr = getVarFromCtx(ctx, true, ctx.rom.timestampOffset, auxScalar); + if (zkr != ZKR_SUCCESS) + { + zklog.error("FullTracer::onFinishBlock() failed calling getVarFromCtx(ctx.rom.timestampOffset)"); + return zkr; + } + currentBlock.timestamp = auxScalar.get_ui(); + + // Get global exit root + zkr = getVarFromCtx(ctx, true, ctx.rom.gerL1InfoTreeOffset, auxScalar); + if (zkr != ZKR_SUCCESS) + { + zklog.error("FullTracer::onFinishBlock() failed calling getVarFromCtx(ctx.rom.gerL1InfoTreeOffset)"); + return zkr; + } + currentBlock.ger = NormalizeTo0xNFormat(auxScalar.get_str(16), 64); + + // Get block hash L1 + zkr = getVarFromCtx(ctx, true, ctx.rom.blockchashL1InfoTreeOffset, auxScalar); + if (zkr != ZKR_SUCCESS) + { + zklog.error("FullTracer::onFinishBlock() failed calling getVarFromCtx(ctx.rom.blockchashL1InfoTreeOffset)"); + return zkr; + } + currentBlock.block_hash_l1 = NormalizeTo0xNFormat(auxScalar.get_str(16), 64); + + // Get gas used + zkr = getVarFromCtx(ctx, true, ctx.rom.cumulativeGasUsedOffset, auxScalar); + if (zkr != ZKR_SUCCESS) + { + zklog.error("FullTracer::onFinishBlock() failed calling getVarFromCtx(ctx.rom.cumulativeGasUsedOffset)"); + return zkr; + } + currentBlock.gas_used = auxScalar.get_ui(); + + // Get block info root + zkr = getVarFromCtx(ctx, true, ctx.rom.blockInfoSROffset, auxScalar); + if (zkr != ZKR_SUCCESS) + { + zklog.error("FullTracer::onFinishBlock() failed calling getVarFromCtx(ctx.rom.sequencerAddrOffset)"); + return zkr; + } + currentBlock.block_info_root = NormalizeTo0xNFormat(auxScalar.get_str(16), 64); + + // Get block hash + if (!fea2scalar(ctx.fr, auxScalar, ctx.pols.SR0[*ctx.pStep], ctx.pols.SR1[*ctx.pStep], ctx.pols.SR2[*ctx.pStep], ctx.pols.SR3[*ctx.pStep], ctx.pols.SR4[*ctx.pStep], ctx.pols.SR5[*ctx.pStep], ctx.pols.SR6[*ctx.pStep], ctx.pols.SR7[*ctx.pStep])) + { + zklog.error("FullTracer::onFinishBlock() failed calling fea2scalar()"); + return ZKR_SM_MAIN_FEA2SCALAR; + } + currentBlock.block_hash = NormalizeTo0xNFormat(auxScalar.get_str(16), 64); + + // Clear logs + currentBlock.logs.clear(); + + // Order all logs (from all CTX) in order of index + map auxLogs; + map>::iterator logIt; + map::const_iterator it; + for (logIt=logs.begin(); logIt!=logs.end(); logIt++) + { + for (it = logIt->second.begin(); it != logIt->second.end(); it++) + { + auxLogs[it->second.index] = it->second; + } + } + + // Append to response logs, overwriting log indexes to be sequential + uint64_t logIndex = 0; + map::iterator auxLogsIt; + for (auxLogsIt = auxLogs.begin(); auxLogsIt != auxLogs.end(); auxLogsIt++) + { + auxLogsIt->second.index = logIndex; + logIndex++; + auxLogsIt->second.block_hash = currentBlock.block_hash; + currentBlock.logs.push_back(auxLogsIt->second); + } + + // Set block hash to all txs of block + for (uint64_t tx=0; tx response.gas_left) @@ -1237,6 +1448,15 @@ zkresult FullTracer::onFinishTx(Context &ctx, const RomCommand &cmd) // Set gas left response.gas_left -= response.gas_used; + // Set gas refunded + zkr = getVarFromCtx(ctx, false, ctx.rom.cumulativeGasUsedOffset, auxScalar); + if (zkr != ZKR_SUCCESS) + { + zklog.error("FullTracer::onFinishTx() failed calling getVarFromCtx(ctx.rom.cumulativeGasUsedOffset)"); + return zkr; + } + response.cumulative_gas_used = auxScalar.get_ui(); + // Set new State Root if (!fea2scalar(ctx.fr, auxScalar, ctx.pols.SR0[*ctx.pStep], ctx.pols.SR1[*ctx.pStep], ctx.pols.SR2[*ctx.pStep], ctx.pols.SR3[*ctx.pStep], ctx.pols.SR4[*ctx.pStep], ctx.pols.SR5[*ctx.pStep], ctx.pols.SR6[*ctx.pStep], ctx.pols.SR7[*ctx.pStep])) { @@ -1251,9 +1471,6 @@ zkresult FullTracer::onFinishTx(Context &ctx, const RomCommand &cmd) { Opcode &lastOpcodeCall = full_trace.at(full_trace.size() - 1); - // set refunded gas - response.gas_refunded = lastOpcodeCall.gas_refund; - // Set gas price of last opcode if no error and is not a deploy and is not STOP (RETURN + REVERT) if ( (full_trace.size() > 1) && (lastOpcodeCall.op != 0x00 /*STOP opcode*/ ) && @@ -1274,9 +1491,9 @@ zkresult FullTracer::onFinishTx(Context &ctx, const RomCommand &cmd) (full_trace.size() > 0) ) { Opcode &lastOpcodeCall = full_trace.at(full_trace.size() - 1); - if (finalTrace.responses[finalTrace.responses.size() - 1].error == "") + if (currentBlock.responses[currentBlock.responses.size() - 1].error == "") { - finalTrace.responses[finalTrace.responses.size() - 1].error = lastOpcodeCall.error; + currentBlock.responses[currentBlock.responses.size() - 1].error = lastOpcodeCall.error; } } @@ -1284,17 +1501,17 @@ zkresult FullTracer::onFinishTx(Context &ctx, const RomCommand &cmd) (numberOfOpcodesInThisTx != 0) && (lastErrorOpcode != numberOfOpcodesInThisTx) ) { - finalTrace.responses[finalTrace.responses.size() - 1].error = ""; + currentBlock.responses[currentBlock.responses.size() - 1].error = ""; } // set flags has_gasprice_opcode and has_balance_opcode - finalTrace.responses[finalTrace.responses.size() - 1].has_gasprice_opcode = hasGaspriceOpcode; - finalTrace.responses[finalTrace.responses.size() - 1].has_balance_opcode = hasBalanceOpcode; + currentBlock.responses[currentBlock.responses.size() - 1].has_gasprice_opcode = hasGaspriceOpcode; + currentBlock.responses[currentBlock.responses.size() - 1].has_balance_opcode = hasBalanceOpcode; // Order all logs (from all CTX) in order of index - map auxLogs; - map>::iterator logIt; - map::const_iterator it; + map auxLogs; + map>::iterator logIt; + map::const_iterator it; for (logIt=logs.begin(); logIt!=logs.end(); logIt++) { for (it = logIt->second.begin(); it != logIt->second.end(); it++) @@ -1305,16 +1522,16 @@ zkresult FullTracer::onFinishTx(Context &ctx, const RomCommand &cmd) // Append to response logs, overwriting log indexes to be sequential uint64_t logIndex = 0; - map::iterator auxLogsIt; + map::iterator auxLogsIt; for (auxLogsIt = auxLogs.begin(); auxLogsIt != auxLogs.end(); auxLogsIt++) { auxLogsIt->second.index = logIndex; logIndex++; - finalTrace.responses[finalTrace.responses.size() - 1].logs.push_back(auxLogsIt->second); + currentBlock.responses[currentBlock.responses.size() - 1].logs.push_back(auxLogsIt->second); } - // Increase transaction count - txCount++; + // Increase transaction index + txIndex++; // Clean aux array for next iteration full_trace.clear(); @@ -1345,7 +1562,7 @@ zkresult FullTracer::onFinishTx (ContextC &ctxc) gettimeofday(&t, NULL); #endif //zkresult zkr; - Response &response = finalTrace.responses[txCount]; + ResponseV2 &response = currentBlock.responses[txIndex]; // Set from address response.full_trace.context.from = NormalizeTo0xNFormat(ctxc.batch.tx[ctxc.tx].fromPublicKey.get_str(16), 40); @@ -1435,9 +1652,9 @@ zkresult FullTracer::onFinishTx (ContextC &ctxc) (full_trace.size() > 0) ) { Opcode &lastOpcodeCall = full_trace.at(full_trace.size() - 1); - if (finalTrace.responses[finalTrace.responses.size() - 1].error == "") + if (currentBlock.responses[currentBlock.responses.size() - 1].error == "") { - finalTrace.responses[finalTrace.responses.size() - 1].error = lastOpcodeCall.error; + currentBlock.responses[currentBlock.responses.size() - 1].error = lastOpcodeCall.error; } } @@ -1445,13 +1662,13 @@ zkresult FullTracer::onFinishTx (ContextC &ctxc) (numberOfOpcodesInThisTx != 0) && (lastErrorOpcode != numberOfOpcodesInThisTx) ) { - finalTrace.responses[finalTrace.responses.size() - 1].error = ""; + currentBlock.responses[currentBlock.responses.size() - 1].error = ""; } // Order all logs (from all CTX) in order of index - map auxLogs; - map>::iterator logIt; - map::const_iterator it; + map auxLogs; + map>::iterator logIt; + map::const_iterator it; for (logIt=logs.begin(); logIt!=logs.end(); logIt++) { for (it = logIt->second.begin(); it != logIt->second.end(); it++) @@ -1462,16 +1679,16 @@ zkresult FullTracer::onFinishTx (ContextC &ctxc) // Append to response logs, overwriting log indexes to be sequential uint64_t logIndex = 0; - map::iterator auxLogsIt; + map::iterator auxLogsIt; for (auxLogsIt = auxLogs.begin(); auxLogsIt != auxLogs.end(); auxLogsIt++) { auxLogsIt->second.index = logIndex; logIndex++; - finalTrace.responses[finalTrace.responses.size() - 1].logs.push_back(auxLogsIt->second); + currentBlock.responses[currentBlock.responses.size() - 1].logs.push_back(auxLogsIt->second); } // Increase transaction count - txCount++; + txIndex++; // Clean aux array for next iteration logs.clear(); @@ -1507,7 +1724,17 @@ zkresult FullTracer::onStartBatch(Context &ctx, const RomCommand &cmd) return ZKR_SUCCESS; } - finalTrace.responses.clear(); + // Set is forced + mpz_class auxScalar; + zkresult zkr = getVarFromCtx(ctx, true, ctx.rom.isForcedOffset, auxScalar); + if (zkr != ZKR_SUCCESS) + { + zklog.error("FullTracer::onFinishTx() failed calling getVarFromCtx(ctx.rom.txDestAddrOffset)"); + return zkr; + } + isForced = auxScalar.get_ui(); + + finalTrace.block_responses.clear(); finalTrace.bInitialized = true; #ifdef LOG_FULL_TRACER @@ -1533,7 +1760,7 @@ zkresult FullTracer::onStartBatch (ContextC &ctxc) return ZKR_SUCCESS; } - finalTrace.responses.clear(); + finalTrace.block_responses.clear(); finalTrace.bInitialized = true; #ifdef LOG_FULL_TRACER @@ -1551,13 +1778,14 @@ zkresult FullTracer::onFinishBatch(Context &ctx, const RomCommand &cmd) #ifdef LOG_TIME_STATISTICS gettimeofday(&t, NULL); #endif + mpz_class auxScalar; zkresult zkr; - // Update used gas - finalTrace.cumulative_gas_used = accBatchGas; + onFinishBlock(ctx); + + finalTrace.gas_used = accBatchGas; // New state root - mpz_class auxScalar; if (!fea2scalar(ctx.fr, auxScalar, ctx.pols.SR0[*ctx.pStep], ctx.pols.SR1[*ctx.pStep], ctx.pols.SR2[*ctx.pStep], ctx.pols.SR3[*ctx.pStep], ctx.pols.SR4[*ctx.pStep], ctx.pols.SR5[*ctx.pStep], ctx.pols.SR6[*ctx.pStep], ctx.pols.SR7[*ctx.pStep])) { zklog.error("FullTracer::onFinishBatch() failed calling fea2scalar(SR)"); @@ -1574,16 +1802,6 @@ zkresult FullTracer::onFinishBatch(Context &ctx, const RomCommand &cmd) } finalTrace.new_acc_input_hash = NormalizeTo0xNFormat(auxScalar.get_str(16), 64); - // TODO: Can we simply use finalTrace.new_acc_input_hash when constructing the response? Can we avoid these fields in the .proto? - for (uint64_t r=0; r> deltaStorage; - FinalTrace finalTrace; + FinalTraceV2 finalTrace; unordered_map txGAS; - uint64_t txCount; uint64_t txTime; // in us vector> fullStack;// Stack of the transaction uint64_t accBatchGas; - map> logs; + map> logs; vector full_trace; string lastError; uint64_t numberOfOpcodesInThisTx; @@ -49,6 +48,9 @@ class FullTracer: public FullTracerInterface string previousMemory; bool hasGaspriceOpcode; bool hasBalanceOpcode; + uint64_t txIndex; + Block currentBlock; + bool isForced; #ifdef LOG_TIME_STATISTICS TimeMetricStorage tms; struct timeval t; @@ -60,6 +62,8 @@ class FullTracer: public FullTracerInterface zkresult onError (ContextC &ctxc, const string &error); zkresult onStoreLog (Context &ctx, const RomCommand &cmd); zkresult onStoreLog (ContextC &ctxc); + zkresult onStartBlock (Context &ctx); + zkresult onFinishBlock (Context &ctx); zkresult onProcessTx (Context &ctx, const RomCommand &cmd); zkresult onProcessTx (ContextC &ctxc); zkresult onUpdateStorage (Context &ctx, const RomCommand &cmd); @@ -76,7 +80,7 @@ class FullTracer: public FullTracerInterface const Goldilocks::Element &keyType0, const Goldilocks::Element &keyType1, const Goldilocks::Element &keyType2, const Goldilocks::Element &keyType3, const Goldilocks::Element &keyType4, const Goldilocks::Element &keyType5, const Goldilocks::Element &keyType6, const Goldilocks::Element &keyType7, const mpz_class &value ); - FullTracer(Goldilocks &fr) : fr(fr), depth(1), prevCTX(0), initGas(0), txCount(0), txTime(0), accBatchGas(0), numberOfOpcodesInThisTx(0), lastErrorOpcode(0), hasGaspriceOpcode(false), hasBalanceOpcode(false) { }; + FullTracer(Goldilocks &fr) : fr(fr), depth(1), prevCTX(0), initGas(0), txTime(0), accBatchGas(0), numberOfOpcodesInThisTx(0), lastErrorOpcode(0), hasGaspriceOpcode(false), hasBalanceOpcode(false), txIndex(0), isForced(false) { }; ~FullTracer() { #ifdef LOG_TIME_STATISTICS @@ -94,7 +98,7 @@ class FullTracer: public FullTracerInterface deltaStorage = other.deltaStorage; finalTrace = other.finalTrace; txGAS = other.txGAS; - txCount = other.txCount; + txIndex = other.txIndex; txTime = other.txTime; //info = other.info; fullStack = other.fullStack; @@ -103,6 +107,8 @@ class FullTracer: public FullTracerInterface full_trace = other.full_trace; lastError = other.lastError; callData = other.callData; + currentBlock = other.currentBlock; + isForced = other.isForced; return *this; } @@ -127,9 +133,16 @@ class FullTracer: public FullTracerInterface { return &read_write_addresses; } + vector emptyResponses; vector & get_responses(void) { - return finalTrace.responses; + zklog.error("FullTracer::get_responses() called in fork 7"); + exitProcess(); + return emptyResponses; + } + vector & get_block_responses(void) + { + return finalTrace.block_responses; } vector & get_info(void) { @@ -137,7 +150,7 @@ class FullTracer: public FullTracerInterface } uint64_t get_tx_number(void) { - return finalTrace.responses.size(); + return currentBlock.responses.size(); } }; diff --git a/src/main_sm/fork_7/main/rom.cpp b/src/main_sm/fork_7/main/rom.cpp index 553f2c7fa..12c1600f4 100644 --- a/src/main_sm/fork_7/main/rom.cpp +++ b/src/main_sm/fork_7/main/rom.cpp @@ -65,6 +65,18 @@ void Rom::load(Goldilocks &fr, json &romJson) effectivePercentageRLPOffset = getMemoryOffset("effectivePercentageRLP"); calldataCTXOffset = getMemoryOffset("calldataCTX"); calldataOffsetOffset = getMemoryOffset("calldataOffset"); + blockNumOffset = getMemoryOffset("blockNum"); + cumulativeGasUsedOffset = getMemoryOffset("cumulativeGasUsed"); + isForcedOffset = getMemoryOffset("isForced"); + sequencerAddrOffset = getMemoryOffset("sequencerAddr"); + blockInfoSROffset = getMemoryOffset("blockInfoSR"); + timestampOffset = getMemoryOffset("timestamp"); + gerL1InfoTreeOffset = getMemoryOffset("gerL1InfoTree"); + previousBlockHashOffset = getMemoryOffset("previousBlockHash"); + blockchashL1InfoTreeOffset = getMemoryOffset("blockchashL1InfoTree"); + isChangeL2BlockTxOffset = getMemoryOffset("isChangeL2BlockTx"); + txIndexOffset = getMemoryOffset("txIndex"); + l2TxHashOffset = getMemoryOffset("l2TxHash"); } // Load ROM integer constants @@ -146,6 +158,7 @@ void Rom::load(Goldilocks &fr, json &romJson) constants.MIN_CNT_KECCAK_BATCH = getConstant(romJson, "MIN_CNT_KECCAK_BATCH"); constants.CODE_SIZE_LIMIT = getConstant(romJson, "CODE_SIZE_LIMIT"); constants.BYTECODE_STARTS_EF = getConstant(romJson, "BYTECODE_STARTS_EF"); + constants.BLOCK_GAS_LIMIT = getConstant(romJson, "BLOCK_GAS_LIMIT"); // Load ROM scalar constants constants.ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2 = getConstantL(romJson, "ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2"); diff --git a/src/main_sm/fork_7/main/rom.hpp b/src/main_sm/fork_7/main/rom.hpp index c7ed92850..e8e99ae87 100644 --- a/src/main_sm/fork_7/main/rom.hpp +++ b/src/main_sm/fork_7/main/rom.hpp @@ -61,6 +61,18 @@ class Rom uint64_t effectivePercentageRLPOffset; uint64_t calldataCTXOffset; uint64_t calldataOffsetOffset; + uint64_t blockNumOffset; + uint64_t cumulativeGasUsedOffset; + uint64_t isForcedOffset; + uint64_t sequencerAddrOffset; + uint64_t blockInfoSROffset; + uint64_t timestampOffset; + uint64_t gerL1InfoTreeOffset; + uint64_t previousBlockHashOffset; + uint64_t blockchashL1InfoTreeOffset; + uint64_t isChangeL2BlockTxOffset; + uint64_t txIndexOffset; + uint64_t l2TxHashOffset; /* Constants */ RomConstants constants; @@ -103,7 +115,19 @@ class Rom gasCTXOffset(0), lastCtxUsedOffset(0), isCreateOffset(0), - effectivePercentageRLPOffset(0) + effectivePercentageRLPOffset(0), + blockNumOffset(0), + cumulativeGasUsedOffset(0), + isForcedOffset(0), + sequencerAddrOffset(0), + blockInfoSROffset(0), + timestampOffset(0), + gerL1InfoTreeOffset(0), + previousBlockHashOffset(0), + blockchashL1InfoTreeOffset(0), + isChangeL2BlockTxOffset(0), + txIndexOffset(0), + l2TxHashOffset(0) { }; /* Destructor */ diff --git a/src/main_sm/fork_7/main/rom_constants.hpp b/src/main_sm/fork_7/main/rom_constants.hpp index 84f8e4c55..69eb56cfe 100644 --- a/src/main_sm/fork_7/main/rom_constants.hpp +++ b/src/main_sm/fork_7/main/rom_constants.hpp @@ -89,6 +89,7 @@ class RomConstants uint64_t MIN_CNT_KECCAK_BATCH; uint64_t CODE_SIZE_LIMIT; uint64_t BYTECODE_STARTS_EF; + uint64_t BLOCK_GAS_LIMIT; /* Scalar constants */ mpz_class ADDRESS_GLOBAL_EXIT_ROOT_MANAGER_L2; diff --git a/src/prover/full_tracer_interface.hpp b/src/prover/full_tracer_interface.hpp index 9ffca3f58..80e7a1adb 100644 --- a/src/prover/full_tracer_interface.hpp +++ b/src/prover/full_tracer_interface.hpp @@ -60,6 +60,22 @@ class Log Log() : batch_number(0), tx_index(0), index(0) {}; }; +class LogV2 +{ +public: + string address; + uint64_t block_number; + string block_hash; + string tx_hash; + string tx_hash_l2; + uint64_t tx_index; + string batch_hash; + uint64_t index; + vector data; + vector topics; + LogV2() : block_number(0), tx_index(0), index(0) {}; +}; + class TxTraceContext { public: @@ -81,6 +97,28 @@ class TxTraceContext TxTraceContext() : gas(0), gas_used(0), execution_time(0) {}; }; +class TxTraceContextV2 +{ +public: + string type; + string from; + string to; + string data; + uint64_t gas; + uint64_t gas_used; + mpz_class value; + string batch; + string output; + mpz_class gas_price; + uint64_t chainId; // TODO: delete; only used by fork_0 + string old_state_root; + uint64_t execution_time; // In us + string error; + vector logs; + uint64_t txIndex; + TxTraceContextV2() : gas(0), gas_used(0), execution_time(0), txIndex(0) {}; +}; + class FullTrace { public: @@ -88,6 +126,13 @@ class FullTrace vector steps; }; +class FullTraceV2 +{ +public: + TxTraceContextV2 context; + vector steps; +}; + class Response { public: @@ -110,6 +155,32 @@ class Response Response() : type(0), gas_left(0), gas_used(0), gas_refunded(0), effective_percentage(0), has_gasprice_opcode(false), has_balance_opcode(false) {}; }; +class ResponseV2 +{ +public: + FullTraceV2 full_trace; + string tx_hash; + string tx_hash_l2; + string block_hash; + uint64_t block_number; + string rlp_tx; + uint64_t type; + string return_value; + uint64_t gas_left; + uint64_t gas_used; + uint64_t gas_refunded; + uint64_t cumulative_gas_used; + string error; + string create_address; + string state_root; + vector logs; + string effective_gas_price; + uint32_t effective_percentage; + bool has_gasprice_opcode; + bool has_balance_opcode; + ResponseV2() : block_number(0), type(0), gas_left(0), gas_used(0), gas_refunded(0), cumulative_gas_used(0), effective_percentage(0), has_gasprice_opcode(false), has_balance_opcode(false) {}; +}; + class FinalTrace { public: @@ -125,6 +196,41 @@ class FinalTrace FinalTrace() : bInitialized(false), numBatch(0), cumulative_gas_used(0) {}; }; +class Block +{ +public: + string parent_hash; + string coinbase; + uint64_t gas_limit; + uint64_t gas_used; + string block_hash; + uint64_t block_number; + string receipts_root; + uint64_t timestamp; + string ger; + string block_info_root; + string block_hash_l1; + vector responses; + vector logs; + Block() : gas_limit(0), block_number(0), timestamp(0) {}; +}; + +class FinalTraceV2 +{ +public: + bool bInitialized; + string new_state_root; + string new_local_exit_root; + string newAccInputHash; + string new_acc_input_hash; + uint64_t numBatch; + uint64_t cumulative_gas_used; + uint64_t gas_used; + vector block_responses; + string error; + FinalTraceV2() : bInitialized(false), numBatch(0), cumulative_gas_used(0), gas_used(0) {}; +}; + class InfoReadWrite { public: @@ -159,6 +265,7 @@ class FullTracerInterface virtual string & get_new_local_exit_root(void) = 0; virtual unordered_map * get_read_write_addresses(void) = 0; virtual vector & get_responses(void) = 0; + virtual vector & get_block_responses(void) = 0; virtual vector & get_info(void) = 0; virtual uint64_t get_tx_number(void) = 0; // tx number = 0, 1, 2... }; diff --git a/src/service/executor/executor_service.cpp b/src/service/executor/executor_service.cpp index 486bb6b48..11a4f5e41 100644 --- a/src/service/executor/executor_service.cpp +++ b/src/service/executor/executor_service.cpp @@ -367,6 +367,7 @@ ::grpc::Status ExecutorServiceImpl::ProcessBatch(::grpc::ServerContext* context, response->set_flush_id(proverRequest.flushId); response->set_stored_flush_id(proverRequest.lastSentFlushId); response->set_prover_id(config.proverID); + response->set_fork_id(proverRequest.input.publicInputsExtended.publicInputs.forkID); unordered_map * p_read_write_addresses = proverRequest.pFullTracer->get_read_write_addresses(); if (p_read_write_addresses != NULL) @@ -1039,6 +1040,7 @@ ::grpc::Status ExecutorServiceImpl::ProcessBatchV2 (::grpc::ServerContext* conte response->set_flush_id(proverRequest.flushId); response->set_stored_flush_id(proverRequest.lastSentFlushId); response->set_prover_id(config.proverID); + response->set_fork_id(proverRequest.input.publicInputsExtended.publicInputs.forkID); unordered_map * p_read_write_addresses = proverRequest.pFullTracer->get_read_write_addresses(); if (p_read_write_addresses != NULL) @@ -1054,100 +1056,119 @@ ::grpc::Status ExecutorServiceImpl::ProcessBatchV2 (::grpc::ServerContext* conte } } - vector &responses = proverRequest.pFullTracer->get_responses(); - for (uint64_t tx=0; tx &block_responses = proverRequest.pFullTracer->get_block_responses(); + uint64_t nTxs = 0; + for (uint64_t block=0; blockadd_block_responses(); - executor::v1::ProcessTransactionResponseV2 * pProcessTransactionResponse = pProcessBlockResponse->add_responses(); - - //executor::v1::ProcessTransactionResponse * pProcessTransactionResponse = response->add_responses(); - pProcessTransactionResponse->set_tx_hash(string2ba(responses[tx].tx_hash)); - pProcessTransactionResponse->set_rlp_tx(responses[tx].rlp_tx); - pProcessTransactionResponse->set_type(responses[tx].type); // Type indicates legacy transaction; it will be always 0 (legacy) in the executor - pProcessTransactionResponse->set_return_value(string2ba(responses[tx].return_value)); // Returned data from the runtime (function result or data supplied with revert opcode) - pProcessTransactionResponse->set_gas_left(responses[tx].gas_left); // Total gas left as result of execution - pProcessTransactionResponse->set_gas_used(responses[tx].gas_used); // Total gas used as result of execution or gas estimation - pProcessTransactionResponse->set_gas_refunded(responses[tx].gas_refunded); // Total gas refunded as result of execution - pProcessTransactionResponse->set_error(string2error(responses[tx].error)); // Any error encountered during the execution - pProcessTransactionResponse->set_create_address(responses[tx].create_address); // New SC Address in case of SC creation - pProcessTransactionResponse->set_state_root(string2ba(responses[tx].state_root)); - pProcessTransactionResponse->set_effective_percentage(responses[tx].effective_percentage); - pProcessTransactionResponse->set_effective_gas_price(responses[tx].effective_gas_price); - pProcessTransactionResponse->set_has_balance_opcode(responses[tx].has_balance_opcode); - pProcessTransactionResponse->set_has_gasprice_opcode(responses[tx].has_gasprice_opcode); - for (uint64_t log=0; logset_block_hash(string2ba(block_responses[block].block_hash)); + pProcessBlockResponse->set_block_hash_l1(string2ba(block_responses[block].block_hash_l1)); + pProcessBlockResponse->set_block_info_root(string2ba(block_responses[block].block_info_root)); + pProcessBlockResponse->set_block_number(block_responses[block].block_number); + pProcessBlockResponse->set_coinbase(block_responses[block].coinbase); + pProcessBlockResponse->set_gas_limit(block_responses[block].gas_limit); + pProcessBlockResponse->set_gas_used(block_responses[block].gas_used); + pProcessBlockResponse->set_ger(string2ba(block_responses[block].ger)); + pProcessBlockResponse->set_parent_hash(string2ba(block_responses[block].parent_hash)); + pProcessBlockResponse->set_timestamp(block_responses[block].timestamp); + + vector &responses = block_responses[block].responses; + nTxs += responses.size(); + + for (uint64_t tx=0; txadd_logs(); - pLog->set_address(responses[tx].logs[log].address); // Address of the contract that generated the event - for (uint64_t topic=0; topicadd_responses(); + + //executor::v1::ProcessTransactionResponse * pProcessTransactionResponse = response->add_responses(); + pProcessTransactionResponse->set_tx_hash(string2ba(responses[tx].tx_hash)); + pProcessTransactionResponse->set_rlp_tx(responses[tx].rlp_tx); + pProcessTransactionResponse->set_type(responses[tx].type); // Type indicates legacy transaction; it will be always 0 (legacy) in the executor + pProcessTransactionResponse->set_return_value(string2ba(responses[tx].return_value)); // Returned data from the runtime (function result or data supplied with revert opcode) + pProcessTransactionResponse->set_gas_left(responses[tx].gas_left); // Total gas left as result of execution + pProcessTransactionResponse->set_gas_used(responses[tx].gas_used); // Total gas used as result of execution or gas estimation + pProcessTransactionResponse->set_gas_refunded(responses[tx].gas_refunded); // Total gas refunded as result of execution + pProcessTransactionResponse->set_error(string2error(responses[tx].error)); // Any error encountered during the execution + pProcessTransactionResponse->set_create_address(responses[tx].create_address); // New SC Address in case of SC creation + pProcessTransactionResponse->set_state_root(string2ba(responses[tx].state_root)); + pProcessTransactionResponse->set_effective_percentage(responses[tx].effective_percentage); + pProcessTransactionResponse->set_effective_gas_price(responses[tx].effective_gas_price); + pProcessTransactionResponse->set_has_balance_opcode(responses[tx].has_balance_opcode); + pProcessTransactionResponse->set_has_gasprice_opcode(responses[tx].has_gasprice_opcode); + for (uint64_t log=0; logadd_topics(); - *pTopic = string2ba(responses[tx].logs[log].topics[topic]); // List of topics provided by the contract + executor::v1::LogV2 * pLog = pProcessTransactionResponse->add_logs(); + pLog->set_address(responses[tx].logs[log].address); // Address of the contract that generated the event + for (uint64_t topic=0; topicadd_topics(); + *pTopic = string2ba(responses[tx].logs[log].topics[topic]); // List of topics provided by the contract + } + string dataConcatenated; + for (uint64_t data=0; dataset_data(string2ba(dataConcatenated)); // Supplied by the contract, usually ABI-encoded + //pLog->set_batch_number(responses[tx].logs[log].batch_number); // Batch in which the transaction was included + pLog->set_tx_hash(string2ba(responses[tx].logs[log].tx_hash)); // Hash of the transaction + pLog->set_tx_index(responses[tx].logs[log].tx_index); // Index of the transaction in the block + //pLog->set_batch_hash(string2ba(responses[tx].logs[log].batch_hash)); // Hash of the batch in which the transaction was included + pLog->set_index(responses[tx].logs[log].index); // Index of the log in the block } - string dataConcatenated; - for (uint64_t data=0; dataset_data(string2ba(dataConcatenated)); // Supplied by the contract, usually ABI-encoded - //pLog->set_batch_number(responses[tx].logs[log].batch_number); // Batch in which the transaction was included - pLog->set_tx_hash(string2ba(responses[tx].logs[log].tx_hash)); // Hash of the transaction - pLog->set_tx_index(responses[tx].logs[log].tx_index); // Index of the transaction in the block - //pLog->set_batch_hash(string2ba(responses[tx].logs[log].batch_hash)); // Hash of the batch in which the transaction was included - pLog->set_index(responses[tx].logs[log].index); // Index of the log in the block - } - if (proverRequest.input.traceConfig.bEnabled && (proverRequest.input.traceConfig.txHashToGenerateFullTrace == responses[tx].tx_hash)) - { - executor::v1::FullTraceV2 * pFullTrace = new executor::v1::FullTraceV2(); - executor::v1::TransactionContextV2 * pTransactionContext = pFullTrace->mutable_context(); - pTransactionContext->set_type(responses[tx].full_trace.context.type); // "CALL" or "CREATE" - pTransactionContext->set_from(responses[tx].full_trace.context.from); // Sender of the transaction - pTransactionContext->set_to(responses[tx].full_trace.context.to); // Target of the transaction - pTransactionContext->set_data(string2ba(responses[tx].full_trace.context.data)); // Input data of the transaction - pTransactionContext->set_gas(responses[tx].full_trace.context.gas); - pTransactionContext->set_gas_price(Add0xIfMissing(responses[tx].full_trace.context.gas_price.get_str(16))); - pTransactionContext->set_value(Add0xIfMissing(responses[tx].full_trace.context.value.get_str(16))); - //pTransactionContext->set_batch(string2ba(responses[tx].full_trace.context.batch)); // Hash of the batch in which the transaction was included - pTransactionContext->set_output(string2ba(responses[tx].full_trace.context.output)); // Returned data from the runtime (function result or data supplied with revert opcode) - pTransactionContext->set_gas_used(responses[tx].full_trace.context.gas_used); // Total gas used as result of execution - pTransactionContext->set_execution_time(responses[tx].full_trace.context.execution_time); - pTransactionContext->set_old_state_root(string2ba(responses[tx].full_trace.context.old_state_root)); // Starting state root - for (uint64_t step=0; stepadd_steps(); - pTransactionStep->set_state_root(string2ba(responses[tx].full_trace.steps[step].state_root)); - pTransactionStep->set_depth(responses[tx].full_trace.steps[step].depth); // Call depth - pTransactionStep->set_pc(responses[tx].full_trace.steps[step].pc); // Program counter - pTransactionStep->set_gas(responses[tx].full_trace.steps[step].gas); // Remaining gas - pTransactionStep->set_gas_cost(responses[tx].full_trace.steps[step].gas_cost); // Gas cost of the operation - pTransactionStep->set_gas_refund(responses[tx].full_trace.steps[step].gas_refund); // Gas refunded during the operation - pTransactionStep->set_op(responses[tx].full_trace.steps[step].op); // Opcode - for (uint64_t stack=0; stackadd_stack(responses[tx].full_trace.steps[step].stack[stack].get_str(16)); // Content of the stack - pTransactionStep->set_memory_size(responses[tx].full_trace.steps[step].memory_size); - pTransactionStep->set_memory_offset(responses[tx].full_trace.steps[step].memory_offset); - pTransactionStep->set_memory(responses[tx].full_trace.steps[step].memory); - string dataConcatenated; - for (uint64_t data=0; dataset_return_data(string2ba(dataConcatenated)); - executor::v1::ContractV2 * pContract = pTransactionStep->mutable_contract(); // Contract information - pContract->set_address(responses[tx].full_trace.steps[step].contract.address); - pContract->set_caller(responses[tx].full_trace.steps[step].contract.caller); - pContract->set_value(Add0xIfMissing(responses[tx].full_trace.steps[step].contract.value.get_str(16))); - pContract->set_data(string2ba(responses[tx].full_trace.steps[step].contract.data)); - pContract->set_gas(responses[tx].full_trace.steps[step].contract.gas); - pContract->set_type(responses[tx].full_trace.steps[step].contract.type); - pTransactionStep->set_error(string2error(responses[tx].full_trace.steps[step].error)); - - google::protobuf::Map * pStorage = pTransactionStep->mutable_storage(); - unordered_map::iterator it; - for (it=responses[tx].full_trace.steps[step].storage.begin(); it!=responses[tx].full_trace.steps[step].storage.end(); it++) - (*pStorage)[it->first] = it->second; // Content of the storage + executor::v1::FullTraceV2 * pFullTrace = new executor::v1::FullTraceV2(); + executor::v1::TransactionContextV2 * pTransactionContext = pFullTrace->mutable_context(); + pTransactionContext->set_type(responses[tx].full_trace.context.type); // "CALL" or "CREATE" + pTransactionContext->set_from(responses[tx].full_trace.context.from); // Sender of the transaction + pTransactionContext->set_to(responses[tx].full_trace.context.to); // Target of the transaction + pTransactionContext->set_data(string2ba(responses[tx].full_trace.context.data)); // Input data of the transaction + pTransactionContext->set_gas(responses[tx].full_trace.context.gas); + pTransactionContext->set_gas_price(Add0xIfMissing(responses[tx].full_trace.context.gas_price.get_str(16))); + pTransactionContext->set_value(Add0xIfMissing(responses[tx].full_trace.context.value.get_str(16))); + //pTransactionContext->set_batch(string2ba(responses[tx].full_trace.context.batch)); // Hash of the batch in which the transaction was included + pTransactionContext->set_output(string2ba(responses[tx].full_trace.context.output)); // Returned data from the runtime (function result or data supplied with revert opcode) + pTransactionContext->set_gas_used(responses[tx].full_trace.context.gas_used); // Total gas used as result of execution + pTransactionContext->set_execution_time(responses[tx].full_trace.context.execution_time); + pTransactionContext->set_old_state_root(string2ba(responses[tx].full_trace.context.old_state_root)); // Starting state root + for (uint64_t step=0; stepadd_steps(); + pTransactionStep->set_state_root(string2ba(responses[tx].full_trace.steps[step].state_root)); + pTransactionStep->set_depth(responses[tx].full_trace.steps[step].depth); // Call depth + pTransactionStep->set_pc(responses[tx].full_trace.steps[step].pc); // Program counter + pTransactionStep->set_gas(responses[tx].full_trace.steps[step].gas); // Remaining gas + pTransactionStep->set_gas_cost(responses[tx].full_trace.steps[step].gas_cost); // Gas cost of the operation + pTransactionStep->set_gas_refund(responses[tx].full_trace.steps[step].gas_refund); // Gas refunded during the operation + pTransactionStep->set_op(responses[tx].full_trace.steps[step].op); // Opcode + for (uint64_t stack=0; stackadd_stack(responses[tx].full_trace.steps[step].stack[stack].get_str(16)); // Content of the stack + pTransactionStep->set_memory_size(responses[tx].full_trace.steps[step].memory_size); + pTransactionStep->set_memory_offset(responses[tx].full_trace.steps[step].memory_offset); + pTransactionStep->set_memory(responses[tx].full_trace.steps[step].memory); + string dataConcatenated; + for (uint64_t data=0; dataset_return_data(string2ba(dataConcatenated)); + executor::v1::ContractV2 * pContract = pTransactionStep->mutable_contract(); // Contract information + pContract->set_address(responses[tx].full_trace.steps[step].contract.address); + pContract->set_caller(responses[tx].full_trace.steps[step].contract.caller); + pContract->set_value(Add0xIfMissing(responses[tx].full_trace.steps[step].contract.value.get_str(16))); + pContract->set_data(string2ba(responses[tx].full_trace.steps[step].contract.data)); + pContract->set_gas(responses[tx].full_trace.steps[step].contract.gas); + pContract->set_type(responses[tx].full_trace.steps[step].contract.type); + pTransactionStep->set_error(string2error(responses[tx].full_trace.steps[step].error)); + + google::protobuf::Map * pStorage = pTransactionStep->mutable_storage(); + unordered_map::iterator it; + for (it=responses[tx].full_trace.steps[step].storage.begin(); it!=responses[tx].full_trace.steps[step].storage.end(); it++) + (*pStorage)[it->first] = it->second; // Content of the storage + } + pProcessTransactionResponse->set_allocated_full_trace(pFullTrace); } - pProcessTransactionResponse->set_allocated_full_trace(pFullTrace); } } @@ -1183,18 +1204,24 @@ ::grpc::Status ExecutorServiceImpl::ProcessBatchV2 (::grpc::ServerContext* conte " counters.binary=" + to_string(proverRequest.counters.binary) + " flush_id=" + to_string(proverRequest.flushId) + " last_sent_flush_id=" + to_string(proverRequest.lastSentFlushId) + - " nTxs=" + to_string(responses.size()); + " nBlocks=" + to_string(block_responses.size()) + + " nTxs=" + to_string(nTxs); if (config.logExecutorServerTxs) { - for (uint64_t tx=0; tx