From 965545b002e9943f07ffe49da7fe97766412c2f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= Date: Tue, 13 Feb 2024 13:34:14 +0100 Subject: [PATCH 1/9] check unsupported precompiles --- docker-compose.yml | 2 +- event/event.go | 3 + proto/src/proto/executor/v1/executor.proto | 10 ++ sequencer/finalizer.go | 27 +++- state/pgstatestorage/datastream.go | 2 +- state/runtime/executor/errors.go | 20 +++ state/runtime/executor/executor.pb.go | 81 ++++++++---- state/runtime/runtime.go | 10 ++ state/test/forkid_etrog/etrog_test.go | 139 +++++++++++++++++++++ test/contracts/auto/customModExp.sol | 24 ++++ test/contracts/index.yaml | 2 +- test/docker-compose.yml | 4 +- 12 files changed, 293 insertions(+), 31 deletions(-) create mode 100644 test/contracts/auto/customModExp.sol diff --git a/docker-compose.yml b/docker-compose.yml index 57ddfb19bd..536f89b5fb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -107,7 +107,7 @@ services: zkevm-prover: container_name: zkevm-prover restart: unless-stopped - image: hermeznetwork/zkevm-prover:v4.0.4 + image: hermeznetwork/zkevm-prover:v4.0.10 depends_on: zkevm-state-db: condition: service_healthy diff --git a/event/event.go b/event/event.go index 21dbe7799c..9cff00de4e 100644 --- a/event/event.go +++ b/event/event.go @@ -42,6 +42,9 @@ const ( EventID_SynchronizerHalt EventID = "SYNCHRONIZER HALT" // EventID_SequenceSenderHalt is triggered when the SequenceSender halts EventID_SequenceSenderHalt EventID = "SEQUENCESENDER HALT" + // EventID_UnsupportedPrecompile is triggered when the executor returns an unsupported precompile error + EventID_UnsupportedPrecompile EventID = "UNSUPPORTED PRECOMPILE" + // Source_Node is the source of the event Source_Node Source = "node" diff --git a/proto/src/proto/executor/v1/executor.proto b/proto/src/proto/executor/v1/executor.proto index ff92f6776e..cef5cf5321 100644 --- a/proto/src/proto/executor/v1/executor.proto +++ b/proto/src/proto/executor/v1/executor.proto @@ -854,4 +854,14 @@ enum ExecutorError { EXECUTOR_ERROR_INVALID_L1_INFO_TREE_INDEX = 111; // EXECUTOR_ERROR_INVALID_L1_INFO_TREE_SMT_PROOF_VALUE indicates that the ROM asked for an L1InfoTree SMT proof that was not present in the input EXECUTOR_ERROR_INVALID_L1_INFO_TREE_SMT_PROOF_VALUE = 112; + // EXECUTOR_ERROR_INVALID_WITNESS indicates that the provided witness data is invalid + EXECUTOR_ERROR_INVALID_WITNESS = 113; + // EXECUTOR_ERROR_INVALID_CBOR indicates that the provided CBOR data is invalid + EXECUTOR_ERROR_INVALID_CBOR = 114; + // EXECUTOR_ERROR_INVALID_DATA_STREAM indicates that the provided data stream data is invalid + EXECUTOR_ERROR_INVALID_DATA_STREAM = 115; + // EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE indicates that the provided update merkle tree is invalid, e.g. because the executor is configured not to write to database + EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE = 116; + // EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED indicates that an unsupported precompiled has been used + EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED = 117; } diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index 11521c0d0b..507ccbc2fb 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -2,6 +2,7 @@ package sequencer import ( "context" + "encoding/json" "errors" "fmt" "math/big" @@ -441,13 +442,35 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first } else if err == nil && !batchResponse.IsRomLevelError && len(batchResponse.BlockResponses) == 0 { err = fmt.Errorf("executor returned no errors and no responses for tx %s", tx.HashStr) f.Halt(ctx, err, false) - } else if batchResponse.IsExecutorLevelError { + } else if err != nil { log.Errorf("error received from executor, error: %v", err) + + if errors.Is(err, runtime.ErrExecutorErrorUnsupportedPrecompile) { + payload, err := json.Marshal(batchRequest) + if err != nil { + log.Errorf("error marshaling payload, error: %v", err) + } else { + event := &event.Event{ + ReceivedAt: time.Now(), + Source: event.Source_Node, + Component: event.Component_Sequencer, + Level: event.Level_Warning, + EventID: event.EventID_UnsupportedPrecompile, + Description: string(payload), + Json: batchRequest, + } + err = f.eventLog.LogEvent(ctx, event) + if err != nil { + log.Errorf("error storing payload, error: %v", err) + } + } + } + // Delete tx from the worker f.workerIntf.DeleteTx(tx.Hash, tx.From) // Set tx as invalid in the pool - errMsg := batchResponse.ExecutorError.Error() + errMsg := err.Error() err = f.poolIntf.UpdateTxStatus(ctx, tx.Hash, pool.TxStatusInvalid, false, &errMsg) if err != nil { log.Errorf("failed to update status to invalid in the pool for tx %s, error: %v", tx.Hash.String(), err) diff --git a/state/pgstatestorage/datastream.go b/state/pgstatestorage/datastream.go index 800f2b0f66..00d136a278 100644 --- a/state/pgstatestorage/datastream.go +++ b/state/pgstatestorage/datastream.go @@ -29,7 +29,7 @@ func (p *PostgresStorage) GetDSGenesisBlock(ctx context.Context, dbTx pgx.Tx) (* // GetDSL2Blocks returns the L2 blocks func (p *PostgresStorage) GetDSL2Blocks(ctx context.Context, firstBatchNumber, lastBatchNumber uint64, dbTx pgx.Tx) ([]*state.DSL2Block, error) { - const l2BlockSQL = `SELECT l2b.batch_num, l2b.block_num, l2b.received_at, b.global_exit_root, l2b.header->>'globalExitRoot' AS block_global_exit_root, l2b.header->>'miner' AS coinbase, f.fork_id, l2b.block_hash, l2b.state_root + const l2BlockSQL = `SELECT l2b.batch_num, l2b.block_num, l2b.received_at, b.global_exit_root, COALESCE(l2b.header->>'globalExitRoot', '') AS block_global_exit_root, l2b.header->>'miner' AS coinbase, f.fork_id, l2b.block_hash, l2b.state_root FROM state.l2block l2b, state.batch b, state.fork_id f WHERE l2b.batch_num BETWEEN $1 AND $2 AND l2b.batch_num = b.batch_num AND l2b.batch_num between f.from_batch_num AND f.to_batch_num ORDER BY l2b.block_num ASC` diff --git a/state/runtime/executor/errors.go b/state/runtime/executor/errors.go index da9a2630d5..e2cbbab59f 100644 --- a/state/runtime/executor/errors.go +++ b/state/runtime/executor/errors.go @@ -446,6 +446,16 @@ func ExecutorErr(errorCode ExecutorError) error { return runtime.ErrExecutorErrorInvalidL1InfoTreeIndex case ExecutorError_EXECUTOR_ERROR_INVALID_L1_INFO_TREE_SMT_PROOF_VALUE: return runtime.ErrExecutorErrorInvalidL1InfoTreeSmtProofValue + case ExecutorError_EXECUTOR_ERROR_INVALID_WITNESS: + return runtime.ErrExecutorErrorInvalidWitness + case ExecutorError_EXECUTOR_ERROR_INVALID_CBOR: + return runtime.ErrExecutorErrorInvalidCBOR + case ExecutorError_EXECUTOR_ERROR_INVALID_DATA_STREAM: + return runtime.ErrExecutorErrorInvalidDataStream + case ExecutorError_EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE: + return runtime.ErrExecutorErrorInvalidUpdateMerkleTree + case ExecutorError_EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED: + return runtime.ErrExecutorErrorUnsupportedPrecompile } return ErrExecutorUnknown } @@ -678,6 +688,16 @@ func ExecutorErrorCode(err error) ExecutorError { return ExecutorError_EXECUTOR_ERROR_INVALID_L1_INFO_TREE_INDEX case runtime.ErrExecutorErrorInvalidL1InfoTreeSmtProofValue: return ExecutorError_EXECUTOR_ERROR_INVALID_L1_INFO_TREE_SMT_PROOF_VALUE + case runtime.ErrExecutorErrorInvalidWitness: + return ExecutorError_EXECUTOR_ERROR_INVALID_WITNESS + case runtime.ErrExecutorErrorInvalidCBOR: + return ExecutorError_EXECUTOR_ERROR_INVALID_CBOR + case runtime.ErrExecutorErrorInvalidDataStream: + return ExecutorError_EXECUTOR_ERROR_INVALID_DATA_STREAM + case runtime.ErrExecutorErrorInvalidUpdateMerkleTree: + return ExecutorError_EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE + case runtime.ErrExecutorErrorUnsupportedPrecompile: + return ExecutorError_EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED } return ErrCodeExecutorUnknown diff --git a/state/runtime/executor/executor.pb.go b/state/runtime/executor/executor.pb.go index 0215584aac..ab3c79e7d8 100644 --- a/state/runtime/executor/executor.pb.go +++ b/state/runtime/executor/executor.pb.go @@ -430,6 +430,16 @@ const ( ExecutorError_EXECUTOR_ERROR_INVALID_L1_INFO_TREE_INDEX ExecutorError = 111 // EXECUTOR_ERROR_INVALID_L1_INFO_TREE_SMT_PROOF_VALUE indicates that the ROM asked for an L1InfoTree SMT proof that was not present in the input ExecutorError_EXECUTOR_ERROR_INVALID_L1_INFO_TREE_SMT_PROOF_VALUE ExecutorError = 112 + // EXECUTOR_ERROR_INVALID_WITNESS indicates that the provided witness data is invalid + ExecutorError_EXECUTOR_ERROR_INVALID_WITNESS ExecutorError = 113 + // EXECUTOR_ERROR_INVALID_CBOR indicates that the provided CBOR data is invalid + ExecutorError_EXECUTOR_ERROR_INVALID_CBOR ExecutorError = 114 + // EXECUTOR_ERROR_INVALID_DATA_STREAM indicates that the provided data stream data is invalid + ExecutorError_EXECUTOR_ERROR_INVALID_DATA_STREAM ExecutorError = 115 + // EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE indicates that the provided update merkle tree is invalid, e.g. because the executor is configured not to write to database + ExecutorError_EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE ExecutorError = 116 + // EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED indicates that an unsupported precompiled has been used + ExecutorError_EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED ExecutorError = 117 ) // Enum value maps for ExecutorError. @@ -548,6 +558,11 @@ var ( 110: "EXECUTOR_ERROR_STATE_MANAGER", 111: "EXECUTOR_ERROR_INVALID_L1_INFO_TREE_INDEX", 112: "EXECUTOR_ERROR_INVALID_L1_INFO_TREE_SMT_PROOF_VALUE", + 113: "EXECUTOR_ERROR_INVALID_WITNESS", + 114: "EXECUTOR_ERROR_INVALID_CBOR", + 115: "EXECUTOR_ERROR_INVALID_DATA_STREAM", + 116: "EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE", + 117: "EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED", } ExecutorError_value = map[string]int32{ "EXECUTOR_ERROR_UNSPECIFIED": 0, @@ -663,6 +678,11 @@ var ( "EXECUTOR_ERROR_STATE_MANAGER": 110, "EXECUTOR_ERROR_INVALID_L1_INFO_TREE_INDEX": 111, "EXECUTOR_ERROR_INVALID_L1_INFO_TREE_SMT_PROOF_VALUE": 112, + "EXECUTOR_ERROR_INVALID_WITNESS": 113, + "EXECUTOR_ERROR_INVALID_CBOR": 114, + "EXECUTOR_ERROR_INVALID_DATA_STREAM": 115, + "EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE": 116, + "EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED": 117, } ) @@ -4813,7 +4833,7 @@ var file_executor_proto_rawDesc = []byte{ 0x41, 0x4d, 0x50, 0x10, 0x21, 0x12, 0x36, 0x0a, 0x32, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x4d, 0x49, - 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x10, 0x22, 0x2a, 0x9d, 0x2a, + 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x10, 0x22, 0x2a, 0xe5, 0x2b, 0x0a, 0x0d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1e, 0x0a, 0x1a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, @@ -5151,29 +5171,42 @@ var file_executor_proto_rawDesc = []byte{ 0x45, 0x58, 0x10, 0x6f, 0x12, 0x37, 0x0a, 0x33, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4c, 0x31, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x5f, 0x53, 0x4d, 0x54, 0x5f, - 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x70, 0x32, 0x96, 0x02, - 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, - 0x65, 0x12, 0x55, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x12, 0x20, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, - 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x56, 0x32, 0x12, 0x22, 0x2e, 0x65, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x32, 0x1a, 0x23, - 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x56, 0x32, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x75, 0x73, - 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, - 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, - 0x23, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, - 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x78, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x48, 0x65, - 0x72, 0x6d, 0x65, 0x7a, 0x2f, 0x7a, 0x6b, 0x65, 0x76, 0x6d, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x65, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x70, 0x12, 0x22, 0x0a, + 0x1e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x57, 0x49, 0x54, 0x4e, 0x45, 0x53, 0x53, 0x10, + 0x71, 0x12, 0x1f, 0x0a, 0x1b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x42, 0x4f, 0x52, + 0x10, 0x72, 0x12, 0x26, 0x0a, 0x22, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x41, 0x54, + 0x41, 0x5f, 0x53, 0x54, 0x52, 0x45, 0x41, 0x4d, 0x10, 0x73, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x4d, 0x45, 0x52, 0x4b, + 0x4c, 0x45, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x10, 0x74, 0x12, 0x2a, 0x0a, 0x26, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x55, + 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x50, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x50, 0x49, + 0x4c, 0x45, 0x44, 0x10, 0x75, 0x32, 0x96, 0x02, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x6f, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x0c, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x20, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, + 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, + 0x12, 0x5b, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x56, 0x32, 0x12, 0x22, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x56, 0x32, 0x1a, 0x23, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x22, 0x00, 0x12, 0x4f, 0x0a, + 0x0e, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, + 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, + 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x23, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x3e, + 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x78, 0x50, + 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x48, 0x65, 0x72, 0x6d, 0x65, 0x7a, 0x2f, 0x7a, 0x6b, 0x65, + 0x76, 0x6d, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x75, + 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x62, 0x06, + 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/state/runtime/runtime.go b/state/runtime/runtime.go index bc542e9961..137db90335 100644 --- a/state/runtime/runtime.go +++ b/state/runtime/runtime.go @@ -311,6 +311,16 @@ var ( ErrExecutorErrorInvalidL1InfoTreeIndex = errors.New("invalid l1_info_tree_index") // ErrExecutorErrorInvalidL1InfoTreeSmtProofValue indicates that the ROM asked for an L1InfoTree SMT proof that was not present in the input ErrExecutorErrorInvalidL1InfoTreeSmtProofValue = errors.New("invalid l1_info_tree_smt_proof_value") + // ErrExecutorErrorInvalidWitness indicates that the input parameter witness is invalid + ErrExecutorErrorInvalidWitness = errors.New("invalid witness") + // ErrExecutorErrorInvalidCBOR indicates that the input parameter cbor is invalid + ErrExecutorErrorInvalidCBOR = errors.New("invalid cbor") + // ErrExecutorErrorInvalidDataStream indicates that the input parameter data stream is invalid + ErrExecutorErrorInvalidDataStream = errors.New("invalid data stream") + // ErrExecutorErrorInvalidUpdateMerkleTree indicates that the input parameter update merkle tree is invalid + ErrExecutorErrorInvalidUpdateMerkleTree = errors.New("invalid update merkle tree") + // ErrExecutorErrorUnsupportedPrecompile indicates that the precompile is not supported + ErrExecutorErrorUnsupportedPrecompile = errors.New("unsupported precompile") // GRPC ERRORS // =========== diff --git a/state/test/forkid_etrog/etrog_test.go b/state/test/forkid_etrog/etrog_test.go index d8dfd77398..4be5ba1abb 100644 --- a/state/test/forkid_etrog/etrog_test.go +++ b/state/test/forkid_etrog/etrog_test.go @@ -2,17 +2,25 @@ package etrog_test import ( "context" + "errors" "math" "math/big" "os" + "strings" "testing" "time" "github.com/0xPolygonHermez/zkevm-node/ci/vectors" + "github.com/0xPolygonHermez/zkevm-node/merkletree" "github.com/0xPolygonHermez/zkevm-node/state" "github.com/0xPolygonHermez/zkevm-node/state/metrics" + "github.com/0xPolygonHermez/zkevm-node/state/runtime" test "github.com/0xPolygonHermez/zkevm-node/state/test/forkid_common" + "github.com/0xPolygonHermez/zkevm-node/test/testutils" + "github.com/ethereum/go-ethereum/accounts/abi/bind" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" + "github.com/ethereum/go-ethereum/crypto" "github.com/stretchr/testify/require" ) @@ -131,3 +139,134 @@ func TestStateTransition(t *testing.T) { } } } + +func TestUnsupportedPrecompile(t *testing.T) { + ctx := context.Background() + var chainIDSequencer = new(big.Int).SetUint64(stateCfg.ChainID) + var sequencerAddress = common.HexToAddress("0x617b3a3528F9cDd6630fd3301B9c8911F7Bf063D") + var sequencerPvtKey = "0x28b2b0318721be8c8339199172cd7cc8f5e273800a35616ec893083a4b32c02e" + var scAddress = common.HexToAddress("0x1275fbb540c8efC58b812ba83B0D0B8b9917AE98") + var sequencerBalance = 4000000 + scByteCode, err := testutils.ReadBytecode("customModExp/customModExp.bin") + require.NoError(t, err) + + // Set Genesis + block := state.Block{ + BlockNumber: 0, + BlockHash: state.ZeroHash, + ParentHash: state.ZeroHash, + ReceivedAt: time.Now(), + } + + test.Genesis.Actions = []*state.GenesisAction{ + { + Address: "0x617b3a3528F9cDd6630fd3301B9c8911F7Bf063D", + Type: int(merkletree.LeafTypeBalance), + Value: "100000000000000000000000", + }, + { + Address: "0x70997970C51812dc3A010C7d01b50e0d17dc79C8", + Type: int(merkletree.LeafTypeBalance), + Value: "100000000000000000000000", + }, + { + Address: "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266", + Type: int(merkletree.LeafTypeBalance), + Value: "100000000000000000000000", + }, + } + + test.InitOrResetDB(test.StateDBCfg) + + dbTx, err := testState.BeginStateTransaction(ctx) + require.NoError(t, err) + stateRoot, err := testState.SetGenesis(ctx, block, test.Genesis, metrics.SynchronizerCallerLabel, dbTx) + require.NoError(t, err) + require.NoError(t, dbTx.Commit(ctx)) + + nonce := uint64(0) + + // Deploy contract + tx0 := types.NewTx(&types.LegacyTx{ + Nonce: nonce, + To: nil, + Value: new(big.Int), + Gas: uint64(sequencerBalance), + GasPrice: new(big.Int).SetUint64(0), + Data: common.Hex2Bytes(scByteCode), + }) + + privateKey, err := crypto.HexToECDSA(strings.TrimPrefix(sequencerPvtKey, "0x")) + require.NoError(t, err) + auth, err := bind.NewKeyedTransactorWithChainID(privateKey, chainIDSequencer) + require.NoError(t, err) + + signedTx0, err := auth.Signer(auth.From, tx0) + require.NoError(t, err) + + // Call SC method + nonce++ + tx1 := types.NewTransaction(nonce, scAddress, new(big.Int), 40000, new(big.Int).SetUint64(1), common.Hex2Bytes("d5665d6f000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000")) + signedTx1, err := auth.Signer(auth.From, tx1) + require.NoError(t, err) + + l2block := state.L2BlockRaw{ + DeltaTimestamp: 3, + IndexL1InfoTree: 0, + Transactions: []state.L2TxRaw{{Tx: *signedTx0, EfficiencyPercentage: 255}}, + } + + batch := state.BatchRawV2{ + Blocks: []state.L2BlockRaw{l2block}, + } + + batchData, err := state.EncodeBatchV2(&batch) + require.NoError(t, err) + + processRequest := state.ProcessRequest{ + BatchNumber: 1, + L1InfoRoot_V2: common.Hash{}, + OldStateRoot: stateRoot, + OldAccInputHash: common.Hash{}, + Transactions: batchData, + TimestampLimit_V2: 3, + Coinbase: sequencerAddress, + ForkID: forkID, + SkipVerifyL1InfoRoot_V2: true, + } + + processResponse, _ := testState.ProcessBatchV2(ctx, processRequest, true) + require.Nil(t, processResponse.ExecutorError) + require.NoError(t, err) + + // Call SC method + l2block = state.L2BlockRaw{ + DeltaTimestamp: 3, + IndexL1InfoTree: 0, + Transactions: []state.L2TxRaw{{Tx: *signedTx1, EfficiencyPercentage: 255}}, + } + + batch = state.BatchRawV2{ + Blocks: []state.L2BlockRaw{l2block}, + } + + batchData, err = state.EncodeBatchV2(&batch) + require.NoError(t, err) + + processRequest = state.ProcessRequest{ + BatchNumber: 2, + L1InfoRoot_V2: common.Hash{}, + OldStateRoot: processResponse.NewStateRoot, + OldAccInputHash: common.Hash{}, + Transactions: batchData, + TimestampLimit_V2: 6, + Coinbase: sequencerAddress, + ForkID: forkID, + SkipVerifyL1InfoRoot_V2: true, + } + + processResponse, err = testState.ProcessBatchV2(ctx, processRequest, true) + require.Error(t, err) + require.Nil(t, processResponse) + require.True(t, errors.Is(err, runtime.ErrExecutorErrorUnsupportedPrecompile)) +} diff --git a/test/contracts/auto/customModExp.sol b/test/contracts/auto/customModExp.sol new file mode 100644 index 0000000000..b9becfeacb --- /dev/null +++ b/test/contracts/auto/customModExp.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity ^0.8.24; + +contract customModExp { + bytes32 hashResult; + address retEcrecover; + bytes dataResult; + uint256 dataRes; + + bytes32[10] arrayStorage; + + function modExpGeneric(bytes memory input) public { + bytes32[10] memory output; + + assembly { + let success := staticcall(gas(), 0x05, add(input, 32), mload(input), output, 0x140) + sstore(0x00, success) + } + + for (uint i = 0; i < 10; i++) { + arrayStorage[i] = output[i]; + } + } +} \ No newline at end of file diff --git a/test/contracts/index.yaml b/test/contracts/index.yaml index c57470a48b..f284f6a09f 100644 --- a/test/contracts/index.yaml +++ b/test/contracts/index.yaml @@ -25,7 +25,7 @@ compileUnits: parallel: - name: auto # all the files under tests/contracts/auto will be compiled automatically - solcVersion: 0.8.12-alpine + solcVersion: 0.8.24-alpine inputPath: auto outputPath: "." diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 9e7193c21d..ce9577e546 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -513,7 +513,7 @@ services: zkevm-prover: container_name: zkevm-prover - image: hermeznetwork/zkevm-prover:v4.0.4 + image: hermeznetwork/zkevm-prover:v4.0.10 ports: - 50061:50061 # MT - 50071:50071 # Executor @@ -602,7 +602,7 @@ services: zkevm-permissionless-prover: container_name: zkevm-permissionless-prover - image: hermeznetwork/zkevm-prover:v4.0.4 + image: hermeznetwork/zkevm-prover:v4.0.10 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover From a332d41bbcd464ed8d79c101acb5e207e739243d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= Date: Tue, 13 Feb 2024 14:42:13 +0100 Subject: [PATCH 2/9] downgrade prover --- docker-compose.yml | 2 +- test/docker-compose.yml | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 536f89b5fb..ab43109278 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -107,7 +107,7 @@ services: zkevm-prover: container_name: zkevm-prover restart: unless-stopped - image: hermeznetwork/zkevm-prover:v4.0.10 + image: hermeznetwork/zkevm-prover:v4.0.8 depends_on: zkevm-state-db: condition: service_healthy diff --git a/test/docker-compose.yml b/test/docker-compose.yml index ce9577e546..9f78ce46e2 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -513,7 +513,7 @@ services: zkevm-prover: container_name: zkevm-prover - image: hermeznetwork/zkevm-prover:v4.0.10 + image: hermeznetwork/zkevm-prover:v4.0.8 ports: - 50061:50061 # MT - 50071:50071 # Executor @@ -602,7 +602,7 @@ services: zkevm-permissionless-prover: container_name: zkevm-permissionless-prover - image: hermeznetwork/zkevm-prover:v4.0.10 + image: hermeznetwork/zkevm-prover:v4.0.8 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover From 969aa92c5bb7e2b290e7ca79b4cf8841fd6aaf86 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= Date: Tue, 13 Feb 2024 15:20:16 +0100 Subject: [PATCH 3/9] restore solc version --- docker-compose.yml | 2 +- test/contracts/index.yaml | 2 +- test/docker-compose.yml | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index ab43109278..536f89b5fb 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -107,7 +107,7 @@ services: zkevm-prover: container_name: zkevm-prover restart: unless-stopped - image: hermeznetwork/zkevm-prover:v4.0.8 + image: hermeznetwork/zkevm-prover:v4.0.10 depends_on: zkevm-state-db: condition: service_healthy diff --git a/test/contracts/index.yaml b/test/contracts/index.yaml index f284f6a09f..c57470a48b 100644 --- a/test/contracts/index.yaml +++ b/test/contracts/index.yaml @@ -25,7 +25,7 @@ compileUnits: parallel: - name: auto # all the files under tests/contracts/auto will be compiled automatically - solcVersion: 0.8.24-alpine + solcVersion: 0.8.12-alpine inputPath: auto outputPath: "." diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 9f78ce46e2..ce9577e546 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -513,7 +513,7 @@ services: zkevm-prover: container_name: zkevm-prover - image: hermeznetwork/zkevm-prover:v4.0.8 + image: hermeznetwork/zkevm-prover:v4.0.10 ports: - 50061:50061 # MT - 50071:50071 # Executor @@ -602,7 +602,7 @@ services: zkevm-permissionless-prover: container_name: zkevm-permissionless-prover - image: hermeznetwork/zkevm-prover:v4.0.8 + image: hermeznetwork/zkevm-prover:v4.0.10 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover From 63341122d525281e8abafd0a3d780a5036111561 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= Date: Tue, 13 Feb 2024 16:03:39 +0100 Subject: [PATCH 4/9] update SC --- test/contracts/auto/customModExp.sol | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/contracts/auto/customModExp.sol b/test/contracts/auto/customModExp.sol index b9becfeacb..b1926aa4f0 100644 --- a/test/contracts/auto/customModExp.sol +++ b/test/contracts/auto/customModExp.sol @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MIT -pragma solidity ^0.8.24; +pragma solidity >=0.7.0 <0.9.0; contract customModExp { bytes32 hashResult; From 43eb91fd647420f6cae7a489423b0ade15355220 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= Date: Wed, 14 Feb 2024 10:30:10 +0100 Subject: [PATCH 5/9] new errors --- proto/src/proto/executor/v1/executor.proto | 6 ++- state/convertersV2.go | 3 +- state/runtime/executor/errors.go | 8 +++ state/runtime/executor/executor.pb.go | 59 +++++++++++++--------- state/runtime/runtime.go | 4 ++ state/types.go | 1 + 6 files changed, 55 insertions(+), 26 deletions(-) diff --git a/proto/src/proto/executor/v1/executor.proto b/proto/src/proto/executor/v1/executor.proto index cef5cf5321..dc43c4fab6 100644 --- a/proto/src/proto/executor/v1/executor.proto +++ b/proto/src/proto/executor/v1/executor.proto @@ -862,6 +862,10 @@ enum ExecutorError { EXECUTOR_ERROR_INVALID_DATA_STREAM = 115; // EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE indicates that the provided update merkle tree is invalid, e.g. because the executor is configured not to write to database EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE = 116; - // EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED indicates that an unsupported precompiled has been used + // EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED indicates that an unsupported precompiled has been used EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED = 117; + // EXECUTOR_ERROR_OOG_2 indicates that an out of gas has occurred + EXECUTOR_ERROR_OOG_2 = 118; + // EXECUTOR_ERROR_CLOSE_BATCH indicates that batch must be closed + EXECUTOR_ERROR_CLOSE_BATCH = 119; } diff --git a/state/convertersV2.go b/state/convertersV2.go index fde56858bd..46b03bf3ab 100644 --- a/state/convertersV2.go +++ b/state/convertersV2.go @@ -56,7 +56,7 @@ func (s *State) convertToProcessBatchResponseV2(batchResponse *executor.ProcessB FlushID: batchResponse.FlushId, StoredFlushID: batchResponse.StoredFlushId, ProverID: batchResponse.ProverId, - IsExecutorLevelError: (batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR), + IsExecutorLevelError: (batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH), IsRomLevelError: isRomLevelError, IsRomOOCError: isRomOOCError, GasUsed_V2: batchResponse.GasUsed, @@ -65,6 +65,7 @@ func (s *State) convertToProcessBatchResponseV2(batchResponse *executor.ProcessB ForkID: batchResponse.ForkId, InvalidBatch_V2: batchResponse.InvalidBatch != 0, RomError_V2: executor.RomErr(batchResponse.ErrorRom), + CloseBatch_V2: batchResponse.Error == executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH, }, nil } diff --git a/state/runtime/executor/errors.go b/state/runtime/executor/errors.go index e2cbbab59f..ace96ea969 100644 --- a/state/runtime/executor/errors.go +++ b/state/runtime/executor/errors.go @@ -456,6 +456,10 @@ func ExecutorErr(errorCode ExecutorError) error { return runtime.ErrExecutorErrorInvalidUpdateMerkleTree case ExecutorError_EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED: return runtime.ErrExecutorErrorUnsupportedPrecompile + case ExecutorError_EXECUTOR_ERROR_OOG_2: + return runtime.ErrExecutorErrorOOG2 + case ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH: + return runtime.ErrExecutorErrorCloseBatch } return ErrExecutorUnknown } @@ -698,6 +702,10 @@ func ExecutorErrorCode(err error) ExecutorError { return ExecutorError_EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE case runtime.ErrExecutorErrorUnsupportedPrecompile: return ExecutorError_EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED + case runtime.ErrExecutorErrorOOG2: + return ExecutorError_EXECUTOR_ERROR_OOG_2 + case runtime.ErrExecutorErrorCloseBatch: + return ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH } return ErrCodeExecutorUnknown diff --git a/state/runtime/executor/executor.pb.go b/state/runtime/executor/executor.pb.go index ab3c79e7d8..2b94c5c0e0 100644 --- a/state/runtime/executor/executor.pb.go +++ b/state/runtime/executor/executor.pb.go @@ -440,6 +440,10 @@ const ( ExecutorError_EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE ExecutorError = 116 // EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED indicates that an unsupported precompiled has been used ExecutorError_EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED ExecutorError = 117 + // EXECUTOR_ERROR_OOG_2 indicates that an out of gas has occurred + ExecutorError_EXECUTOR_ERROR_OOG_2 ExecutorError = 118 + // EXECUTOR_ERROR_CLOSE_BATCH indicates that batch must be closed + ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH ExecutorError = 119 ) // Enum value maps for ExecutorError. @@ -563,6 +567,8 @@ var ( 115: "EXECUTOR_ERROR_INVALID_DATA_STREAM", 116: "EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE", 117: "EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED", + 118: "EXECUTOR_ERROR_OOG_2", + 119: "EXECUTOR_ERROR_CLOSE_BATCH", } ExecutorError_value = map[string]int32{ "EXECUTOR_ERROR_UNSPECIFIED": 0, @@ -683,6 +689,8 @@ var ( "EXECUTOR_ERROR_INVALID_DATA_STREAM": 115, "EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE": 116, "EXECUTOR_ERROR_UNSUPPORTED_PRECOMPILED": 117, + "EXECUTOR_ERROR_OOG_2": 118, + "EXECUTOR_ERROR_CLOSE_BATCH": 119, } ) @@ -4833,7 +4841,7 @@ var file_executor_proto_rawDesc = []byte{ 0x41, 0x4d, 0x50, 0x10, 0x21, 0x12, 0x36, 0x0a, 0x32, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x4d, 0x49, - 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x10, 0x22, 0x2a, 0xe5, 0x2b, + 0x4e, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x10, 0x22, 0x2a, 0x9f, 0x2c, 0x0a, 0x0d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x1e, 0x0a, 0x1a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, @@ -5184,29 +5192,32 @@ var file_executor_proto_rawDesc = []byte{ 0x4c, 0x45, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x10, 0x74, 0x12, 0x2a, 0x0a, 0x26, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x50, 0x52, 0x45, 0x43, 0x4f, 0x4d, 0x50, 0x49, - 0x4c, 0x45, 0x44, 0x10, 0x75, 0x32, 0x96, 0x02, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x6f, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x0c, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x20, 0x2e, 0x65, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x65, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, - 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, - 0x12, 0x5b, 0x0a, 0x0e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x56, 0x32, 0x12, 0x22, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, - 0x75, 0x65, 0x73, 0x74, 0x56, 0x32, 0x1a, 0x23, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x22, 0x00, 0x12, 0x4f, 0x0a, - 0x0e, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, 0x79, 0x1a, 0x23, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x53, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x3e, - 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x78, 0x50, - 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, 0x48, 0x65, 0x72, 0x6d, 0x65, 0x7a, 0x2f, 0x7a, 0x6b, 0x65, - 0x76, 0x6d, 0x2d, 0x6e, 0x6f, 0x64, 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x75, - 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x62, 0x06, - 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x4c, 0x45, 0x44, 0x10, 0x75, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x4f, 0x47, 0x5f, 0x32, 0x10, 0x76, 0x12, + 0x1e, 0x0a, 0x1a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x43, 0x4c, 0x4f, 0x53, 0x45, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x10, 0x77, 0x32, + 0x96, 0x02, 0x0a, 0x0f, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x53, 0x65, 0x72, 0x76, + 0x69, 0x63, 0x65, 0x12, 0x55, 0x0a, 0x0c, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x12, 0x20, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, + 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x21, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x12, 0x5b, 0x0a, 0x0e, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x56, 0x32, 0x12, 0x22, 0x2e, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x32, + 0x1a, 0x23, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, + 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x56, 0x32, 0x22, 0x00, 0x12, 0x4f, 0x0a, 0x0e, 0x47, 0x65, 0x74, 0x46, 0x6c, + 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x16, 0x2e, 0x67, 0x6f, 0x6f, 0x67, + 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x45, 0x6d, 0x70, 0x74, + 0x79, 0x1a, 0x23, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x22, 0x00, 0x42, 0x3e, 0x5a, 0x3c, 0x67, 0x69, 0x74, 0x68, + 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x78, 0x50, 0x6f, 0x6c, 0x79, 0x67, 0x6f, 0x6e, + 0x48, 0x65, 0x72, 0x6d, 0x65, 0x7a, 0x2f, 0x7a, 0x6b, 0x65, 0x76, 0x6d, 0x2d, 0x6e, 0x6f, 0x64, + 0x65, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x2f, 0x72, 0x75, 0x6e, 0x74, 0x69, 0x6d, 0x65, 0x2f, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/state/runtime/runtime.go b/state/runtime/runtime.go index 137db90335..2fa1f05369 100644 --- a/state/runtime/runtime.go +++ b/state/runtime/runtime.go @@ -321,6 +321,10 @@ var ( ErrExecutorErrorInvalidUpdateMerkleTree = errors.New("invalid update merkle tree") // ErrExecutorErrorUnsupportedPrecompile indicates that the precompile is not supported ErrExecutorErrorUnsupportedPrecompile = errors.New("unsupported precompile") + // EXECUTOR_ERROR_OOG_2 indicates that an out of gas has occurred + ErrExecutorErrorOOG2 = errors.New("out of gas 2") + // EXECUTOR_ERROR_CLOSE_BATCH indicates that batch must be closed + ErrExecutorErrorCloseBatch = errors.New("close batch") // GRPC ERRORS // =========== diff --git a/state/types.go b/state/types.go index 510e1b1a37..e44052f205 100644 --- a/state/types.go +++ b/state/types.go @@ -64,6 +64,7 @@ type ProcessBatchResponse struct { ForkID uint64 InvalidBatch_V2 bool RomError_V2 error + CloseBatch_V2 bool } // ProcessBlockResponse represents the response of a block From ad26b039d6b77e2b6aa016596e2616065511051c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Wed, 14 Feb 2024 10:30:37 +0100 Subject: [PATCH 6/9] fix as workaround to close batch on tx oog (#3271) Co-authored-by: agnusmor --- sequencer/finalizer.go | 48 ++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 18 deletions(-) diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index 452b43346e..de97876f99 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -284,6 +284,7 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { continue } + closeWIPBatch := false metrics.WorkerProcessingTime(time.Since(start)) if tx != nil { showNotFoundTxLog = true @@ -291,7 +292,8 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { firstTxProcess := true for { - _, err := f.processTransaction(ctx, tx, firstTxProcess) + var err error + _, err, closeWIPBatch = f.processTransaction(ctx, tx, firstTxProcess) if err != nil { if err == ErrEffectiveGasPriceReprocess { firstTxProcess = false @@ -326,7 +328,11 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { } // Check if we must finalize the batch due to a closing reason (resources exhausted, max txs, timestamp resolution, forced batches deadline) - if finalize, closeReason := f.checkIfFinalizeBatch(); finalize { + finalize, closeReason := f.checkIfFinalizeBatch() + if closeWIPBatch || finalize { + if closeWIPBatch { + closeReason = "tx OOG" + } f.finalizeWIPBatch(ctx, closeReason) } @@ -338,7 +344,7 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { } // processTransaction processes a single transaction. -func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, firstTxProcess bool) (errWg *sync.WaitGroup, err error) { +func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, firstTxProcess bool) (errWg *sync.WaitGroup, err error, closeWIPBatch bool) { start := time.Now() defer func() { metrics.ProcessingTime(time.Since(start)) @@ -381,7 +387,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first egp, err := f.effectiveGasPrice.CalculateEffectiveGasPrice(tx.RawTx, txGasPrice, tx.BatchResources.ZKCounters.GasUsed, tx.L1GasPrice, txL2GasPrice) if err != nil { if f.effectiveGasPrice.IsEnabled() { - return nil, err + return nil, err, false } else { log.Warnf("effectiveGasPrice is disabled, but failed to calculate effectiveGasPrice for tx %s, error: %v", tx.HashStr, err) tx.EGPLog.Error = fmt.Sprintf("CalculateEffectiveGasPrice#1: %s", err) @@ -409,7 +415,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first egpPercentage, err := f.effectiveGasPrice.CalculateEffectiveGasPricePercentage(txGasPrice, tx.EffectiveGasPrice) if err != nil { if f.effectiveGasPrice.IsEnabled() { - return nil, err + return nil, err, false } else { log.Warnf("effectiveGasPrice is disabled, but failed to to calculate efftive gas price percentage (#1), error: %v", err) tx.EGPLog.Error = fmt.Sprintf("%s; CalculateEffectiveGasPricePercentage#1: %s", tx.EGPLog.Error, err) @@ -429,7 +435,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first effectivePercentageAsDecodedHex, err := hex.DecodeHex(fmt.Sprintf("%x", tx.EGPPercentage)) if err != nil { - return nil, err + return nil, err, false } batchRequest.Transactions = append(batchRequest.Transactions, effectivePercentageAsDecodedHex...) @@ -438,7 +444,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first if err != nil && (errors.Is(err, runtime.ErrExecutorDBError) || errors.Is(err, runtime.ErrInvalidTxChangeL2BlockMinTimestamp)) { log.Errorf("failed to process tx %s, error: %v", tx.HashStr, err) - return nil, err + return nil, err, false } else if err == nil && !batchResponse.IsRomLevelError && len(batchResponse.BlockResponses) == 0 { err = fmt.Errorf("executor returned no errors and no responses for tx %s", tx.HashStr) f.Halt(ctx, err, false) @@ -477,14 +483,15 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first } else { metrics.TxProcessed(metrics.TxProcessedLabelInvalid, 1) } - return nil, err + return nil, err, false } + closeBatch := false oldStateRoot := f.wipBatch.imStateRoot if len(batchResponse.BlockResponses) > 0 { - errWg, err = f.handleProcessTransactionResponse(ctx, tx, batchResponse, oldStateRoot) + errWg, err, closeBatch = f.handleProcessTransactionResponse(ctx, tx, batchResponse, oldStateRoot) if err != nil { - return errWg, err + return errWg, err, false } } @@ -494,17 +501,17 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first log.Infof("processed tx %s, batchNumber: %d, l2Block: [%d], newStateRoot: %s, oldStateRoot: %s, used counters: %s", tx.HashStr, batchRequest.BatchNumber, f.wipL2Block.trackingNum, batchResponse.NewStateRoot.String(), batchRequest.OldStateRoot.String(), f.logZKCounters(batchResponse.UsedZkCounters)) - return nil, nil + return nil, nil, closeBatch } // handleProcessTransactionResponse handles the response of transaction processing. -func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *TxTracker, result *state.ProcessBatchResponse, oldStateRoot common.Hash) (errWg *sync.WaitGroup, err error) { +func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *TxTracker, result *state.ProcessBatchResponse, oldStateRoot common.Hash) (errWg *sync.WaitGroup, err error, closeWIPBatch bool) { // Handle Transaction Error errorCode := executor.RomErrorCode(result.BlockResponses[0].TransactionResponses[0].RomError) if !state.IsStateRootChanged(errorCode) { // If intrinsic error or OOC error, we skip adding the transaction to the batch errWg = f.handleProcessTransactionError(ctx, result, tx) - return errWg, result.BlockResponses[0].TransactionResponses[0].RomError + return errWg, result.BlockResponses[0].TransactionResponses[0].RomError, false } egpEnabled := f.effectiveGasPrice.IsEnabled() @@ -519,7 +526,7 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx if err != nil { if egpEnabled { log.Errorf("failed to calculate effective gas price with new gasUsed for tx %s, error: %v", tx.HashStr, err.Error()) - return nil, err + return nil, err, false } else { log.Warnf("effectiveGasPrice is disabled, but failed to calculate effective gas price with new gasUsed for tx %s, error: %v", tx.HashStr, err.Error()) tx.EGPLog.Error = fmt.Sprintf("%s; CalculateEffectiveGasPrice#2: %s", tx.EGPLog.Error, err) @@ -544,7 +551,7 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx } if errCompare != nil && egpEnabled { - return nil, errCompare + return nil, errCompare, false } } } @@ -580,12 +587,12 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx log.Errorf("failed to update status to invalid in the pool for tx %s, error: %v", tx.Hash.String(), err) } - return nil, ErrBatchResourceUnderFlow + return nil, ErrBatchResourceUnderFlow, false } else { start := time.Now() f.workerIntf.UpdateTxZKCounters(result.BlockResponses[0].TransactionResponses[0].TxHash, tx.From, result.UsedZkCounters) metrics.WorkerProcessingTime(time.Since(start)) - return nil, ErrBatchResourceUnderFlow + return nil, ErrBatchResourceUnderFlow, false } } @@ -606,7 +613,12 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx f.updateWorkerAfterSuccessfulProcessing(ctx, tx.Hash, tx.From, false, result) - return nil, nil + if errors.Is(result.BlockResponses[0].TransactionResponses[0].RomError, runtime.ErrOutOfGas) { + log.Infof("tx %s is OOG", tx.HashStr) + return nil, nil, true + } + + return nil, nil, false } // compareTxEffectiveGasPrice compares newEffectiveGasPrice with tx.EffectiveGasPrice. From b3112e9e04bc0864cfdc55fc3cc846f7ca45fb43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= Date: Wed, 14 Feb 2024 10:38:01 +0100 Subject: [PATCH 7/9] handle executor close batch --- sequencer/finalizer.go | 41 ++++++++++++++++++++-------------------- state/runtime/runtime.go | 4 ++-- 2 files changed, 22 insertions(+), 23 deletions(-) diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index de97876f99..cd25871565 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -293,7 +293,7 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { for { var err error - _, err, closeWIPBatch = f.processTransaction(ctx, tx, firstTxProcess) + _, closeWIPBatch, err = f.processTransaction(ctx, tx, firstTxProcess) if err != nil { if err == ErrEffectiveGasPriceReprocess { firstTxProcess = false @@ -331,7 +331,7 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { finalize, closeReason := f.checkIfFinalizeBatch() if closeWIPBatch || finalize { if closeWIPBatch { - closeReason = "tx OOG" + closeReason = "Executor Close Batch" } f.finalizeWIPBatch(ctx, closeReason) } @@ -344,7 +344,7 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { } // processTransaction processes a single transaction. -func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, firstTxProcess bool) (errWg *sync.WaitGroup, err error, closeWIPBatch bool) { +func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, firstTxProcess bool) (errWg *sync.WaitGroup, closeWIPBatch bool, err error) { start := time.Now() defer func() { metrics.ProcessingTime(time.Since(start)) @@ -387,7 +387,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first egp, err := f.effectiveGasPrice.CalculateEffectiveGasPrice(tx.RawTx, txGasPrice, tx.BatchResources.ZKCounters.GasUsed, tx.L1GasPrice, txL2GasPrice) if err != nil { if f.effectiveGasPrice.IsEnabled() { - return nil, err, false + return nil, false, err } else { log.Warnf("effectiveGasPrice is disabled, but failed to calculate effectiveGasPrice for tx %s, error: %v", tx.HashStr, err) tx.EGPLog.Error = fmt.Sprintf("CalculateEffectiveGasPrice#1: %s", err) @@ -415,7 +415,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first egpPercentage, err := f.effectiveGasPrice.CalculateEffectiveGasPricePercentage(txGasPrice, tx.EffectiveGasPrice) if err != nil { if f.effectiveGasPrice.IsEnabled() { - return nil, err, false + return nil, false, err } else { log.Warnf("effectiveGasPrice is disabled, but failed to to calculate efftive gas price percentage (#1), error: %v", err) tx.EGPLog.Error = fmt.Sprintf("%s; CalculateEffectiveGasPricePercentage#1: %s", tx.EGPLog.Error, err) @@ -435,7 +435,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first effectivePercentageAsDecodedHex, err := hex.DecodeHex(fmt.Sprintf("%x", tx.EGPPercentage)) if err != nil { - return nil, err, false + return nil, false, err } batchRequest.Transactions = append(batchRequest.Transactions, effectivePercentageAsDecodedHex...) @@ -444,7 +444,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first if err != nil && (errors.Is(err, runtime.ErrExecutorDBError) || errors.Is(err, runtime.ErrInvalidTxChangeL2BlockMinTimestamp)) { log.Errorf("failed to process tx %s, error: %v", tx.HashStr, err) - return nil, err, false + return nil, false, err } else if err == nil && !batchResponse.IsRomLevelError && len(batchResponse.BlockResponses) == 0 { err = fmt.Errorf("executor returned no errors and no responses for tx %s", tx.HashStr) f.Halt(ctx, err, false) @@ -483,15 +483,15 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first } else { metrics.TxProcessed(metrics.TxProcessedLabelInvalid, 1) } - return nil, err, false + return nil, false, err } closeBatch := false oldStateRoot := f.wipBatch.imStateRoot if len(batchResponse.BlockResponses) > 0 { - errWg, err, closeBatch = f.handleProcessTransactionResponse(ctx, tx, batchResponse, oldStateRoot) + errWg, closeBatch, err = f.handleProcessTransactionResponse(ctx, tx, batchResponse, oldStateRoot) if err != nil { - return errWg, err, false + return errWg, false, err } } @@ -501,17 +501,17 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first log.Infof("processed tx %s, batchNumber: %d, l2Block: [%d], newStateRoot: %s, oldStateRoot: %s, used counters: %s", tx.HashStr, batchRequest.BatchNumber, f.wipL2Block.trackingNum, batchResponse.NewStateRoot.String(), batchRequest.OldStateRoot.String(), f.logZKCounters(batchResponse.UsedZkCounters)) - return nil, nil, closeBatch + return nil, closeBatch, nil } // handleProcessTransactionResponse handles the response of transaction processing. -func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *TxTracker, result *state.ProcessBatchResponse, oldStateRoot common.Hash) (errWg *sync.WaitGroup, err error, closeWIPBatch bool) { +func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *TxTracker, result *state.ProcessBatchResponse, oldStateRoot common.Hash) (errWg *sync.WaitGroup, closeWIPBatch bool, err error) { // Handle Transaction Error errorCode := executor.RomErrorCode(result.BlockResponses[0].TransactionResponses[0].RomError) if !state.IsStateRootChanged(errorCode) { // If intrinsic error or OOC error, we skip adding the transaction to the batch errWg = f.handleProcessTransactionError(ctx, result, tx) - return errWg, result.BlockResponses[0].TransactionResponses[0].RomError, false + return errWg, false, result.BlockResponses[0].TransactionResponses[0].RomError } egpEnabled := f.effectiveGasPrice.IsEnabled() @@ -526,7 +526,7 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx if err != nil { if egpEnabled { log.Errorf("failed to calculate effective gas price with new gasUsed for tx %s, error: %v", tx.HashStr, err.Error()) - return nil, err, false + return nil, false, err } else { log.Warnf("effectiveGasPrice is disabled, but failed to calculate effective gas price with new gasUsed for tx %s, error: %v", tx.HashStr, err.Error()) tx.EGPLog.Error = fmt.Sprintf("%s; CalculateEffectiveGasPrice#2: %s", tx.EGPLog.Error, err) @@ -551,7 +551,7 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx } if errCompare != nil && egpEnabled { - return nil, errCompare, false + return nil, false, errCompare } } } @@ -587,12 +587,12 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx log.Errorf("failed to update status to invalid in the pool for tx %s, error: %v", tx.Hash.String(), err) } - return nil, ErrBatchResourceUnderFlow, false + return nil, false, ErrBatchResourceUnderFlow } else { start := time.Now() f.workerIntf.UpdateTxZKCounters(result.BlockResponses[0].TransactionResponses[0].TxHash, tx.From, result.UsedZkCounters) metrics.WorkerProcessingTime(time.Since(start)) - return nil, ErrBatchResourceUnderFlow, false + return nil, false, ErrBatchResourceUnderFlow } } @@ -613,12 +613,11 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx f.updateWorkerAfterSuccessfulProcessing(ctx, tx.Hash, tx.From, false, result) - if errors.Is(result.BlockResponses[0].TransactionResponses[0].RomError, runtime.ErrOutOfGas) { - log.Infof("tx %s is OOG", tx.HashStr) - return nil, nil, true + if result.CloseBatch_V2 { + return nil, true, nil } - return nil, nil, false + return nil, false, nil } // compareTxEffectiveGasPrice compares newEffectiveGasPrice with tx.EffectiveGasPrice. diff --git a/state/runtime/runtime.go b/state/runtime/runtime.go index 2fa1f05369..63e446746e 100644 --- a/state/runtime/runtime.go +++ b/state/runtime/runtime.go @@ -321,9 +321,9 @@ var ( ErrExecutorErrorInvalidUpdateMerkleTree = errors.New("invalid update merkle tree") // ErrExecutorErrorUnsupportedPrecompile indicates that the precompile is not supported ErrExecutorErrorUnsupportedPrecompile = errors.New("unsupported precompile") - // EXECUTOR_ERROR_OOG_2 indicates that an out of gas has occurred + // ErrExecutorErrorOOG2 indicates that an out of gas has occurred ErrExecutorErrorOOG2 = errors.New("out of gas 2") - // EXECUTOR_ERROR_CLOSE_BATCH indicates that batch must be closed + // ErrExecutorErrorCloseBatch indicates that batch must be closed ErrExecutorErrorCloseBatch = errors.New("close batch") // GRPC ERRORS From 6f571e99888247f342cc268b296c5da18703a64d Mon Sep 17 00:00:00 2001 From: agnusmor Date: Wed, 14 Feb 2024 10:41:58 +0100 Subject: [PATCH 8/9] added sanity check closing an empty batch --- sequencer/batch.go | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/sequencer/batch.go b/sequencer/batch.go index 877dd76a0a..6643ed15ee 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -305,6 +305,11 @@ func (f *finalizer) openNewWIPBatch(ctx context.Context, batchNumber uint64, sta // closeWIPBatch closes the current batch in the state func (f *finalizer) closeWIPBatch(ctx context.Context) error { + // Sanity check: batch must not be empty (should have L2 blocks) + if f.wipBatch.isEmpty() { + f.Halt(ctx, fmt.Errorf("closing WIP batch %d without L2 blocks and should have at least 1", f.wipBatch.batchNumber), false) + } + usedResources := getUsedBatchResources(f.batchConstraints, f.wipBatch.imRemainingResources) receipt := state.ProcessingReceipt{ BatchNumber: f.wipBatch.batchNumber, From cdf99eab3ba8257c947bc96832a1b9534908a169 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= Date: Wed, 14 Feb 2024 10:48:47 +0100 Subject: [PATCH 9/9] change log --- sequencer/finalizer.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index cd25871565..c1421de489 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -331,7 +331,7 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { finalize, closeReason := f.checkIfFinalizeBatch() if closeWIPBatch || finalize { if closeWIPBatch { - closeReason = "Executor Close Batch" + closeReason = "Executor close batch" } f.finalizeWIPBatch(ctx, closeReason) }