From 0171536b04448817e228dbd4280f8f8d5c3e5052 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 11:09:09 +0100 Subject: [PATCH 01/51] check unsupported precompiles (#3264) * check unsupported precompiles * downgrade prover * restore solc version * update SC * new errors * fix as workaround to close batch on tx oog (#3271) Co-authored-by: agnusmor * handle executor close batch * added sanity check closing an empty batch * change log --------- Co-authored-by: agnusmor --- docker-compose.yml | 2 +- event/event.go | 3 + proto/src/proto/executor/v1/executor.proto | 14 +++ sequencer/batch.go | 5 + sequencer/finalizer.go | 70 ++++++++--- state/convertersV2.go | 3 +- state/pgstatestorage/datastream.go | 2 +- state/runtime/executor/errors.go | 28 +++++ state/runtime/executor/executor.pb.go | 90 +++++++++---- state/runtime/runtime.go | 14 +++ state/test/forkid_etrog/etrog_test.go | 139 +++++++++++++++++++++ state/types.go | 1 + test/contracts/auto/customModExp.sol | 24 ++++ test/docker-compose.yml | 4 +- 14 files changed, 353 insertions(+), 46 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 c0a8c0d94f..840078749a 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" + // EventID_NodeOOC is triggered when an OOC at node level is detected EventID_NodeOOC EventID = "NODE OOC" // Source_Node is the source of the event diff --git a/proto/src/proto/executor/v1/executor.proto b/proto/src/proto/executor/v1/executor.proto index ff92f6776e..dc43c4fab6 100644 --- a/proto/src/proto/executor/v1/executor.proto +++ b/proto/src/proto/executor/v1/executor.proto @@ -854,4 +854,18 @@ 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; + // 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/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, diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index e11e912243..c1421de489 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -2,6 +2,7 @@ package sequencer import ( "context" + "encoding/json" "errors" "fmt" "math/big" @@ -283,6 +284,7 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { continue } + closeWIPBatch := false metrics.WorkerProcessingTime(time.Since(start)) if tx != nil { showNotFoundTxLog = true @@ -290,7 +292,8 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { firstTxProcess := true for { - _, err := f.processTransaction(ctx, tx, firstTxProcess) + var err error + _, closeWIPBatch, err = f.processTransaction(ctx, tx, firstTxProcess) if err != nil { if err == ErrEffectiveGasPriceReprocess { firstTxProcess = false @@ -325,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 = "Executor close batch" + } f.finalizeWIPBatch(ctx, closeReason) } @@ -337,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, closeWIPBatch bool, err error) { start := time.Now() defer func() { metrics.ProcessingTime(time.Since(start)) @@ -380,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, 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) @@ -408,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, 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) @@ -428,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, false, err } batchRequest.Transactions = append(batchRequest.Transactions, effectivePercentageAsDecodedHex...) @@ -437,12 +444,34 @@ 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, 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) } 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) @@ -454,14 +483,15 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first } else { metrics.TxProcessed(metrics.TxProcessedLabelInvalid, 1) } - return nil, err + return nil, false, err } + closeBatch := false oldStateRoot := f.wipBatch.imStateRoot if len(batchResponse.BlockResponses) > 0 { - errWg, err = f.handleProcessTransactionResponse(ctx, tx, batchResponse, oldStateRoot) + errWg, closeBatch, err = f.handleProcessTransactionResponse(ctx, tx, batchResponse, oldStateRoot) if err != nil { - return errWg, err + return errWg, false, err } } @@ -471,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, 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) { +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 + return errWg, false, result.BlockResponses[0].TransactionResponses[0].RomError } egpEnabled := f.effectiveGasPrice.IsEnabled() @@ -496,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, 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) @@ -521,7 +551,7 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx } if errCompare != nil && egpEnabled { - return nil, errCompare + return nil, false, errCompare } } } @@ -557,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, 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 + return nil, false, ErrBatchResourceUnderFlow } } @@ -583,7 +613,11 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx f.updateWorkerAfterSuccessfulProcessing(ctx, tx.Hash, tx.From, false, result) - return nil, nil + if result.CloseBatch_V2 { + return nil, true, nil + } + + return nil, false, nil } // compareTxEffectiveGasPrice compares newEffectiveGasPrice with tx.EffectiveGasPrice. 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/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..ace96ea969 100644 --- a/state/runtime/executor/errors.go +++ b/state/runtime/executor/errors.go @@ -446,6 +446,20 @@ 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 + case ExecutorError_EXECUTOR_ERROR_OOG_2: + return runtime.ErrExecutorErrorOOG2 + case ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH: + return runtime.ErrExecutorErrorCloseBatch } return ErrExecutorUnknown } @@ -678,6 +692,20 @@ 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 + 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 0215584aac..2b94c5c0e0 100644 --- a/state/runtime/executor/executor.pb.go +++ b/state/runtime/executor/executor.pb.go @@ -430,6 +430,20 @@ 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 + // 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. @@ -548,6 +562,13 @@ 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", + 118: "EXECUTOR_ERROR_OOG_2", + 119: "EXECUTOR_ERROR_CLOSE_BATCH", } ExecutorError_value = map[string]int32{ "EXECUTOR_ERROR_UNSPECIFIED": 0, @@ -663,6 +684,13 @@ 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, + "EXECUTOR_ERROR_OOG_2": 118, + "EXECUTOR_ERROR_CLOSE_BATCH": 119, } ) @@ -4813,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, 0x9d, 0x2a, + 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, @@ -5151,29 +5179,45 @@ 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, + 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, 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, - 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, + 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..63e446746e 100644 --- a/state/runtime/runtime.go +++ b/state/runtime/runtime.go @@ -311,6 +311,20 @@ 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") + // ErrExecutorErrorOOG2 indicates that an out of gas has occurred + ErrExecutorErrorOOG2 = errors.New("out of gas 2") + // ErrExecutorErrorCloseBatch indicates that batch must be closed + ErrExecutorErrorCloseBatch = errors.New("close batch") // 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/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 diff --git a/test/contracts/auto/customModExp.sol b/test/contracts/auto/customModExp.sol new file mode 100644 index 0000000000..b1926aa4f0 --- /dev/null +++ b/test/contracts/auto/customModExp.sol @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT +pragma solidity >=0.7.0 <0.9.0; + +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/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 eb3ae9b1be37a0defbacb22c9d16f86943460551 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 15:21:22 +0100 Subject: [PATCH 02/51] fix RPC closebatch executor error (#3272) * fix RPC closebatch executor error * fix close batch * fix close batch * fix close batch * fix close batch * fix close batch --------- Co-authored-by: agnusmor --- sequencer/batch.go | 4 +++- sequencer/finalizer_test.go | 3 +++ sequencer/l2block.go | 10 ++++++---- state/batchV2.go | 2 +- state/trace.go | 2 +- state/transaction.go | 4 ++-- 6 files changed, 16 insertions(+), 9 deletions(-) diff --git a/sequencer/batch.go b/sequencer/batch.go index 6643ed15ee..53845886e9 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -3,6 +3,7 @@ package sequencer import ( "context" "encoding/json" + "errors" "fmt" "time" @@ -11,6 +12,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" + "github.com/0xPolygonHermez/zkevm-node/state/runtime" "github.com/ethereum/go-ethereum/common" ) @@ -404,7 +406,7 @@ func (f *finalizer) batchSanityCheck(ctx context.Context, batchNum uint64, initi return nil, ErrProcessBatch } - if batchResponse.ExecutorError != nil { + if batchResponse.ExecutorError != nil && !errors.Is(batchResponse.ExecutorError, runtime.ErrExecutorErrorCloseBatch) { log.Errorf("executor error when reprocessing batch %d, error: %v", batch.BatchNumber, batchResponse.ExecutorError) reprocessError(batch) return nil, ErrExecutorError diff --git a/sequencer/finalizer_test.go b/sequencer/finalizer_test.go index 7c33c2f54e..6aa201fd29 100644 --- a/sequencer/finalizer_test.go +++ b/sequencer/finalizer_test.go @@ -945,6 +945,9 @@ func TestNewFinalizer(t *testing.T) { func TestFinalizer_closeWIPBatch(t *testing.T) { // arrange f = setupFinalizer(true) + // set wip batch has at least one L2 block as it can not be closed empty + f.wipBatch.countOfL2Blocks++ + usedResources := getUsedBatchResources(f.batchConstraints, f.wipBatch.imRemainingResources) receipt := state.ProcessingReceipt{ diff --git a/sequencer/l2block.go b/sequencer/l2block.go index 63dbabf3d1..c2a4a52a7e 100644 --- a/sequencer/l2block.go +++ b/sequencer/l2block.go @@ -2,6 +2,7 @@ package sequencer import ( "context" + "errors" "fmt" "time" @@ -11,6 +12,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" + "github.com/0xPolygonHermez/zkevm-node/state/runtime" "github.com/ethereum/go-ethereum/common" ) @@ -279,13 +281,13 @@ func (f *finalizer) executeL2Block(ctx context.Context, initialStateRoot common. return nil, 0, err } - if batchResponse.ExecutorError != nil { - executeL2BLockError(err) + if batchResponse.ExecutorError != nil && !errors.Is(batchResponse.ExecutorError, runtime.ErrExecutorErrorCloseBatch) { + executeL2BLockError(batchResponse.ExecutorError) return nil, 0, ErrExecutorError } if batchResponse.IsRomOOCError { - executeL2BLockError(err) + executeL2BLockError(batchResponse.RomError_V2) return nil, 0, ErrProcessBatchOOC } @@ -557,7 +559,7 @@ func (f *finalizer) executeNewWIPL2Block(ctx context.Context) (*state.ProcessBat return nil, err } - if batchResponse.ExecutorError != nil { + if batchResponse.ExecutorError != nil && !errors.Is(batchResponse.ExecutorError, runtime.ErrExecutorErrorCloseBatch) { return nil, ErrExecutorError } diff --git a/state/batchV2.go b/state/batchV2.go index 9f26e612f6..f10b0ddef7 100644 --- a/state/batchV2.go +++ b/state/batchV2.go @@ -299,7 +299,7 @@ func (s *State) sendBatchRequestToExecutorV2(ctx context.Context, batchRequest * log.Errorf("error executor ProcessBatchV2 response: %v", batchResponse) } else { batchResponseToString := processBatchResponseToString(newBatchNum, batchResponse, elapsed) - if batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR { + if batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { err = executor.ExecutorErr(batchResponse.Error) log.Warnf("executor batch %d response, executor error: %v", newBatchNum, err) log.Warn(batchResponseToString) diff --git a/state/trace.go b/state/trace.go index c227ad85c0..13c66a6aa7 100644 --- a/state/trace.go +++ b/state/trace.go @@ -225,7 +225,7 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has endTime = time.Now() if err != nil { return nil, err - } else if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR { + } else if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { err = executor.ExecutorErr(processBatchResponseV2.Error) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2) return nil, err diff --git a/state/transaction.go b/state/transaction.go index c2011c8e30..781be79e21 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -580,7 +580,7 @@ func (s *State) internalProcessUnsignedTransactionV2(ctx context.Context, tx *ty } } - if err == nil && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR { + if err == nil && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { err = executor.ExecutorErr(processBatchResponseV2.Error) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2) return nil, err @@ -1014,7 +1014,7 @@ func (s *State) internalTestGasEstimationTransactionV2(ctx context.Context, batc log.Errorf("error estimating gas: %v", err) return false, false, gasUsed, nil, err } - if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR { + if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { err = executor.ExecutorErr(processBatchResponseV2.Error) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2) return false, false, gasUsed, nil, err From 2d76f1293106960b8de2f05cbf53ba39d9e5921f Mon Sep 17 00:00:00 2001 From: Joan Esteban <129153821+joanestebanr@users.noreply.github.com> Date: Wed, 14 Feb 2024 21:41:17 +0100 Subject: [PATCH 03/51] fix executor error closebatch (#3276) * fix executor error closebatch * fix linter --------- Co-authored-by: agnusmor --- state/batchV2.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/state/batchV2.go b/state/batchV2.go index f10b0ddef7..caa01c58cf 100644 --- a/state/batchV2.go +++ b/state/batchV2.go @@ -165,7 +165,7 @@ func (s *State) ExecuteBatchV2(ctx context.Context, batch Batch, L1InfoTreeRoot if err != nil { log.Error("error executing batch: ", err) return nil, err - } else if processBatchResponse != nil && processBatchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR { + } else if processBatchResponse != nil && processBatchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && processBatchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { err = executor.ExecutorErr(processBatchResponse.Error) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponse.Error, processBatchRequest) } From 20fa91fdb1382d43172800b554b6e491f72cc8a2 Mon Sep 17 00:00:00 2001 From: Thiago Coimbra Lemos Date: Wed, 14 Feb 2024 18:52:30 -0300 Subject: [PATCH 04/51] add oog2 checks for all the oog cheks (#3277) --- jsonrpc/endpoints_eth.go | 2 +- pool/pool.go | 4 ++-- state/trace.go | 2 +- state/transaction.go | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/jsonrpc/endpoints_eth.go b/jsonrpc/endpoints_eth.go index 4d9ffe0270..e999a0facf 100644 --- a/jsonrpc/endpoints_eth.go +++ b/jsonrpc/endpoints_eth.go @@ -106,7 +106,7 @@ func (e *EthEndpoints) Call(arg *types.TxArgs, blockArg *types.BlockNumberOrHash result, err := e.state.ProcessUnsignedTransaction(ctx, tx, sender, blockToProcess, true, dbTx) if err != nil { errMsg := fmt.Sprintf("failed to execute the unsigned transaction: %v", err.Error()) - logError := !executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) && !errors.Is(err, runtime.ErrOutOfGas) + logError := !executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) && !(errors.Is(err, runtime.ErrOutOfGas) || errors.Is(err, runtime.ErrExecutorErrorOOG2)) return RPCErrorResponse(types.DefaultErrorCode, errMsg, nil, logError) } diff --git a/pool/pool.go b/pool/pool.go index 6f67982665..ed0e9ace21 100644 --- a/pool/pool.go +++ b/pool/pool.go @@ -298,7 +298,7 @@ func (p *Pool) preExecuteTx(ctx context.Context, tx types.Transaction) (preExecu processBatchResponse, err := p.state.PreProcessTransaction(ctx, &tx, nil) if err != nil { isOOC := executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) - isOOG := errors.Is(err, runtime.ErrOutOfGas) + isOOG := errors.Is(err, runtime.ErrOutOfGas) || errors.Is(err, runtime.ErrExecutorErrorOOG2) if !isOOC && !isOOG { return response, err } else { @@ -324,7 +324,7 @@ func (p *Pool) preExecuteTx(ctx context.Context, tx types.Transaction) (preExecu if executor.IsROMOutOfCountersError(executor.RomErrorCode(errorToCheck)) { response.OOCError = err } - if errors.Is(errorToCheck, runtime.ErrOutOfGas) { + if errors.Is(errorToCheck, runtime.ErrOutOfGas) || errors.Is(errorToCheck, runtime.ErrExecutorErrorOOG2) { response.OOGError = err } } else { diff --git a/state/trace.go b/state/trace.go index 13c66a6aa7..387e95543b 100644 --- a/state/trace.go +++ b/state/trace.go @@ -495,7 +495,7 @@ func (s *State) buildTrace(evm *fakevm.FakeEVM, result *runtime.ExecutionResult, if previousStep.Depth > step.Depth && previousStep.OpCode != "REVERT" { var gasUsed uint64 var err error - if errors.Is(previousStep.Error, runtime.ErrOutOfGas) { + if errors.Is(previousStep.Error, runtime.ErrOutOfGas) || errors.Is(previousStep.Error, runtime.ErrExecutorErrorOOG2) { itCtx, err := internalTxSteps.Pop() if err != nil { return nil, err diff --git a/state/transaction.go b/state/transaction.go index 781be79e21..ae7fca748a 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -1060,7 +1060,7 @@ func isGasApplyError(err error) bool { // Checks if EVM level valid gas errors occurred func isGasEVMError(err error) bool { - return errors.Is(err, runtime.ErrOutOfGas) + return errors.Is(err, runtime.ErrOutOfGas) || errors.Is(err, runtime.ErrExecutorErrorOOG2) } // Checks if the EVM reverted during execution From f968d8bf2f922c1969e435d38ce638c8ecf874a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Fri, 16 Feb 2024 13:09:26 +0100 Subject: [PATCH 05/51] fix oog2 in internal gas estimation (#3280) * fix oog2 * fix oog2 for estimateGas --------- Co-authored-by: tclemos --- state/transaction.go | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/state/transaction.go b/state/transaction.go index ae7fca748a..ba5ed64f88 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -1010,11 +1010,16 @@ func (s *State) internalTestGasEstimationTransactionV2(ctx context.Context, batc txExecutionOnExecutorTime := time.Now() processBatchResponseV2, err := s.executorClient.ProcessBatchV2(ctx, processBatchRequestV2) log.Debugf("executor time: %vms", time.Since(txExecutionOnExecutorTime).Milliseconds()) - if err != nil { + if err != nil && !errors.Is(err, runtime.ErrExecutorErrorOOG2) { log.Errorf("error estimating gas: %v", err) return false, false, gasUsed, nil, err } - if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { + if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && + processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { + if processBatchResponseV2.Error == executor.ExecutorError_EXECUTOR_ERROR_OOG_2 { + return true, false, gasUsed, nil, nil + } + err = executor.ExecutorErr(processBatchResponseV2.Error) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2) return false, false, gasUsed, nil, err @@ -1060,7 +1065,7 @@ func isGasApplyError(err error) bool { // Checks if EVM level valid gas errors occurred func isGasEVMError(err error) bool { - return errors.Is(err, runtime.ErrOutOfGas) || errors.Is(err, runtime.ErrExecutorErrorOOG2) + return errors.Is(err, runtime.ErrOutOfGas) } // Checks if the EVM reverted during execution From ca5a2c2e2257799571e9c1b38619ef6636974836 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Fri, 16 Feb 2024 14:36:30 +0100 Subject: [PATCH 06/51] execution mode (#3285) * execution mode * execution mode * execution mode --- proto/src/proto/executor/v1/executor.proto | 1 + sequencer/batch.go | 2 + sequencer/finalizer.go | 1 + sequencer/forcedbatch.go | 2 + sequencer/l2block.go | 3 + state/batchV2.go | 4 + state/runtime/executor/client.go | 7 + state/runtime/executor/executor.pb.go | 1537 +++++++++-------- state/trace.go | 1 + state/transaction.go | 2 + state/types.go | 1 + .../etrog/processor_l1_sequence_batches.go | 3 + .../processor_l1_update_etrog_sequence.go | 2 + .../executor_trusted_batch_sync.go | 2 + .../l2_sync_incaberry/sync_trusted_state.go | 1 + 15 files changed, 806 insertions(+), 763 deletions(-) diff --git a/proto/src/proto/executor/v1/executor.proto b/proto/src/proto/executor/v1/executor.proto index dc43c4fab6..b260ec1c6f 100644 --- a/proto/src/proto/executor/v1/executor.proto +++ b/proto/src/proto/executor/v1/executor.proto @@ -292,6 +292,7 @@ message ProcessBatchRequestV2 { // prior to executing the call. map state_override = 23; DebugV2 debug = 24; + uint64 execution_mode = 25; } message L1DataV2 { diff --git a/sequencer/batch.go b/sequencer/batch.go index 53845886e9..0884cbfffd 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -13,6 +13,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" "github.com/0xPolygonHermez/zkevm-node/state/runtime" + "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/ethereum/go-ethereum/common" ) @@ -386,6 +387,7 @@ func (f *finalizer) batchSanityCheck(ctx context.Context, batchNum uint64, initi ForkID: f.stateIntf.GetForkIDByBatchNumber(batch.BatchNumber), SkipVerifyL1InfoRoot_V2: true, Caller: caller, + ExecutionMode: executor.ExecutionMode0, } batchRequest.L1InfoTreeData_V2, _, _, err = f.stateIntf.GetL1InfoTreeDataFromBatchL2Data(ctx, batch.BatchL2Data, nil) if err != nil { diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index c1421de489..7f400b9f4c 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -366,6 +366,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first SkipWriteBlockInfoRoot_V2: true, SkipVerifyL1InfoRoot_V2: true, L1InfoTreeData_V2: map[uint32]state.L1DataV2{}, + ExecutionMode: executor.ExecutionMode0, } txGasPrice := tx.GasPrice diff --git a/sequencer/forcedbatch.go b/sequencer/forcedbatch.go index 16fd40e564..4f035ec708 100644 --- a/sequencer/forcedbatch.go +++ b/sequencer/forcedbatch.go @@ -8,6 +8,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" + "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/ethereum/go-ethereum/common" "github.com/jackc/pgx/v4" ) @@ -105,6 +106,7 @@ func (f *finalizer) processForcedBatch(ctx context.Context, forcedBatch state.Fo ForkID: f.stateIntf.GetForkIDByBatchNumber(lastBatchNumber), SkipVerifyL1InfoRoot_V2: true, Caller: stateMetrics.SequencerCallerLabel, + ExecutionMode: executor.ExecutionMode0, } batchResponse, err := f.stateIntf.ProcessBatchV2(ctx, batchRequest, true) diff --git a/sequencer/l2block.go b/sequencer/l2block.go index c2a4a52a7e..7fd7877c03 100644 --- a/sequencer/l2block.go +++ b/sequencer/l2block.go @@ -13,6 +13,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" "github.com/0xPolygonHermez/zkevm-node/state/runtime" + "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/ethereum/go-ethereum/common" ) @@ -262,6 +263,7 @@ func (f *finalizer) executeL2Block(ctx context.Context, initialStateRoot common. ForkID: f.stateIntf.GetForkIDByBatchNumber(f.wipBatch.batchNumber), SkipVerifyL1InfoRoot_V2: true, L1InfoTreeData_V2: map[uint32]state.L1DataV2{}, + ExecutionMode: executor.ExecutionMode0, } batchRequest.L1InfoTreeData_V2[l2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{ GlobalExitRoot: l2Block.l1InfoTreeExitRoot.GlobalExitRoot.GlobalExitRoot, @@ -545,6 +547,7 @@ func (f *finalizer) executeNewWIPL2Block(ctx context.Context) (*state.ProcessBat SkipFirstChangeL2Block_V2: false, Transactions: f.stateIntf.BuildChangeL2Block(f.wipL2Block.deltaTimestamp, f.wipL2Block.getL1InfoTreeIndex()), L1InfoTreeData_V2: map[uint32]state.L1DataV2{}, + ExecutionMode: executor.ExecutionMode0, } batchRequest.L1InfoTreeData_V2[f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{ diff --git a/state/batchV2.go b/state/batchV2.go index caa01c58cf..01d371f397 100644 --- a/state/batchV2.go +++ b/state/batchV2.go @@ -33,6 +33,7 @@ type ProcessingContextV2 struct { ForcedBlockHashL1 *common.Hash SkipVerifyL1InfoRoot uint32 GlobalExitRoot common.Hash // GlobalExitRoot is not use for execute but use to OpenBatch (data on DB) + ExecutionMode uint64 } // ProcessBatchV2 processes a batch for forkID >= ETROG @@ -67,6 +68,7 @@ func (s *State) ProcessBatchV2(ctx context.Context, request ProcessRequest, upda ChainId: s.cfg.ChainID, ForkId: request.ForkID, ContextId: uuid.NewString(), + ExecutionMode: request.ExecutionMode, } if request.SkipFirstChangeL2Block_V2 { @@ -129,6 +131,7 @@ func (s *State) ExecuteBatchV2(ctx context.Context, batch Batch, L1InfoTreeRoot ForkId: forkId, ContextId: uuid.NewString(), SkipVerifyL1InfoRoot: skipVerifyL1InfoRoot, + ExecutionMode: executor.ExecutionMode1, } if forcedBlockHashL1 != nil { @@ -229,6 +232,7 @@ func (s *State) processBatchV2(ctx context.Context, processingCtx *ProcessingCon ContextId: uuid.NewString(), SkipVerifyL1InfoRoot: processingCtx.SkipVerifyL1InfoRoot, L1InfoRoot: processingCtx.L1InfoRoot.Bytes(), + ExecutionMode: processingCtx.ExecutionMode, } if processingCtx.ForcedBlockHashL1 != nil { diff --git a/state/runtime/executor/client.go b/state/runtime/executor/client.go index b386d4320f..40f39bfb50 100644 --- a/state/runtime/executor/client.go +++ b/state/runtime/executor/client.go @@ -10,6 +10,13 @@ import ( "google.golang.org/grpc/credentials/insecure" ) +const ( + // ExecutionMode0 is the execution mode for the sequencer and RPC, default one + ExecutionMode0 = uint64(0) + // ExecutionMode1 is the execution mode for the synchronizer + ExecutionMode1 = uint64(1) +) + // NewExecutorClient is the executor client constructor. func NewExecutorClient(ctx context.Context, c Config) (ExecutorServiceClient, *grpc.ClientConn, context.CancelFunc) { opts := []grpc.DialOption{ diff --git a/state/runtime/executor/executor.pb.go b/state/runtime/executor/executor.pb.go index 2b94c5c0e0..029c84186f 100644 --- a/state/runtime/executor/executor.pb.go +++ b/state/runtime/executor/executor.pb.go @@ -2236,6 +2236,7 @@ type ProcessBatchRequestV2 struct { // prior to executing the call. StateOverride map[string]*OverrideAccountV2 `protobuf:"bytes,23,rep,name=state_override,json=stateOverride,proto3" json:"state_override,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Debug *DebugV2 `protobuf:"bytes,24,opt,name=debug,proto3" json:"debug,omitempty"` + ExecutionMode uint64 `protobuf:"varint,25,opt,name=execution_mode,json=executionMode,proto3" json:"execution_mode,omitempty"` } func (x *ProcessBatchRequestV2) Reset() { @@ -2438,6 +2439,13 @@ func (x *ProcessBatchRequestV2) GetDebug() *DebugV2 { return nil } +func (x *ProcessBatchRequestV2) GetExecutionMode() uint64 { + if x != nil { + return x.ExecutionMode + } + return 0 +} + type L1DataV2 struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4354,7 +4362,7 @@ var file_executor_proto_rawDesc = []byte{ 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x48, 0x61, 0x73, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xd5, + 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xfc, 0x0b, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x32, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, @@ -4428,796 +4436,799 @@ var file_executor_proto_rawDesc = []byte{ 0x72, 0x79, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x62, 0x75, 0x67, 0x56, 0x32, 0x52, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x1a, 0x58, 0x0a, - 0x13, 0x4c, 0x31, 0x49, 0x6e, 0x66, 0x6f, 0x54, 0x72, 0x65, 0x65, 0x44, 0x61, 0x74, 0x61, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x31, 0x44, 0x61, 0x74, 0x61, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x35, 0x0a, 0x07, 0x44, 0x62, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x44, - 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x74, 0x65, 0x63, - 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x60, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x76, 0x65, - 0x72, 0x72, 0x69, 0x64, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x34, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, - 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9a, 0x01, 0x0a, 0x08, 0x4c, 0x31, 0x44, 0x61, 0x74, - 0x61, 0x56, 0x32, 0x12, 0x28, 0x0a, 0x10, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x78, - 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x67, - 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, - 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x31, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x4c, - 0x31, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, - 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x54, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x6d, 0x74, 0x5f, 0x70, 0x72, - 0x6f, 0x6f, 0x66, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x6d, 0x74, 0x50, 0x72, - 0x6f, 0x6f, 0x66, 0x22, 0xcc, 0x01, 0x0a, 0x07, 0x44, 0x65, 0x62, 0x75, 0x67, 0x56, 0x32, 0x12, - 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, - 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, - 0x6f, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x63, 0x63, 0x5f, 0x69, 0x6e, - 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, - 0x6e, 0x65, 0x77, 0x41, 0x63, 0x63, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, - 0x2d, 0x0a, 0x13, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x69, - 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6e, 0x65, - 0x77, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, - 0x0a, 0x0d, 0x6e, 0x65, 0x77, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x75, 0x6d, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4e, - 0x75, 0x6d, 0x22, 0x88, 0x09, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x24, 0x0a, - 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x6f, 0x6f, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x63, 0x63, 0x5f, 0x69, - 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0f, 0x6e, 0x65, 0x77, 0x41, 0x63, 0x63, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x48, 0x61, 0x73, 0x68, - 0x12, 0x2d, 0x0a, 0x13, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, - 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6e, - 0x65, 0x77, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, - 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x77, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x75, 0x6d, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x4e, 0x75, 0x6d, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x63, 0x63, 0x61, - 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, - 0x63, 0x6e, 0x74, 0x4b, 0x65, 0x63, 0x63, 0x61, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, - 0x2e, 0x0a, 0x13, 0x63, 0x6e, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x5f, - 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x63, 0x6e, - 0x74, 0x50, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, - 0x32, 0x0a, 0x15, 0x63, 0x6e, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x5f, - 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, - 0x63, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x50, 0x61, 0x64, 0x64, 0x69, - 0x6e, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6e, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x61, - 0x6c, 0x69, 0x67, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x6e, 0x74, - 0x4d, 0x65, 0x6d, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6e, 0x74, - 0x5f, 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x73, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0e, 0x63, 0x6e, 0x74, 0x41, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, - 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6e, 0x74, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x69, - 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6e, 0x74, 0x42, 0x69, 0x6e, - 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x65, - 0x70, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x6e, 0x74, 0x53, 0x74, 0x65, - 0x70, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6e, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x63, - 0x6e, 0x74, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x4c, - 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, - 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x52, 0x0e, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x65, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x6f, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x6d, - 0x0a, 0x14, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x72, 0x65, 0x61, 0x64, 0x57, - 0x72, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x19, 0x0a, - 0x08, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x07, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x72, - 0x65, 0x64, 0x5f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x64, - 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, - 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x6d, 0x74, 0x5f, - 0x6b, 0x65, 0x79, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x6d, 0x74, 0x4b, - 0x65, 0x79, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x5f, 0x6b, - 0x65, 0x79, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x67, 0x72, - 0x61, 0x6d, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x69, - 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, - 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, - 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, - 0x61, 0x74, 0x63, 0x68, 0x12, 0x32, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x6f, - 0x6d, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x08, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x6f, 0x6d, 0x1a, 0x63, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x64, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x32, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, - 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf3, 0x01, - 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, - 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x23, 0x0a, - 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x6d, 0x6f, - 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, 0x61, - 0x12, 0x41, 0x0a, 0x1e, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x5f, 0x67, - 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x74, 0x72, 0x61, - 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x19, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, - 0x54, 0x6f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, - 0x61, 0x63, 0x65, 0x22, 0xde, 0x02, 0x0a, 0x11, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, - 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x3f, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, - 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4c, - 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x18, 0x05, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, + 0x65, 0x62, 0x75, 0x67, 0x56, 0x32, 0x52, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x12, 0x25, 0x0a, + 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, + 0x19, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x4d, 0x6f, 0x64, 0x65, 0x1a, 0x58, 0x0a, 0x13, 0x4c, 0x31, 0x49, 0x6e, 0x66, 0x6f, 0x54, 0x72, + 0x65, 0x65, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x31, 0x44, 0x61, 0x74, + 0x61, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x35, + 0x0a, 0x07, 0x44, 0x62, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x44, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x73, 0x42, 0x79, 0x74, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x60, 0x0a, 0x12, 0x53, + 0x74, 0x61, 0x74, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x34, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x1a, 0x38, 0x0a, 0x0a, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x44, - 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0x41, 0x0a, 0x0f, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x61, 0x64, - 0x57, 0x72, 0x69, 0x74, 0x65, 0x56, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, - 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x80, 0x01, 0x0a, 0x0b, 0x46, 0x75, 0x6c, 0x6c, - 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, 0x32, 0x12, 0x3b, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, - 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x56, 0x32, 0x52, 0x07, 0x63, 0x6f, 0x6e, - 0x74, 0x65, 0x78, 0x74, 0x12, 0x34, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, - 0x70, 0x56, 0x32, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x22, 0x92, 0x03, 0x0a, 0x14, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, - 0x74, 0x56, 0x32, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, - 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, - 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, - 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x19, - 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, - 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x61, - 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, - 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, - 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, - 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6f, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, - 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, - 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, 0x78, 0x49, - 0x6e, 0x64, 0x65, 0x78, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, - 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, - 0xae, 0x04, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x74, 0x65, 0x70, 0x56, 0x32, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, - 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x70, 0x63, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x70, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, - 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x19, 0x0a, 0x08, - 0x67, 0x61, 0x73, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, - 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x73, 0x5f, 0x72, - 0x65, 0x66, 0x75, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x67, 0x61, 0x73, - 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, - 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, - 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6d, 0x65, - 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x73, - 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x6f, 0x72, - 0x79, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, - 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x65, - 0x6d, 0x6f, 0x72, 0x79, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, - 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x08, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, - 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, - 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, - 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x45, 0x0a, - 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, - 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, - 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x2e, 0x53, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x73, 0x74, 0x6f, - 0x72, 0x61, 0x67, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x22, 0x8e, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, 0x12, - 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6c, - 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, - 0x72, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, - 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x12, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x22, 0xe9, 0x03, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, - 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x1f, 0x0a, 0x0b, - 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, - 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, - 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, - 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, - 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, - 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, - 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x65, 0x72, 0x18, 0x06, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x67, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x31, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x31, 0x12, 0x19, 0x0a, - 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x6f, 0x6f, 0x74, - 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0a, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, - 0x47, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, - 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x52, 0x09, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, - 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, + 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9a, 0x01, + 0x0a, 0x08, 0x4c, 0x31, 0x44, 0x61, 0x74, 0x61, 0x56, 0x32, 0x12, 0x28, 0x0a, 0x10, 0x67, 0x6c, + 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, + 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x5f, 0x6c, 0x31, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x31, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0c, 0x6d, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1b, 0x0a, + 0x09, 0x73, 0x6d, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x08, 0x73, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xcc, 0x01, 0x0a, 0x07, 0x44, + 0x65, 0x62, 0x75, 0x67, 0x56, 0x32, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, + 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, + 0x6d, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, 0x77, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x77, + 0x5f, 0x61, 0x63, 0x63, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x6e, 0x65, 0x77, 0x41, 0x63, 0x63, 0x49, 0x6e, 0x70, + 0x75, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2d, 0x0a, 0x13, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, + 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x78, 0x69, + 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x77, 0x5f, 0x62, 0x61, 0x74, + 0x63, 0x68, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, + 0x77, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4e, 0x75, 0x6d, 0x22, 0x88, 0x09, 0x0a, 0x16, 0x50, 0x72, + 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x56, 0x32, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, + 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, + 0x77, 0x5f, 0x61, 0x63, 0x63, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x6e, 0x65, 0x77, 0x41, 0x63, 0x63, 0x49, 0x6e, + 0x70, 0x75, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2d, 0x0a, 0x13, 0x6e, 0x65, 0x77, 0x5f, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x78, + 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x77, 0x5f, 0x62, 0x61, + 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, + 0x65, 0x77, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4e, 0x75, 0x6d, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6e, + 0x74, 0x5f, 0x6b, 0x65, 0x63, 0x63, 0x61, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x63, 0x6e, 0x74, 0x4b, 0x65, 0x63, 0x63, 0x61, 0x6b, + 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x6e, 0x74, 0x5f, 0x70, 0x6f, + 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x11, 0x63, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, + 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x6e, 0x74, 0x5f, 0x70, 0x6f, + 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x63, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x65, 0x69, 0x64, + 0x6f, 0x6e, 0x50, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6e, + 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x73, + 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, + 0x69, 0x63, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x63, 0x6e, 0x74, 0x41, 0x72, + 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6e, 0x74, + 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0b, 0x63, 0x6e, 0x74, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, + 0x63, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x08, 0x63, 0x6e, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6e, 0x74, + 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x63, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, + 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, + 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x56, 0x32, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x6d, 0x0a, 0x14, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x77, 0x72, + 0x69, 0x74, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x0f, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, + 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x12, 0x72, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x64, + 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x64, 0x12, + 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, + 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, + 0x46, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x65, + 0x72, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, + 0x65, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, + 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, + 0x19, 0x0a, 0x08, 0x73, 0x6d, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, + 0x0c, 0x52, 0x07, 0x73, 0x6d, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, + 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0c, + 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x17, 0x0a, + 0x07, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, + 0x66, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, + 0x64, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x69, + 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x32, 0x0a, 0x09, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x6d, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, + 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x6f, 0x6d, 0x1a, + 0x63, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x32, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, + 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf3, 0x01, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, + 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, + 0x74, 0x61, 0x63, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, + 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6e, 0x61, + 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, + 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x1e, 0x74, 0x78, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x66, + 0x75, 0x6c, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x19, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x22, 0xde, 0x02, 0x0a, 0x11, 0x4f, + 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, + 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, + 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, + 0x63, 0x6f, 0x64, 0x65, 0x12, 0x3f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, + 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x64, + 0x69, 0x66, 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, + 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x44, + 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x44, + 0x69, 0x66, 0x66, 0x1a, 0x38, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, + 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, + 0x0e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, + 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, + 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x41, 0x0a, 0x0f, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x56, 0x32, 0x12, 0x14, + 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, + 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x80, + 0x01, 0x0a, 0x0b, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, 0x32, 0x12, 0x3b, + 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x21, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, + 0x56, 0x32, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x34, 0x0a, 0x05, 0x73, + 0x74, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, + 0x73, 0x22, 0x92, 0x03, 0x0a, 0x14, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, + 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x56, 0x32, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, + 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, + 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, + 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, + 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, + 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, + 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, + 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x25, 0x0a, + 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, + 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, + 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6f, 0x6c, + 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, + 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x19, 0x0a, 0x08, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x63, + 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0xae, 0x04, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x12, 0x1d, 0x0a, 0x0a, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, + 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x70, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x70, + 0x63, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, + 0x67, 0x61, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x12, 0x1d, + 0x0a, 0x0a, 0x67, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x09, 0x67, 0x61, 0x73, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x12, 0x0e, 0x0a, + 0x02, 0x6f, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x14, 0x0a, + 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, + 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x23, 0x0a, 0x0d, + 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x0b, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4f, 0x66, 0x66, 0x73, 0x65, + 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, + 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, + 0x74, 0x61, 0x12, 0x33, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x0d, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, 0x52, 0x08, 0x63, + 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x12, 0x45, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, + 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, + 0x74, 0x65, 0x70, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x53, + 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8e, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, + 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, + 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, + 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x03, 0x67, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xe9, 0x03, 0x0a, 0x16, 0x50, 0x72, 0x6f, + 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x56, 0x32, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, + 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x21, 0x0a, + 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x10, + 0x0a, 0x03, 0x67, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x67, 0x65, 0x72, + 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, + 0x31, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, + 0x73, 0x68, 0x4c, 0x31, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, + 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, + 0x26, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x72, 0x6f, + 0x6f, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x49, + 0x6e, 0x66, 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x47, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, + 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x56, 0x32, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, + 0x26, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x56, + 0x32, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, + 0x72, 0x72, 0x6f, 0x72, 0x22, 0x83, 0x06, 0x0a, 0x1c, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, + 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, + 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x32, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x32, 0x12, 0x15, 0x0a, 0x06, + 0x72, 0x6c, 0x70, 0x5f, 0x74, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x6c, + 0x70, 0x54, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, + 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, + 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x19, 0x0a, 0x08, + 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x65, 0x66, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, + 0x67, 0x61, 0x73, 0x4c, 0x65, 0x66, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, + 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, + 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, + 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x11, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x47, 0x61, 0x73, 0x55, 0x73, + 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, + 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x67, 0x61, 0x73, 0x52, 0x65, 0x66, + 0x75, 0x6e, 0x64, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0c, + 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, + 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, + 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, + 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x56, 0x32, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, - 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, - 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, - 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x83, 0x06, - 0x0a, 0x1c, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x17, - 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x68, 0x61, - 0x73, 0x68, 0x5f, 0x6c, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x48, - 0x61, 0x73, 0x68, 0x4c, 0x32, 0x12, 0x15, 0x0a, 0x06, 0x72, 0x6c, 0x70, 0x5f, 0x74, 0x78, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x6c, 0x70, 0x54, 0x78, 0x12, 0x1d, 0x0a, 0x0a, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, - 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, - 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x76, 0x61, 0x6c, - 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, - 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x65, 0x66, - 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x4c, 0x65, 0x66, 0x74, - 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x63, - 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, - 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, - 0x74, 0x69, 0x76, 0x65, 0x47, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x67, - 0x61, 0x73, 0x5f, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x0b, 0x67, 0x61, 0x73, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x12, 0x2b, - 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, - 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, - 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0d, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, - 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, - 0x74, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x12, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, - 0x67, 0x56, 0x32, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x37, 0x0a, 0x0a, 0x66, 0x75, 0x6c, - 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, - 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x75, 0x6c, 0x6c, - 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, 0x32, 0x52, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, - 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, - 0x63, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, - 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x65, 0x72, 0x63, 0x65, - 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x73, - 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x13, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x11, 0x68, 0x61, 0x73, 0x47, 0x61, 0x73, 0x70, 0x72, 0x69, 0x63, 0x65, 0x4f, - 0x70, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x68, 0x61, 0x73, 0x5f, 0x62, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x10, 0x68, 0x61, 0x73, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x70, 0x63, - 0x6f, 0x64, 0x65, 0x22, 0xf7, 0x01, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x56, 0x32, 0x12, 0x18, 0x0a, - 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, - 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x12, - 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, - 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, - 0x1c, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x32, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x32, 0x12, 0x19, 0x0a, - 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2a, 0xbd, 0x0a, - 0x0a, 0x08, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, - 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, - 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x18, 0x0a, - 0x14, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, - 0x46, 0x5f, 0x47, 0x41, 0x53, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, - 0x4c, 0x4f, 0x57, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x52, 0x46, 0x4c, - 0x4f, 0x57, 0x10, 0x04, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, - 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x05, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, - 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, - 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x49, 0x53, 0x49, - 0x4f, 0x4e, 0x10, 0x06, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x56, 0x45, - 0x52, 0x54, 0x45, 0x44, 0x10, 0x07, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, - 0x45, 0x52, 0x53, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x10, 0x08, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, - 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, - 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x10, 0x09, - 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, - 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x42, 0x49, - 0x4e, 0x41, 0x52, 0x59, 0x10, 0x0a, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, - 0x45, 0x52, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x4f, 0x4d, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, - 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x10, 0x0c, 0x12, 0x25, - 0x0a, 0x21, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, - 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x50, 0x41, 0x44, 0x44, - 0x49, 0x4e, 0x47, 0x10, 0x0d, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, - 0x52, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x45, 0x49, 0x44, 0x4f, 0x4e, 0x10, 0x0e, 0x12, 0x21, 0x0a, + 0x12, 0x37, 0x0a, 0x0a, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x10, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, + 0x76, 0x31, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, 0x32, 0x52, 0x09, + 0x66, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, + 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, + 0x65, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x65, 0x66, 0x66, + 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, + 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x13, + 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x73, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x68, 0x61, 0x73, 0x47, 0x61, + 0x73, 0x70, 0x72, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x2c, 0x0a, 0x12, + 0x68, 0x61, 0x73, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x63, 0x6f, + 0x64, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x68, 0x61, 0x73, 0x42, 0x61, 0x6c, + 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x22, 0xf7, 0x01, 0x0a, 0x05, 0x4c, + 0x6f, 0x67, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, + 0x0a, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, + 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x17, 0x0a, + 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, + 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x5f, 0x6c, 0x32, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, + 0x73, 0x68, 0x4c, 0x32, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, + 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, + 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x08, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x14, + 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x2a, 0xbd, 0x0a, 0x0a, 0x08, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, + 0x72, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, + 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, + 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x47, 0x41, 0x53, 0x10, 0x02, 0x12, 0x1c, + 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x43, + 0x4b, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, + 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x5f, + 0x55, 0x4e, 0x44, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x04, 0x12, 0x24, 0x0a, 0x20, 0x52, + 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x43, 0x4f, 0x44, + 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, + 0x05, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, + 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, + 0x43, 0x4f, 0x4c, 0x4c, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x12, 0x20, 0x0a, 0x1c, 0x52, + 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x49, + 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x56, 0x45, 0x52, 0x54, 0x45, 0x44, 0x10, 0x07, 0x12, 0x22, 0x0a, + 0x1e, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, + 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x10, + 0x08, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, + 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4b, + 0x45, 0x43, 0x43, 0x41, 0x4b, 0x10, 0x09, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, + 0x54, 0x45, 0x52, 0x53, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x0a, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, - 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x53, 0x48, 0x41, 0x10, 0x0f, - 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4a, 0x55, 0x4d, 0x50, 0x10, 0x10, 0x12, 0x1c, 0x0a, 0x18, - 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, - 0x44, 0x5f, 0x4f, 0x50, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x11, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, - 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, - 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x12, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x59, - 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x53, 0x5f, 0x45, 0x46, - 0x10, 0x13, 0x12, 0x29, 0x0a, 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, - 0x44, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0x14, 0x12, 0x28, 0x0a, - 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, - 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x48, 0x41, - 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x10, 0x15, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x4f, 0x4d, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, - 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x16, 0x12, 0x29, - 0x0a, 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, - 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x47, 0x41, - 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x17, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x4f, 0x4d, + 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x10, 0x0b, + 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, + 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x41, 0x52, + 0x49, 0x54, 0x48, 0x10, 0x0c, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, + 0x52, 0x53, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x0d, 0x12, 0x26, 0x0a, 0x22, + 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, + 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x45, 0x49, 0x44, + 0x4f, 0x4e, 0x10, 0x0e, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, + 0x53, 0x5f, 0x53, 0x48, 0x41, 0x10, 0x0f, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x4f, 0x4d, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4a, 0x55, 0x4d, + 0x50, 0x10, 0x10, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4f, 0x50, 0x43, 0x4f, 0x44, 0x45, 0x10, + 0x11, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x12, 0x12, + 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, + 0x41, 0x52, 0x54, 0x53, 0x5f, 0x45, 0x46, 0x10, 0x13, 0x12, 0x29, 0x0a, 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, - 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, - 0x10, 0x18, 0x12, 0x2f, 0x0a, 0x2b, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, - 0x44, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, - 0x54, 0x10, 0x19, 0x12, 0x2b, 0x0a, 0x27, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x1a, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55, + 0x52, 0x45, 0x10, 0x14, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x10, 0x15, 0x12, 0x25, + 0x0a, 0x21, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, + 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, + 0x4e, 0x43, 0x45, 0x10, 0x16, 0x12, 0x29, 0x0a, 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x17, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, - 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x54, 0x58, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4f, - 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x1b, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x4f, 0x4d, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x44, 0x41, 0x54, - 0x41, 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x42, 0x49, 0x47, 0x10, 0x1c, 0x12, 0x21, 0x0a, 0x1d, 0x52, - 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, - 0x52, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x4b, 0x5f, 0x49, 0x44, 0x10, 0x1d, 0x12, 0x19, - 0x0a, 0x15, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x4c, 0x50, 0x10, 0x1e, 0x12, 0x2c, 0x0a, 0x28, 0x52, 0x4f, 0x4d, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, - 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, - 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x1f, 0x12, 0x32, 0x0a, 0x2e, 0x52, 0x4f, 0x4d, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x54, - 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x5f, 0x54, 0x58, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, - 0x5f, 0x4c, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x20, 0x12, 0x38, 0x0a, 0x34, 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, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, - 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, 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, - 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x44, - 0x42, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, + 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, + 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x18, 0x12, 0x2f, 0x0a, 0x2b, 0x52, 0x4f, 0x4d, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x47, + 0x41, 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x19, 0x12, 0x2b, 0x0a, 0x27, 0x52, 0x4f, + 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, + 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x45, 0x52, + 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x1a, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x4f, 0x4d, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x54, + 0x58, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x1b, + 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x42, 0x41, + 0x54, 0x43, 0x48, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x42, 0x49, 0x47, + 0x10, 0x1c, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x4b, + 0x5f, 0x49, 0x44, 0x10, 0x1d, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x4c, 0x50, 0x10, 0x1e, + 0x12, 0x2c, 0x0a, 0x28, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x48, 0x41, + 0x4e, 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x1f, 0x12, 0x32, + 0x0a, 0x2e, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x5f, 0x54, 0x58, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, + 0x10, 0x20, 0x12, 0x38, 0x0a, 0x34, 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, 0x4c, 0x49, 0x4d, 0x49, 0x54, + 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 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, 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, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x44, 0x42, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, + 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, + 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x45, + 0x50, 0x53, 0x10, 0x03, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, + 0x5f, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x10, 0x04, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, - 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x53, 0x10, 0x03, 0x12, 0x33, 0x0a, - 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, - 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, - 0x10, 0x04, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, - 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x42, - 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x05, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x05, 0x12, 0x30, + 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, + 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x4d, 0x45, 0x4d, 0x10, 0x06, + 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, + 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x41, 0x52, 0x49, + 0x54, 0x48, 0x10, 0x07, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, + 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x08, 0x12, 0x35, 0x0a, 0x31, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, + 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x50, 0x4f, 0x53, 0x45, 0x49, 0x44, 0x4f, 0x4e, 0x10, + 0x09, 0x12, 0x26, 0x0a, 0x22, 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, + 0x46, 0x4f, 0x52, 0x4b, 0x5f, 0x49, 0x44, 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x42, 0x41, 0x4c, 0x41, + 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x0b, 0x12, 0x1d, + 0x0a, 0x19, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x46, 0x45, 0x41, 0x32, 0x53, 0x43, 0x41, 0x4c, 0x41, 0x52, 0x10, 0x0c, 0x12, 0x18, 0x0a, + 0x14, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x54, 0x4f, 0x53, 0x33, 0x32, 0x10, 0x0d, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, - 0x4c, 0x4f, 0x57, 0x5f, 0x4d, 0x45, 0x4d, 0x10, 0x06, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, - 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x10, 0x07, 0x12, 0x34, 0x0a, - 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, - 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, - 0x47, 0x10, 0x08, 0x12, 0x35, 0x0a, 0x31, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, - 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, - 0x50, 0x4f, 0x53, 0x45, 0x49, 0x44, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x26, 0x0a, 0x22, 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, 0x46, 0x4f, 0x52, 0x4b, 0x5f, 0x49, 0x44, - 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x49, 0x53, - 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x0b, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x58, 0x45, 0x43, 0x55, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x46, 0x45, 0x41, 0x32, 0x53, 0x43, - 0x41, 0x4c, 0x41, 0x52, 0x10, 0x0c, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x54, 0x4f, 0x53, 0x33, 0x32, 0x10, 0x0d, - 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x5f, 0x54, 0x58, 0x10, 0x0e, - 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x10, 0x0f, - 0x12, 0x39, 0x0a, 0x35, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, - 0x5f, 0x45, 0x43, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x49, 0x56, 0x49, 0x44, - 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x10, 0x12, 0x2f, 0x0a, 0x2b, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4f, 0x55, - 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x11, 0x12, 0x2b, 0x0a, 0x27, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, - 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x12, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x13, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x10, 0x14, 0x12, 0x32, 0x0a, 0x2e, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x53, 0x49, 0x5a, 0x45, - 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x15, 0x12, - 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, - 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, - 0x45, 0x10, 0x16, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, - 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, - 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, - 0x4e, 0x47, 0x45, 0x10, 0x17, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, - 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x18, 0x12, - 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, - 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, - 0x54, 0x45, 0x44, 0x10, 0x19, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x50, 0x10, 0x1a, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x4e, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, + 0x45, 0x44, 0x5f, 0x54, 0x58, 0x10, 0x0e, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, - 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x1b, 0x12, 0x32, 0x0a, 0x2e, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, 0x4f, 0x53, 0x49, - 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x1c, 0x12, - 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, - 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, - 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, - 0x1d, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, - 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, - 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x1e, 0x12, 0x34, 0x0a, 0x30, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, - 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, - 0x1f, 0x12, 0x37, 0x0a, 0x33, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, - 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x4f, 0x55, 0x54, 0x5f, - 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x20, 0x12, 0x2a, 0x0a, 0x26, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x50, 0x4c, 0x45, 0x5f, 0x46, 0x52, - 0x45, 0x45, 0x49, 0x4e, 0x10, 0x21, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x10, 0x22, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x10, 0x23, 0x12, 0x30, 0x0a, 0x2c, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x52, - 0x45, 0x41, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x24, 0x12, 0x31, - 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, - 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, - 0x25, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, - 0x4b, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, - 0x10, 0x26, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x4e, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x53, 0x10, 0x0f, 0x12, 0x39, 0x0a, 0x35, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, + 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x45, 0x43, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, + 0x52, 0x5f, 0x44, 0x49, 0x56, 0x49, 0x44, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x5a, 0x45, 0x52, 0x4f, + 0x10, 0x10, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x44, 0x44, + 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, + 0x45, 0x10, 0x11, 0x12, 0x2b, 0x0a, 0x27, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x44, + 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x12, + 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, + 0x47, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x13, + 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, + 0x10, 0x14, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, - 0x48, 0x4b, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, - 0x54, 0x43, 0x48, 0x10, 0x27, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, - 0x54, 0x43, 0x48, 0x10, 0x28, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x4b, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, - 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x29, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, + 0x48, 0x4b, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, + 0x41, 0x4e, 0x47, 0x45, 0x10, 0x15, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x16, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x4c, 0x45, 0x4e, 0x5f, 0x43, 0x41, - 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x2a, 0x12, 0x30, 0x0a, 0x2c, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, + 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x17, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, - 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x2b, 0x12, 0x36, - 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, - 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, - 0x41, 0x54, 0x43, 0x48, 0x10, 0x2c, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, + 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x18, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, - 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x2d, 0x12, 0x2f, 0x0a, 0x2b, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x56, 0x41, 0x4c, 0x55, - 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x2e, 0x12, 0x31, 0x0a, 0x2d, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, + 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x19, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, 0x41, 0x44, - 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x2f, 0x12, - 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, - 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x30, 0x12, - 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x4c, - 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, - 0x43, 0x48, 0x10, 0x31, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, - 0x41, 0x53, 0x48, 0x50, 0x4c, 0x45, 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, - 0x57, 0x49, 0x43, 0x45, 0x10, 0x32, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x10, 0x1a, 0x12, 0x32, + 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x53, + 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, + 0x10, 0x1b, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, + 0x48, 0x50, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, + 0x54, 0x49, 0x56, 0x45, 0x10, 0x1c, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, - 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x33, 0x12, 0x33, - 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, - 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, - 0x45, 0x10, 0x34, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, - 0x49, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x35, 0x12, 0x33, - 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x45, - 0x43, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x36, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, - 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x37, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, - 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x53, 0x55, 0x42, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x38, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, - 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4c, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, - 0x10, 0x39, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, - 0x41, 0x52, 0x59, 0x5f, 0x53, 0x4c, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, - 0x10, 0x3a, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, - 0x41, 0x52, 0x59, 0x5f, 0x45, 0x51, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, - 0x3b, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, - 0x52, 0x59, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, - 0x3c, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, - 0x52, 0x59, 0x5f, 0x4f, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3d, - 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, - 0x59, 0x5f, 0x58, 0x4f, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3e, - 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, - 0x49, 0x47, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, - 0x43, 0x48, 0x10, 0x3f, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, - 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x38, 0x5f, 0x4d, - 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x40, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, + 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x1d, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, + 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, + 0x10, 0x1e, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, + 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, + 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x1f, 0x12, 0x37, 0x0a, 0x33, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x53, + 0x45, 0x54, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, + 0x20, 0x12, 0x2a, 0x0a, 0x26, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x55, 0x4c, 0x54, + 0x49, 0x50, 0x4c, 0x45, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x49, 0x4e, 0x10, 0x21, 0x12, 0x21, 0x0a, + 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x10, 0x22, + 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, + 0x59, 0x10, 0x23, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, + 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, + 0x54, 0x43, 0x48, 0x10, 0x24, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4d, 0x49, + 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x25, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x26, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x52, 0x45, 0x41, - 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x41, 0x12, 0x2c, 0x0a, 0x28, + 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, + 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x27, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4a, 0x4d, 0x50, 0x4e, 0x5f, 0x4f, 0x55, 0x54, 0x5f, - 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x42, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, - 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x43, 0x12, 0x32, - 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x52, - 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, - 0x10, 0x44, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4f, 0x4c, 0x44, - 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x45, 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, 0x4f, 0x4c, 0x44, 0x5f, 0x41, 0x43, 0x43, 0x5f, - 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x46, 0x12, 0x23, 0x0a, 0x1f, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, - 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x10, - 0x47, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x54, 0x43, - 0x48, 0x5f, 0x4c, 0x32, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x10, 0x48, 0x12, 0x2b, 0x0a, 0x27, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, - 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x49, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x49, 0x4e, 0x42, 0x41, 0x53, 0x45, 0x10, 0x4a, 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, 0x46, 0x52, 0x4f, 0x4d, 0x10, 0x4b, 0x12, 0x21, - 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x4b, 0x45, 0x59, 0x10, - 0x4c, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x56, - 0x41, 0x4c, 0x55, 0x45, 0x10, 0x4d, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, - 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, 0x53, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, - 0x4f, 0x44, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x4e, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, 0x53, 0x5f, 0x42, 0x59, - 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x4f, 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, 0x47, 0x45, 0x54, 0x5f, 0x4b, 0x45, 0x59, - 0x10, 0x50, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, - 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, - 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x51, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x10, 0x52, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, - 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x53, 0x12, 0x32, 0x0a, - 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x4f, - 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, - 0x54, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x53, 0x49, 0x5a, + 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x28, 0x12, 0x33, 0x0a, 0x2f, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x4c, 0x45, 0x4e, 0x5f, + 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, + 0x29, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, - 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, - 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, - 0x45, 0x10, 0x55, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x4b, 0x4c, 0x45, 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, + 0x45, 0x10, 0x2a, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, - 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, - 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x56, 0x12, 0x34, 0x0a, - 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, - 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, - 0x44, 0x10, 0x57, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, + 0x55, 0x4e, 0x44, 0x10, 0x2b, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, + 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x2c, 0x12, 0x33, 0x0a, + 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, + 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, + 0x10, 0x2d, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, + 0x48, 0x50, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, + 0x48, 0x10, 0x2e, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, - 0x53, 0x48, 0x53, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, - 0x43, 0x48, 0x10, 0x58, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, - 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, - 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x59, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x53, 0x48, 0x50, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, + 0x41, 0x54, 0x43, 0x48, 0x10, 0x2f, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, + 0x41, 0x54, 0x43, 0x48, 0x10, 0x30, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, + 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x31, 0x12, 0x30, 0x0a, 0x2c, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x4c, 0x45, 0x4e, 0x5f, 0x43, + 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x32, 0x12, 0x36, 0x0a, + 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, + 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, + 0x54, 0x43, 0x48, 0x10, 0x33, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, + 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x34, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, + 0x54, 0x43, 0x48, 0x10, 0x35, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x45, 0x43, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, + 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x36, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x41, 0x44, 0x44, 0x5f, + 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x37, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x53, 0x55, 0x42, 0x5f, + 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x38, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4c, 0x54, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x39, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, + 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x53, 0x4c, 0x54, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3a, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, + 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x45, 0x51, 0x5f, 0x4d, 0x49, + 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3b, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x49, + 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3c, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4f, 0x52, 0x5f, 0x4d, 0x49, 0x53, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3d, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, - 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5a, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x58, 0x4f, 0x52, 0x5f, 0x4d, 0x49, 0x53, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3e, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, - 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5b, 0x12, 0x30, 0x0a, 0x2c, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x4c, 0x45, 0x4e, 0x5f, - 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x5c, 0x12, 0x30, - 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, - 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x5d, - 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, + 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3f, 0x12, 0x33, 0x0a, 0x2f, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x57, + 0x52, 0x49, 0x54, 0x45, 0x38, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x40, + 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, + 0x49, 0x47, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, + 0x48, 0x10, 0x41, 0x12, 0x2c, 0x0a, 0x28, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4a, 0x4d, + 0x50, 0x4e, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, + 0x42, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, + 0x4b, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, + 0x4e, 0x47, 0x45, 0x10, 0x43, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, + 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x44, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x5f, 0x4f, 0x4c, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, + 0x4f, 0x54, 0x10, 0x45, 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, 0x4f, + 0x4c, 0x44, 0x5f, 0x41, 0x43, 0x43, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x48, 0x41, 0x53, + 0x48, 0x10, 0x46, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x48, + 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x10, 0x47, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4c, 0x32, 0x5f, 0x44, 0x41, 0x54, 0x41, + 0x10, 0x48, 0x12, 0x2b, 0x0a, 0x27, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x47, 0x4c, 0x4f, + 0x42, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x49, 0x12, + 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x49, 0x4e, 0x42, 0x41, + 0x53, 0x45, 0x10, 0x4a, 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, 0x46, + 0x52, 0x4f, 0x4d, 0x10, 0x4b, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, + 0x44, 0x42, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x4c, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, + 0x49, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x4d, 0x12, 0x31, 0x0a, + 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, + 0x53, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x4e, + 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, + 0x41, 0x43, 0x54, 0x53, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x56, 0x41, + 0x4c, 0x55, 0x45, 0x10, 0x4f, 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, + 0x47, 0x45, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x50, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, + 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, + 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x51, 0x12, 0x20, + 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x10, 0x52, + 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, - 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, - 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5e, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, + 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, + 0x47, 0x45, 0x10, 0x53, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, + 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, + 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x54, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, - 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, - 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x5f, 0x12, 0x32, 0x0a, - 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x52, 0x45, - 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, - 0x60, 0x12, 0x27, 0x0a, 0x23, 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, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x61, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, - 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x42, 0x4c, 0x4f, 0x43, - 0x4b, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x4c, 0x31, 0x10, 0x62, 0x12, 0x36, 0x0a, 0x32, 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, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x56, 0x32, 0x5f, - 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, - 0x10, 0x63, 0x12, 0x33, 0x0a, 0x2f, 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, - 0x44, 0x41, 0x54, 0x41, 0x5f, 0x56, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x48, 0x41, - 0x53, 0x48, 0x5f, 0x4c, 0x31, 0x10, 0x64, 0x12, 0x27, 0x0a, 0x23, 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, 0x53, 0x4d, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x10, 0x65, - 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, 0x42, 0x41, 0x4c, 0x41, 0x4e, - 0x43, 0x45, 0x10, 0x66, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, - 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4c, 0x54, 0x34, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, - 0x43, 0x48, 0x10, 0x67, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, - 0x45, 0x57, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x68, 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, 0x4e, 0x45, 0x57, 0x5f, 0x41, 0x43, - 0x43, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x69, 0x12, 0x2e, + 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, + 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x55, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, + 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, + 0x4e, 0x44, 0x10, 0x56, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, + 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, + 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x57, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, + 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x58, 0x12, 0x31, 0x0a, 0x2d, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x41, 0x44, 0x44, + 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x59, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x4c, 0x4f, 0x43, - 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x6a, 0x12, 0x23, - 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x44, 0x42, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, - 0x44, 0x10, 0x6b, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x54, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, - 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x10, 0x6c, 0x12, 0x24, 0x0a, - 0x20, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x44, 0x42, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x10, 0x6d, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x41, - 0x47, 0x45, 0x52, 0x10, 0x6e, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x53, + 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5a, 0x12, 0x33, + 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x4c, 0x45, + 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, + 0x48, 0x10, 0x5b, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, + 0x53, 0x48, 0x53, 0x4c, 0x45, 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, + 0x49, 0x43, 0x45, 0x10, 0x5c, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, + 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x5d, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, + 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, + 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5e, 0x12, + 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, + 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, + 0x43, 0x45, 0x10, 0x5f, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, + 0x41, 0x53, 0x48, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, + 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x60, 0x12, 0x27, 0x0a, 0x23, 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, 0x52, 0x4f, 0x4f, 0x54, 0x10, + 0x61, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x43, + 0x45, 0x44, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x4c, 0x31, 0x10, + 0x62, 0x12, 0x36, 0x0a, 0x32, 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, 0x44, + 0x41, 0x54, 0x41, 0x5f, 0x56, 0x32, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x45, 0x58, + 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x63, 0x12, 0x33, 0x0a, 0x2f, 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, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x56, 0x32, 0x5f, 0x42, + 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x4c, 0x31, 0x10, 0x64, 0x12, 0x27, + 0x0a, 0x23, 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, 0x53, 0x4d, 0x54, 0x5f, + 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x10, 0x65, 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, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x66, 0x12, 0x2e, 0x0a, 0x2a, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4c, 0x54, 0x34, + 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x67, 0x12, 0x29, 0x0a, 0x25, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, + 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x68, 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, 0x4e, 0x45, 0x57, 0x5f, 0x41, 0x43, 0x43, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x48, + 0x41, 0x53, 0x48, 0x10, 0x69, 0x12, 0x2e, 0x0a, 0x2a, 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, 0x49, 0x4e, 0x44, - 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, 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, 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, + 0x4e, 0x45, 0x57, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, + 0x4f, 0x4f, 0x54, 0x10, 0x6a, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x44, 0x42, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4e, + 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x6b, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x54, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x53, 0x49, + 0x5a, 0x45, 0x10, 0x6c, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x44, 0x42, 0x5f, 0x47, 0x52, + 0x50, 0x43, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x6d, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, + 0x54, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x52, 0x10, 0x6e, 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, 0x4c, 0x31, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x54, + 0x52, 0x45, 0x45, 0x5f, 0x49, 0x4e, 0x44, 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, 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, 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, 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, + 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/trace.go b/state/trace.go index 387e95543b..a7ecdf08c4 100644 --- a/state/trace.go +++ b/state/trace.go @@ -217,6 +217,7 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has TimestampLimit: uint64(time.Now().Unix()), SkipFirstChangeL2Block: cFalse, SkipWriteBlockInfoRoot: cTrue, + ExecutionMode: executor.ExecutionMode0, } // Send Batch to the Executor diff --git a/state/transaction.go b/state/transaction.go index ba5ed64f88..488c13295f 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -519,6 +519,7 @@ func (s *State) internalProcessUnsignedTransactionV2(ctx context.Context, tx *ty TimestampLimit: uint64(time.Now().Unix()), SkipFirstChangeL2Block: cFalse, SkipWriteBlockInfoRoot: cTrue, + ExecutionMode: executor.ExecutionMode0, } if noZKEVMCounters { processBatchRequestV2.NoCounters = cTrue @@ -990,6 +991,7 @@ func (s *State) internalTestGasEstimationTransactionV2(ctx context.Context, batc TimestampLimit: uint64(time.Now().Unix()), SkipFirstChangeL2Block: cTrue, SkipWriteBlockInfoRoot: cTrue, + ExecutionMode: executor.ExecutionMode0, } log.Debugf("EstimateGas[processBatchRequestV2.From]: %v", processBatchRequestV2.From) diff --git a/state/types.go b/state/types.go index e44052f205..e8897a2791 100644 --- a/state/types.go +++ b/state/types.go @@ -31,6 +31,7 @@ type ProcessRequest struct { SkipWriteBlockInfoRoot_V2 bool SkipVerifyL1InfoRoot_V2 bool ForkID uint64 + ExecutionMode uint64 } // L1DataV2 represents the L1InfoTree data used in ProcessRequest.L1InfoTreeData_V2 parameter diff --git a/synchronizer/actions/etrog/processor_l1_sequence_batches.go b/synchronizer/actions/etrog/processor_l1_sequence_batches.go index 162ce0edd8..638c505cee 100644 --- a/synchronizer/actions/etrog/processor_l1_sequence_batches.go +++ b/synchronizer/actions/etrog/processor_l1_sequence_batches.go @@ -155,6 +155,7 @@ func (p *ProcessorL1SequenceBatchesEtrog) processSequenceBatches(ctx context.Con BatchL2Data: &txs, ForcedBlockHashL1: forcedBlockHashL1, SkipVerifyL1InfoRoot: 1, + ExecutionMode: executor.ExecutionMode1, } } else if sbatch.PolygonRollupBaseEtrogBatchData.ForcedTimestamp > 0 && sbatch.BatchNumber == 1 { log.Debug("Processing initial batch") @@ -171,6 +172,7 @@ func (p *ProcessorL1SequenceBatchesEtrog) processSequenceBatches(ctx context.Con BatchL2Data: &txs, ForcedBlockHashL1: forcedBlockHashL1, SkipVerifyL1InfoRoot: 1, + ExecutionMode: executor.ExecutionMode1, } } else { var maxGER common.Hash @@ -195,6 +197,7 @@ func (p *ProcessorL1SequenceBatchesEtrog) processSequenceBatches(ctx context.Con BatchL2Data: &batch.BatchL2Data, SkipVerifyL1InfoRoot: 1, GlobalExitRoot: batch.GlobalExitRoot, + ExecutionMode: executor.ExecutionMode1, } if batch.GlobalExitRoot == (common.Hash{}) { if len(leaves) > 0 { diff --git a/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go b/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go index 20b1bc1824..60347d57bc 100644 --- a/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go +++ b/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go @@ -9,6 +9,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/state" "github.com/0xPolygonHermez/zkevm-node/state/metrics" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" + "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions" syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common" "github.com/ethereum/go-ethereum/common" @@ -83,6 +84,7 @@ func (g *ProcessorL1UpdateEtrogSequence) processUpdateEtrogSequence(ctx context. ForcedBlockHashL1: forcedBlockHashL1, SkipVerifyL1InfoRoot: 1, GlobalExitRoot: updateEtrogSequence.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot, + ExecutionMode: executor.ExecutionMode1, } virtualBatch := state.VirtualBatch{ diff --git a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go index 68e654319c..c428a1e886 100644 --- a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go +++ b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go @@ -9,6 +9,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types" "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/state" + "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common" "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces" "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared" @@ -432,6 +433,7 @@ func (b *SyncTrustedBatchExecutorForEtrog) getProcessRequest(data *l2_shared.Pro Transactions: data.TrustedBatch.BatchL2Data, ForkID: b.state.GetForkIDByBatchNumber(uint64(data.TrustedBatch.Number)), SkipVerifyL1InfoRoot_V2: true, + ExecutionMode: executor.ExecutionMode1, } return request } diff --git a/synchronizer/l2_sync/l2_sync_incaberry/sync_trusted_state.go b/synchronizer/l2_sync/l2_sync_incaberry/sync_trusted_state.go index 9dbf7af212..9957b154ff 100644 --- a/synchronizer/l2_sync/l2_sync_incaberry/sync_trusted_state.go +++ b/synchronizer/l2_sync/l2_sync_incaberry/sync_trusted_state.go @@ -196,6 +196,7 @@ func (s *SyncTrustedBatchesAction) processTrustedBatch(ctx context.Context, trus OldAccInputHash: batches[1].AccInputHash, Coinbase: common.HexToAddress(trustedBatch.Coinbase.String()), Timestamp_V1: time.Unix(int64(trustedBatch.Timestamp), 0), + ExecutionMode: executor.ExecutionMode1, } // check if batch needs to be synchronized if batches[0] != nil { From 0a58f2895b140f0ae183a6e8f150e14adcace673 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Fri, 16 Feb 2024 15:40:09 +0100 Subject: [PATCH 07/51] update prover image (#3286) --- 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..1e87b4a02b 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.12 depends_on: zkevm-state-db: condition: service_healthy diff --git a/test/docker-compose.yml b/test/docker-compose.yml index ce9577e546..8b5ae6532c 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.12 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.12 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover From 857be174c583333c815c4ef40fcdb2273969a20c Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Fri, 16 Feb 2024 19:31:18 +0100 Subject: [PATCH 08/51] fix log when error on batch sanity check (#3287) --- sequencer/batch.go | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/sequencer/batch.go b/sequencer/batch.go index 0884cbfffd..a8ebad70ea 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -354,12 +354,16 @@ func (f *finalizer) batchSanityCheck(ctx context.Context, batchNum uint64, initi // Log batch detailed info log.Errorf("batch %d sanity check error: initialStateRoot: %s, expectedNewStateRoot: %s", batch.BatchNumber, initialStateRoot, expectedNewStateRoot) - for i, rawL2block := range rawL2Blocks.Blocks { - log.Infof("block[%d], txs: %d, deltaTimestamp: %d, l1InfoTreeIndex: %d", i, len(rawL2block.Transactions), rawL2block.DeltaTimestamp, rawL2block.IndexL1InfoTree) - for j, rawTx := range rawL2block.Transactions { - log.Infof("block[%d].tx[%d]: %s, egpPct: %d", batch.BatchNumber, i, j, rawTx.Tx.Hash(), rawTx.EfficiencyPercentage) + batchLog := "" + totalTxs := 0 + for blockIdx, rawL2block := range rawL2Blocks.Blocks { + totalTxs += len(rawL2block.Transactions) + batchLog += fmt.Sprintf("block[%d], txs: %d, deltaTimestamp: %d, l1InfoTreeIndex: %d\n", blockIdx, len(rawL2block.Transactions), rawL2block.DeltaTimestamp, rawL2block.IndexL1InfoTree) + for txIdx, rawTx := range rawL2block.Transactions { + batchLog += fmt.Sprintf(" tx[%d]: %s, egpPct: %d\n", txIdx, rawTx.Tx.Hash(), rawTx.EfficiencyPercentage) } } + log.Infof("DUMP batch %d, blocks: %d, txs: %d\n%s", batch.BatchNumber, len(rawL2Blocks.Blocks), totalTxs, batchLog) f.Halt(ctx, fmt.Errorf("batch sanity check error. Check previous errors in logs to know which was the cause"), false) } From 5a1782f5a56c7447d276a948e8fb4075a4fc85ad Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Fri, 16 Feb 2024 19:37:24 +0100 Subject: [PATCH 09/51] update prover image to v4.0.13 (#3289) --- 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 1e87b4a02b..b9983801ee 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.12 + image: hermeznetwork/zkevm-prover:v4.0.13 depends_on: zkevm-state-db: condition: service_healthy diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 8b5ae6532c..3dc5567a41 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.12 + image: hermeznetwork/zkevm-prover:v4.0.13 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.12 + image: hermeznetwork/zkevm-prover:v4.0.13 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover From a7c9c7172ae4a1b4225e6e253100a825b4a9f85a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Sat, 17 Feb 2024 10:12:53 +0100 Subject: [PATCH 10/51] update prover image (#3290) --- 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 b9983801ee..e5dda3a1dc 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.13 + image: hermeznetwork/zkevm-prover:v4.0.14 depends_on: zkevm-state-db: condition: service_healthy diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 3dc5567a41..a501465771 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.13 + image: hermeznetwork/zkevm-prover:v4.0.14 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.13 + image: hermeznetwork/zkevm-prover:v4.0.14 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover From 3b259710a5ef02353e7277e96b74a9ff7513b211 Mon Sep 17 00:00:00 2001 From: Thiago Coimbra Lemos Date: Sat, 17 Feb 2024 18:12:57 -0300 Subject: [PATCH 11/51] fix deltaTimestamp when debug tx (#3291) * fix deltaTimestamp when debug tx * fix deltaTimeStamp for unsigned txs execution for specific block * fix deltaTimeStamp for unsigned txs execution for specific block * Revert "fix deltaTimeStamp for unsigned txs execution for specific block" This reverts commit eb77e0406d454939728feeea1021d243edde70a8. * Revert "fix deltaTimeStamp for unsigned txs execution for specific block" This reverts commit d2cfa7887721e981868a9e460e293ab436b3bd87. * fix debug trace l1 info tree index and add l1 info tree data * move MockL1InfoRoot from sequencer to state to allow multiple components to use the same value --------- Co-authored-by: agnusmor --- sequencer/batch.go | 2 +- sequencer/finalizer.go | 10 ++------- sequencer/l2block.go | 4 ++-- state/batch.go | 17 +++++++++++++++ state/trace.go | 49 +++++++++++++++++++++++++++++++++++++++--- 5 files changed, 68 insertions(+), 14 deletions(-) diff --git a/sequencer/batch.go b/sequencer/batch.go index a8ebad70ea..934f09c2dd 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -383,7 +383,7 @@ func (f *finalizer) batchSanityCheck(ctx context.Context, batchNum uint64, initi batchRequest := state.ProcessRequest{ BatchNumber: batch.BatchNumber, - L1InfoRoot_V2: mockL1InfoRoot, + L1InfoRoot_V2: state.GetMockL1InfoRoot(), OldStateRoot: initialStateRoot, Transactions: batch.BatchL2Data, Coinbase: batch.Coinbase, diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index 7f400b9f4c..00fc589ee0 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -29,8 +29,7 @@ const ( ) var ( - now = time.Now - mockL1InfoRoot = common.Hash{} + now = time.Now ) // finalizer represents the finalizer component of the sequencer. @@ -139,11 +138,6 @@ func newFinalizer( // Start starts the finalizer. func (f *finalizer) Start(ctx context.Context) { - // Init mockL1InfoRoot to a mock value since it must be different to {0,0,...,0} - for i := 0; i < len(mockL1InfoRoot); i++ { - mockL1InfoRoot[i] = byte(i) - } - // Do sanity check for batches closed but pending to be checked f.processBatchesPendingtoCheck(ctx) @@ -357,7 +351,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first BatchNumber: f.wipBatch.batchNumber, OldStateRoot: f.wipBatch.imStateRoot, Coinbase: f.wipBatch.coinbase, - L1InfoRoot_V2: mockL1InfoRoot, + L1InfoRoot_V2: state.GetMockL1InfoRoot(), TimestampLimit_V2: f.wipL2Block.timestamp, Caller: stateMetrics.SequencerCallerLabel, ForkID: f.stateIntf.GetForkIDByBatchNumber(f.wipBatch.batchNumber), diff --git a/sequencer/l2block.go b/sequencer/l2block.go index 7fd7877c03..8b9ff14bdb 100644 --- a/sequencer/l2block.go +++ b/sequencer/l2block.go @@ -254,7 +254,7 @@ func (f *finalizer) executeL2Block(ctx context.Context, initialStateRoot common. BatchNumber: f.wipBatch.batchNumber, OldStateRoot: initialStateRoot, Coinbase: f.wipBatch.coinbase, - L1InfoRoot_V2: mockL1InfoRoot, + L1InfoRoot_V2: state.GetMockL1InfoRoot(), TimestampLimit_V2: l2Block.timestamp, Transactions: batchL2Data, SkipFirstChangeL2Block_V2: false, @@ -538,7 +538,7 @@ func (f *finalizer) executeNewWIPL2Block(ctx context.Context) (*state.ProcessBat BatchNumber: f.wipBatch.batchNumber, OldStateRoot: f.wipBatch.imStateRoot, Coinbase: f.wipBatch.coinbase, - L1InfoRoot_V2: mockL1InfoRoot, + L1InfoRoot_V2: state.GetMockL1InfoRoot(), TimestampLimit_V2: f.wipL2Block.timestamp, Caller: stateMetrics.SequencerCallerLabel, ForkID: f.stateIntf.GetForkIDByBatchNumber(f.wipBatch.batchNumber), diff --git a/state/batch.go b/state/batch.go index f9a30637c4..601a2e6b16 100644 --- a/state/batch.go +++ b/state/batch.go @@ -21,6 +21,15 @@ const ( cFalse = 0 noFlushID uint64 = 0 noProverID string = "" + + // MockL1InfoRootHex is used to send batches to the Executor + // the number below represents this formula: + // + // mockL1InfoRoot := common.Hash{} + // for i := 0; i < len(mockL1InfoRoot); i++ { + // mockL1InfoRoot[i] = byte(i) + // } + MockL1InfoRootHex = "0x000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f" ) // Batch struct @@ -615,3 +624,11 @@ func findMax(blocks []L2BlockRaw) uint32 { } return maxIndex } + +var mockL1InfoRoot = common.HexToHash(MockL1InfoRootHex) + +// GetMockL1InfoRoot returns an instance of common.Hash set +// with the value provided by the const MockL1InfoRootHex +func GetMockL1InfoRoot() common.Hash { + return mockL1InfoRoot +} diff --git a/state/trace.go b/state/trace.go index a7ecdf08c4..26b00a8048 100644 --- a/state/trace.go +++ b/state/trace.go @@ -187,8 +187,33 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has traceConfigRequestV2.EnableReturnData = cFalse } } - deltaTimestamp := uint32(uint64(time.Now().Unix()) - l2Block.Time()) - transactions := s.BuildChangeL2Block(deltaTimestamp, uint32(0)) + + // build the raw batch so we can get the index l1 info tree for the l2 block + rawBatch, err := DecodeBatchV2(batch.BatchL2Data) + if err != nil { + log.Errorf("error decoding BatchL2Data for batch %d, error: %v", batch.BatchNumber, err) + return nil, err + } + + // identify the first l1 block number so we can identify the + // current l2 block index in the block array + firstBlockNumberForBatch, err := s.GetFirstL2BlockNumberForBatchNumber(ctx, batch.BatchNumber, dbTx) + if err != nil { + log.Errorf("failed to get first l2 block number for batch %v: %v ", batch.BatchNumber, err) + return nil, err + } + + // computes the l2 block index + rawL2BlockIndex := l2Block.NumberU64() - firstBlockNumberForBatch + if rawL2BlockIndex > uint64(len(rawBatch.Blocks)-1) { + log.Errorf("computed rawL2BlockIndex is greater than the number of blocks we have in the batch %v: %v ", batch.BatchNumber, err) + return nil, err + } + + // builds the ChangeL2Block transaction with the correct timestamp and IndexL1InfoTree + rawL2Block := rawBatch.Blocks[rawL2BlockIndex] + deltaTimestamp := uint32(l2Block.Time() - previousL2Block.Time()) + transactions := s.BuildChangeL2Block(deltaTimestamp, rawL2Block.IndexL1InfoTree) batchL2Data, err := EncodeTransactions(txsToEncode, effectivePercentage, forkId) if err != nil { @@ -213,13 +238,31 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has ContextId: uuid.NewString(), // v2 fields - L1InfoRoot: l2Block.BlockInfoRoot().Bytes(), + L1InfoRoot: GetMockL1InfoRoot().Bytes(), TimestampLimit: uint64(time.Now().Unix()), SkipFirstChangeL2Block: cFalse, SkipWriteBlockInfoRoot: cTrue, ExecutionMode: executor.ExecutionMode0, } + // gets the L1InfoTreeData for the transactions + l1InfoTreeData, _, _, err := s.GetL1InfoTreeDataFromBatchL2Data(ctx, transactions, dbTx) + if err != nil { + return nil, err + } + + // In case we have any l1InfoTreeData, add them to the request + if len(l1InfoTreeData) > 0 { + processBatchRequestV2.L1InfoTreeData = map[uint32]*executor.L1DataV2{} + for k, v := range l1InfoTreeData { + processBatchRequestV2.L1InfoTreeData[k] = &executor.L1DataV2{ + GlobalExitRoot: v.GlobalExitRoot.Bytes(), + BlockHashL1: v.BlockHashL1.Bytes(), + MinTimestamp: v.MinTimestamp, + } + } + } + // Send Batch to the Executor startTime = time.Now() processBatchResponseV2, err := s.executorClient.ProcessBatchV2(ctx, processBatchRequestV2) From bfe0166521ae7b54f003ddc3c9d98888ecc16a58 Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Sat, 17 Feb 2024 22:45:19 +0100 Subject: [PATCH 12/51] fix checkStateInconsistency when starting sequencer (#3294) --- sequencer/sequencer.go | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/sequencer/sequencer.go b/sequencer/sequencer.go index 5a6ab8671c..95b9794dcd 100644 --- a/sequencer/sequencer.go +++ b/sequencer/sequencer.go @@ -114,8 +114,12 @@ func (s *Sequencer) Start(ctx context.Context) { // checkStateInconsistency checks if state inconsistency happened func (s *Sequencer) checkStateInconsistency(ctx context.Context) { + var err error + s.numberOfStateInconsistencies, err = s.stateIntf.CountReorgs(ctx, nil) + if err != nil { + log.Error("failed to get initial number of reorgs, error: %v", err) + } for { - time.Sleep(s.cfg.StateConsistencyCheckInterval.Duration) stateInconsistenciesDetected, err := s.stateIntf.CountReorgs(ctx, nil) if err != nil { log.Error("failed to get number of reorgs, error: %v", err) @@ -125,6 +129,8 @@ func (s *Sequencer) checkStateInconsistency(ctx context.Context) { if stateInconsistenciesDetected != s.numberOfStateInconsistencies { s.finalizer.Halt(ctx, fmt.Errorf("state inconsistency detected, halting finalizer"), false) } + + time.Sleep(s.cfg.StateConsistencyCheckInterval.Duration) } } From 8cb184215a60203fb69650ec1ee12202c2d97c54 Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Sun, 18 Feb 2024 01:04:44 +0100 Subject: [PATCH 13/51] disable delete addrQueue if empty as a workaround (#3295) --- sequencer/worker.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sequencer/worker.go b/sequencer/worker.go index b0f07a2311..0d770e6396 100644 --- a/sequencer/worker.go +++ b/sequencer/worker.go @@ -361,9 +361,9 @@ func (w *Worker) ExpireTransactions(maxTime time.Duration) []*TxTracker { w.txSortedList.delete(prevReadyTx) } - if addrQueue.IsEmpty() { + /*if addrQueue.IsEmpty() { delete(w.pool, addrQueue.fromStr) - } + }*/ } log.Debugf("expire transactions ended, addrQueue length: %d, delete count: %d ", len(w.pool), len(txs)) From 03a9291e23326780f91fde1029838cc223eadc06 Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Tue, 20 Feb 2024 10:36:14 +0100 Subject: [PATCH 14/51] add aggregator.BatchProofL1BlockConfirmations config parameter (#3302) (#3313) --- aggregator/aggregator.go | 17 ++++++++- aggregator/aggregator_test.go | 16 ++++++--- aggregator/config.go | 3 ++ aggregator/interfaces.go | 4 ++- aggregator/mocks/mock_etherman.go | 35 +++++++++++++++++++ aggregator/mocks/mock_state.go | 18 +++++----- config/config_test.go | 4 +++ config/default.go | 1 + .../environments/local/local.node.config.toml | 1 + docs/config-file/node-config-doc.html | 2 +- docs/config-file/node-config-doc.md | 15 ++++++++ docs/config-file/node-config-schema.json | 5 +++ state/interfaces.go | 2 +- state/mocks/mock_storage.go | 29 +++++++-------- state/pgstatestorage/batch.go | 5 +-- test/config/debug.node.config.toml | 1 + test/config/test.node.config.toml | 1 + 17 files changed, 125 insertions(+), 34 deletions(-) diff --git a/aggregator/aggregator.go b/aggregator/aggregator.go index 74aed60c3b..1b23c11202 100644 --- a/aggregator/aggregator.go +++ b/aggregator/aggregator.go @@ -756,8 +756,23 @@ func (a *Aggregator) getAndLockBatchToProve(ctx context.Context, prover proverIn return nil, nil, err } + // Get header of the last L1 block + lastL1BlockHeader, err := a.Ethman.GetLatestBlockHeader(ctx) + if err != nil { + log.Errorf("Failed to get last L1 block header, err: %v", err) + return nil, nil, err + } + lastL1BlockNumber := lastL1BlockHeader.Number.Uint64() + + // Calculate max L1 block number for getting next virtual batch to prove + maxL1BlockNumber := uint64(0) + if a.cfg.BatchProofL1BlockConfirmations <= lastL1BlockNumber { + maxL1BlockNumber = lastL1BlockNumber - a.cfg.BatchProofL1BlockConfirmations + } + log.Debugf("Max L1 block number for getting next virtual batch to prove: %d", maxL1BlockNumber) + // Get virtual batch pending to generate proof - batchToVerify, err := a.State.GetVirtualBatchToProve(ctx, lastVerifiedBatch.BatchNumber, nil) + batchToVerify, err := a.State.GetVirtualBatchToProve(ctx, lastVerifiedBatch.BatchNumber, maxL1BlockNumber, nil) if err != nil { return nil, nil, err } diff --git a/aggregator/aggregator_test.go b/aggregator/aggregator_test.go index eb51a09381..a071828a16 100644 --- a/aggregator/aggregator_test.go +++ b/aggregator/aggregator_test.go @@ -17,6 +17,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/state" "github.com/0xPolygonHermez/zkevm-node/test/testutils" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -775,7 +776,7 @@ func TestTryGenerateBatchProof(t *testing.T) { m.proverMock.On("ID").Return(proverID).Twice() m.proverMock.On("Addr").Return("addr") m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once() - m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, nil).Return(&batchToProve, nil).Once() + m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once() m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run( func(args mock.Arguments) { proof := args[1].(*state.Proof) @@ -798,6 +799,7 @@ func TestTryGenerateBatchProof(t *testing.T) { L1InfoRoot: &l1InfoRoot, TimestampBatchEtrog: &t, } + m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) @@ -817,7 +819,7 @@ func TestTryGenerateBatchProof(t *testing.T) { m.proverMock.On("ID").Return(proverID).Twice() m.proverMock.On("Addr").Return("addr") m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once() - m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, nil).Return(&batchToProve, nil).Once() + m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once() m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run( func(args mock.Arguments) { proof := args[1].(*state.Proof) @@ -840,6 +842,7 @@ func TestTryGenerateBatchProof(t *testing.T) { L1InfoRoot: &l1InfoRoot, TimestampBatchEtrog: &t, } + m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) @@ -860,7 +863,7 @@ func TestTryGenerateBatchProof(t *testing.T) { m.proverMock.On("ID").Return(proverID).Twice() m.proverMock.On("Addr").Return(proverID) m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once() - m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, nil).Return(&batchToProve, nil).Once() + m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once() m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run( func(args mock.Arguments) { proof := args[1].(*state.Proof) @@ -883,6 +886,7 @@ func TestTryGenerateBatchProof(t *testing.T) { L1InfoRoot: &l1InfoRoot, TimestampBatchEtrog: &t, } + m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) @@ -903,7 +907,7 @@ func TestTryGenerateBatchProof(t *testing.T) { m.proverMock.On("ID").Return(proverID).Times(3) m.proverMock.On("Addr").Return("addr") m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once() - m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, nil).Return(&batchToProve, nil).Once() + m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once() m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run( func(args mock.Arguments) { proof := args[1].(*state.Proof) @@ -926,6 +930,7 @@ func TestTryGenerateBatchProof(t *testing.T) { L1InfoRoot: &l1InfoRoot, TimestampBatchEtrog: &t, } + m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() m.stateMock.On("GetVirtualBatch", mock.Anything, lastVerifiedBatchNum+1, nil).Return(&vb, nil).Twice() m.stateMock.On("GetLeafsByL1InfoRoot", mock.Anything, *vb.L1InfoRoot, nil).Return([]state.L1InfoTreeExitRootStorageEntry{}, nil).Twice() expectedInputProver, err := a.buildInputProver(context.Background(), &batchToProve) @@ -960,7 +965,7 @@ func TestTryGenerateBatchProof(t *testing.T) { m.proverMock.On("ID").Return(proverID).Times(3) m.proverMock.On("Addr").Return("addr") m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(&lastVerifiedBatch, nil).Once() - m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, nil).Return(&batchToProve, nil).Once() + m.stateMock.On("GetVirtualBatchToProve", mock.MatchedBy(matchProverCtxFn), lastVerifiedBatchNum, mock.Anything, nil).Return(&batchToProve, nil).Once() m.stateMock.On("AddGeneratedProof", mock.MatchedBy(matchProverCtxFn), mock.Anything, nil).Run( func(args mock.Arguments) { proof := args[1].(*state.Proof) @@ -995,6 +1000,7 @@ func TestTryGenerateBatchProof(t *testing.T) { On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil). Return(&state.VerifiedBatch{BatchNumber: uint64(42)}, nil).Once() m.etherman.On("GetLatestVerifiedBatchNum").Return(uint64(42), nil).Once() + m.etherman.On("GetLatestBlockHeader", mock.Anything).Return(&types.Header{Number: new(big.Int).SetUint64(1)}, nil).Once() // make tryBuildFinalProof fail ASAP m.stateMock.On("GetLastVerifiedBatch", mock.MatchedBy(matchProverCtxFn), nil).Return(nil, errBanana).Once().NotBefore(isSyncedCall) m.stateMock.On("UpdateGeneratedProof", mock.MatchedBy(matchAggregatorCtxFn), mock.Anything, nil).Run( diff --git a/aggregator/config.go b/aggregator/config.go index 9099df1931..420d6dcd2a 100644 --- a/aggregator/config.go +++ b/aggregator/config.go @@ -88,4 +88,7 @@ type Config struct { // UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog UpgradeEtrogBatchNumber uint64 `mapstructure:"UpgradeEtrogBatchNumber"` + + // BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch + BatchProofL1BlockConfirmations uint64 `mapstructure:"BatchProofL1BlockConfirmations"` } diff --git a/aggregator/interfaces.go b/aggregator/interfaces.go index 3bc9c2fe8a..0d6b11b7ed 100644 --- a/aggregator/interfaces.go +++ b/aggregator/interfaces.go @@ -9,6 +9,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/ethtxmanager" "github.com/0xPolygonHermez/zkevm-node/state" "github.com/ethereum/go-ethereum/common" + "github.com/ethereum/go-ethereum/core/types" "github.com/jackc/pgx/v4" ) @@ -39,6 +40,7 @@ type ethTxManager interface { type etherman interface { GetLatestVerifiedBatchNum() (uint64, error) BuildTrustedVerifyBatchesTxData(lastVerifiedBatch, newVerifiedBatch uint64, inputs *ethmanTypes.FinalProofInputs, beneficiary common.Address) (to *common.Address, data []byte, err error) + GetLatestBlockHeader(ctx context.Context) (*types.Header, error) } // aggregatorTxProfitabilityChecker interface for different profitability @@ -53,7 +55,7 @@ type stateInterface interface { CheckProofContainsCompleteSequences(ctx context.Context, proof *state.Proof, dbTx pgx.Tx) (bool, error) GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) (*state.VerifiedBatch, error) GetProofReadyToVerify(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Proof, error) - GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) + GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*state.Batch, error) GetProofsToAggregate(ctx context.Context, dbTx pgx.Tx) (*state.Proof, *state.Proof, error) GetBatchByNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) AddGeneratedProof(ctx context.Context, proof *state.Proof, dbTx pgx.Tx) error diff --git a/aggregator/mocks/mock_etherman.go b/aggregator/mocks/mock_etherman.go index 4f0f97c61e..077771c339 100644 --- a/aggregator/mocks/mock_etherman.go +++ b/aggregator/mocks/mock_etherman.go @@ -3,7 +3,12 @@ package mocks import ( + context "context" + common "github.com/ethereum/go-ethereum/common" + + coretypes "github.com/ethereum/go-ethereum/core/types" + mock "github.com/stretchr/testify/mock" types "github.com/0xPolygonHermez/zkevm-node/etherman/types" @@ -53,6 +58,36 @@ func (_m *Etherman) BuildTrustedVerifyBatchesTxData(lastVerifiedBatch uint64, ne return r0, r1, r2 } +// GetLatestBlockHeader provides a mock function with given fields: ctx +func (_m *Etherman) GetLatestBlockHeader(ctx context.Context) (*coretypes.Header, error) { + ret := _m.Called(ctx) + + if len(ret) == 0 { + panic("no return value specified for GetLatestBlockHeader") + } + + var r0 *coretypes.Header + var r1 error + if rf, ok := ret.Get(0).(func(context.Context) (*coretypes.Header, error)); ok { + return rf(ctx) + } + if rf, ok := ret.Get(0).(func(context.Context) *coretypes.Header); ok { + r0 = rf(ctx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*coretypes.Header) + } + } + + if rf, ok := ret.Get(1).(func(context.Context) error); ok { + r1 = rf(ctx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetLatestVerifiedBatchNum provides a mock function with given fields: func (_m *Etherman) GetLatestVerifiedBatchNum() (uint64, error) { ret := _m.Called() diff --git a/aggregator/mocks/mock_state.go b/aggregator/mocks/mock_state.go index 24b2ffd61e..cfc5b66e7d 100644 --- a/aggregator/mocks/mock_state.go +++ b/aggregator/mocks/mock_state.go @@ -454,9 +454,9 @@ func (_m *StateMock) GetVirtualBatchParentHash(ctx context.Context, batchNumber return r0, r1 } -// GetVirtualBatchToProve provides a mock function with given fields: ctx, lastVerfiedBatchNumber, dbTx -func (_m *StateMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) { - ret := _m.Called(ctx, lastVerfiedBatchNumber, dbTx) +// GetVirtualBatchToProve provides a mock function with given fields: ctx, lastVerfiedBatchNumber, maxL1Block, dbTx +func (_m *StateMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*state.Batch, error) { + ret := _m.Called(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) if len(ret) == 0 { panic("no return value specified for GetVirtualBatchToProve") @@ -464,19 +464,19 @@ func (_m *StateMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatc var r0 *state.Batch var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) (*state.Batch, error)); ok { - return rf(ctx, lastVerfiedBatchNumber, dbTx) + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, pgx.Tx) (*state.Batch, error)); ok { + return rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) } - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) *state.Batch); ok { - r0 = rf(ctx, lastVerfiedBatchNumber, dbTx) + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, pgx.Tx) *state.Batch); ok { + r0 = rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*state.Batch) } } - if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok { - r1 = rf(ctx, lastVerfiedBatchNumber, dbTx) + if rf, ok := ret.Get(1).(func(context.Context, uint64, uint64, pgx.Tx) error); ok { + r1 = rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) } else { r1 = ret.Error(1) } diff --git a/config/config_test.go b/config/config_test.go index a031f88a68..2efaaf0616 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -477,6 +477,10 @@ func Test_Defaults(t *testing.T) { path: "Aggregator.UpgradeEtrogBatchNumber", expectedValue: uint64(0), }, + { + path: "Aggregator.BatchProofL1BlockConfirmations", + expectedValue: uint64(2), + }, { path: "State.Batch.Constraints.MaxTxsPerBatch", expectedValue: uint64(300), diff --git a/config/default.go b/config/default.go index a18586be4e..4bca8b1c9a 100644 --- a/config/default.go +++ b/config/default.go @@ -164,6 +164,7 @@ CleanupLockedProofsInterval = "2m" GeneratingProofCleanupThreshold = "10m" GasOffset = 0 UpgradeEtrogBatchNumber = 0 +BatchProofL1BlockConfirmations = 2 [L2GasPriceSuggester] Type = "follower" diff --git a/config/environments/local/local.node.config.toml b/config/environments/local/local.node.config.toml index ebf5b2544d..9fefe6362b 100644 --- a/config/environments/local/local.node.config.toml +++ b/config/environments/local/local.node.config.toml @@ -128,6 +128,7 @@ SenderAddress = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" CleanupLockedProofsInterval = "2m" GeneratingProofCleanupThreshold = "10m" UpgradeEtrogBatchNumber = 0 +BatchProofL1BlockConfirmations = 2 [EthTxManager] ForcedGas = 0 diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index 8f9e04279a..f578dbcd6a 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -66,7 +66,7 @@
"300ms"
 

Default: 0Type: integer

ChainID is the L2 ChainID provided by the Network Config


Default: 0Type: integer

ForkID is the L2 ForkID provided by the Network Config


Default: ""Type: string

SenderAddress defines which private key the eth tx manager needs to use
to sign the L1 txs


Default: "2m0s"Type: string

CleanupLockedProofsInterval is the interval of time to clean up locked proofs.


Examples:

"1m"
 
"300ms"
-

Default: "10m"Type: string

GeneratingProofCleanupThreshold represents the time interval after
which a proof in generating state is considered to be stuck and
allowed to be cleared.


Default: 0Type: integer

GasOffset is the amount of gas to be added to the gas estimation in order
to provide an amount that is higher than the estimated one. This is used
to avoid the TX getting reverted in case something has changed in the network
state after the estimation which can cause the TX to require more gas to be
executed.

ex:
gas estimation: 1000
gas offset: 100
final gas: 1100


Default: 0Type: integer

UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog


Configuration of the genesis of the network. This is used to known the initial state of the network

L1: Configuration related to L1
Default: 0Type: integer

Chain ID of the L1 network


Type: array of integer

ZkEVMAddr Address of the L1 contract polygonZkEVMAddress

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

RollupManagerAddr Address of the L1 contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

PolAddr Address of the L1 Pol token Contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

GlobalExitRootManagerAddr Address of the L1 GlobalExitRootManager contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


L1: Genesis of the rollup, first block number and root
Default: 0Type: integer

BlockNumber is the block number where the polygonZKEVM smc was deployed on L1


Type: array of integer

Root hash of the genesis block

Must contain a minimum of 32 items

Must contain a maximum of 32 items

Each item of this array must be:


Type: array of object

Actions is the data to populate into the state trie

Each item of this array must be:


Configuration of the gas price suggester service
Default: "follower"Type: string

Default: 2000000000Type: integer

DefaultGasPriceWei is used to set the gas price to be used by the default gas pricer or as minimim gas price by the follower gas pricer.


Default: 0Type: integer

MaxGasPriceWei is used to limit the gas price returned by the follower gas pricer to a maximum value. It is ignored if 0.


Default: 0Type: integer

Default: 0Type: integer

Default: "10s"Type: string

Examples:

"1m"
+

Default: "10m"Type: string

GeneratingProofCleanupThreshold represents the time interval after
which a proof in generating state is considered to be stuck and
allowed to be cleared.


Default: 0Type: integer

GasOffset is the amount of gas to be added to the gas estimation in order
to provide an amount that is higher than the estimated one. This is used
to avoid the TX getting reverted in case something has changed in the network
state after the estimation which can cause the TX to require more gas to be
executed.

ex:
gas estimation: 1000
gas offset: 100
final gas: 1100


Default: 0Type: integer

UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog


Default: 2Type: integer

BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch


Configuration of the genesis of the network. This is used to known the initial state of the network

L1: Configuration related to L1
Default: 0Type: integer

Chain ID of the L1 network


Type: array of integer

ZkEVMAddr Address of the L1 contract polygonZkEVMAddress

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

RollupManagerAddr Address of the L1 contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

PolAddr Address of the L1 Pol token Contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Type: array of integer

GlobalExitRootManagerAddr Address of the L1 GlobalExitRootManager contract

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


L1: Genesis of the rollup, first block number and root
Default: 0Type: integer

BlockNumber is the block number where the polygonZKEVM smc was deployed on L1


Type: array of integer

Root hash of the genesis block

Must contain a minimum of 32 items

Must contain a maximum of 32 items

Each item of this array must be:


Type: array of object

Actions is the data to populate into the state trie

Each item of this array must be:


Configuration of the gas price suggester service
Default: "follower"Type: string

Default: 2000000000Type: integer

DefaultGasPriceWei is used to set the gas price to be used by the default gas pricer or as minimim gas price by the follower gas pricer.


Default: 0Type: integer

MaxGasPriceWei is used to limit the gas price returned by the follower gas pricer to a maximum value. It is ignored if 0.


Default: 0Type: integer

Default: 0Type: integer

Default: "10s"Type: string

Examples:

"1m"
 
"300ms"
 

Default: "1h0m0s"Type: string

Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index 37a3d6563a..249daf8660 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -2370,6 +2370,7 @@ GasOffset=80000
 | - [GeneratingProofCleanupThreshold](#Aggregator_GeneratingProofCleanupThreshold )                   | No      | string  | No         | -          | GeneratingProofCleanupThreshold represents the time interval after
which a proof in generating state is considered to be stuck and
allowed to be cleared. | | - [GasOffset](#Aggregator_GasOffset ) | No | integer | No | - | GasOffset is the amount of gas to be added to the gas estimation in order
to provide an amount that is higher than the estimated one. This is used
to avoid the TX getting reverted in case something has changed in the network
state after the estimation which can cause the TX to require more gas to be
executed.

ex:
gas estimation: 1000
gas offset: 100
final gas: 1100 | | - [UpgradeEtrogBatchNumber](#Aggregator_UpgradeEtrogBatchNumber ) | No | integer | No | - | UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog | +| - [BatchProofL1BlockConfirmations](#Aggregator_BatchProofL1BlockConfirmations ) | No | integer | No | - | BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch | ### 12.1. `Aggregator.Host` @@ -2647,6 +2648,20 @@ GasOffset=0 UpgradeEtrogBatchNumber=0 ``` +### 12.16. `Aggregator.BatchProofL1BlockConfirmations` + +**Type:** : `integer` + +**Default:** `2` + +**Description:** BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch + +**Example setting the default value** (2): +``` +[Aggregator] +BatchProofL1BlockConfirmations=2 +``` + ## 13. `[NetworkConfig]` **Type:** : `object` diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json index b28e8ea462..95e2e2b248 100644 --- a/docs/config-file/node-config-schema.json +++ b/docs/config-file/node-config-schema.json @@ -1011,6 +1011,11 @@ "type": "integer", "description": "UpgradeEtrogBatchNumber is the number of the first batch after upgrading to etrog", "default": 0 + }, + "BatchProofL1BlockConfirmations": { + "type": "integer", + "description": "BatchProofL1BlockConfirmations is number of L1 blocks to consider we can generate the proof for a virtual batch", + "default": 2 } }, "additionalProperties": false, diff --git a/state/interfaces.go b/state/interfaces.go index 17636f5ce1..f6b5859a80 100644 --- a/state/interfaces.go +++ b/state/interfaces.go @@ -98,7 +98,7 @@ type storage interface { GetExitRootByGlobalExitRoot(ctx context.Context, ger common.Hash, dbTx pgx.Tx) (*GlobalExitRoot, error) AddSequence(ctx context.Context, sequence Sequence, dbTx pgx.Tx) error GetSequences(ctx context.Context, lastVerifiedBatchNumber uint64, dbTx pgx.Tx) ([]Sequence, error) - GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*Batch, error) + GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*Batch, error) CheckProofContainsCompleteSequences(ctx context.Context, proof *Proof, dbTx pgx.Tx) (bool, error) GetProofReadyToVerify(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*Proof, error) GetProofsToAggregate(ctx context.Context, dbTx pgx.Tx) (*Proof, *Proof, error) diff --git a/state/mocks/mock_storage.go b/state/mocks/mock_storage.go index 559e73a930..4856aa7e41 100644 --- a/state/mocks/mock_storage.go +++ b/state/mocks/mock_storage.go @@ -6950,9 +6950,9 @@ func (_c *StorageMock_GetVirtualBatchParentHash_Call) RunAndReturn(run func(cont return _c } -// GetVirtualBatchToProve provides a mock function with given fields: ctx, lastVerfiedBatchNumber, dbTx -func (_m *StorageMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) { - ret := _m.Called(ctx, lastVerfiedBatchNumber, dbTx) +// GetVirtualBatchToProve provides a mock function with given fields: ctx, lastVerfiedBatchNumber, maxL1Block, dbTx +func (_m *StorageMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*state.Batch, error) { + ret := _m.Called(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) if len(ret) == 0 { panic("no return value specified for GetVirtualBatchToProve") @@ -6960,19 +6960,19 @@ func (_m *StorageMock) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBa var r0 *state.Batch var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) (*state.Batch, error)); ok { - return rf(ctx, lastVerfiedBatchNumber, dbTx) + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, pgx.Tx) (*state.Batch, error)); ok { + return rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) } - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) *state.Batch); ok { - r0 = rf(ctx, lastVerfiedBatchNumber, dbTx) + if rf, ok := ret.Get(0).(func(context.Context, uint64, uint64, pgx.Tx) *state.Batch); ok { + r0 = rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*state.Batch) } } - if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok { - r1 = rf(ctx, lastVerfiedBatchNumber, dbTx) + if rf, ok := ret.Get(1).(func(context.Context, uint64, uint64, pgx.Tx) error); ok { + r1 = rf(ctx, lastVerfiedBatchNumber, maxL1Block, dbTx) } else { r1 = ret.Error(1) } @@ -6988,14 +6988,15 @@ type StorageMock_GetVirtualBatchToProve_Call struct { // GetVirtualBatchToProve is a helper method to define mock.On call // - ctx context.Context // - lastVerfiedBatchNumber uint64 +// - maxL1Block uint64 // - dbTx pgx.Tx -func (_e *StorageMock_Expecter) GetVirtualBatchToProve(ctx interface{}, lastVerfiedBatchNumber interface{}, dbTx interface{}) *StorageMock_GetVirtualBatchToProve_Call { - return &StorageMock_GetVirtualBatchToProve_Call{Call: _e.mock.On("GetVirtualBatchToProve", ctx, lastVerfiedBatchNumber, dbTx)} +func (_e *StorageMock_Expecter) GetVirtualBatchToProve(ctx interface{}, lastVerfiedBatchNumber interface{}, maxL1Block interface{}, dbTx interface{}) *StorageMock_GetVirtualBatchToProve_Call { + return &StorageMock_GetVirtualBatchToProve_Call{Call: _e.mock.On("GetVirtualBatchToProve", ctx, lastVerfiedBatchNumber, maxL1Block, dbTx)} } -func (_c *StorageMock_GetVirtualBatchToProve_Call) Run(run func(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx)) *StorageMock_GetVirtualBatchToProve_Call { +func (_c *StorageMock_GetVirtualBatchToProve_Call) Run(run func(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx)) *StorageMock_GetVirtualBatchToProve_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint64), args[2].(pgx.Tx)) + run(args[0].(context.Context), args[1].(uint64), args[2].(uint64), args[3].(pgx.Tx)) }) return _c } @@ -7005,7 +7006,7 @@ func (_c *StorageMock_GetVirtualBatchToProve_Call) Return(_a0 *state.Batch, _a1 return _c } -func (_c *StorageMock_GetVirtualBatchToProve_Call) RunAndReturn(run func(context.Context, uint64, pgx.Tx) (*state.Batch, error)) *StorageMock_GetVirtualBatchToProve_Call { +func (_c *StorageMock_GetVirtualBatchToProve_Call) RunAndReturn(run func(context.Context, uint64, uint64, pgx.Tx) (*state.Batch, error)) *StorageMock_GetVirtualBatchToProve_Call { _c.Call.Return(run) return _c } diff --git a/state/pgstatestorage/batch.go b/state/pgstatestorage/batch.go index 214be8a685..83bfad3cdb 100644 --- a/state/pgstatestorage/batch.go +++ b/state/pgstatestorage/batch.go @@ -764,7 +764,7 @@ func (p *PostgresStorage) GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) // GetVirtualBatchToProve return the next batch that is not proved, neither in // proved process. -func (p *PostgresStorage) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, dbTx pgx.Tx) (*state.Batch, error) { +func (p *PostgresStorage) GetVirtualBatchToProve(ctx context.Context, lastVerfiedBatchNumber uint64, maxL1Block uint64, dbTx pgx.Tx) (*state.Batch, error) { const query = ` SELECT b.batch_num, @@ -783,6 +783,7 @@ func (p *PostgresStorage) GetVirtualBatchToProve(ctx context.Context, lastVerfie state.virtual_batch v WHERE b.batch_num > $1 AND b.batch_num = v.batch_num AND + v.block_num <= $2 AND NOT EXISTS ( SELECT p.batch_num FROM state.proof p WHERE v.batch_num >= p.batch_num AND v.batch_num <= p.batch_num_final @@ -790,7 +791,7 @@ func (p *PostgresStorage) GetVirtualBatchToProve(ctx context.Context, lastVerfie ORDER BY b.batch_num ASC LIMIT 1 ` e := p.getExecQuerier(dbTx) - row := e.QueryRow(ctx, query, lastVerfiedBatchNumber) + row := e.QueryRow(ctx, query, lastVerfiedBatchNumber, maxL1Block) batch, err := scanBatch(row) if errors.Is(err, pgx.ErrNoRows) { return nil, state.ErrNotFound diff --git a/test/config/debug.node.config.toml b/test/config/debug.node.config.toml index aa1a5f5ee0..32bbdd7f56 100644 --- a/test/config/debug.node.config.toml +++ b/test/config/debug.node.config.toml @@ -129,6 +129,7 @@ SenderAddress = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" CleanupLockedProofsInterval = "2m" GeneratingProofCleanupThreshold = "10m" UpgradeEtrogBatchNumber = 0 +BatchProofL1BlockConfirmations = 2 [EthTxManager] ForcedGas = 0 diff --git a/test/config/test.node.config.toml b/test/config/test.node.config.toml index 76c6e53aee..8d6a0d215d 100644 --- a/test/config/test.node.config.toml +++ b/test/config/test.node.config.toml @@ -146,6 +146,7 @@ SenderAddress = "0x70997970c51812dc3a010c7d01b50e0d17dc79c8" CleanupLockedProofsInterval = "2m" GeneratingProofCleanupThreshold = "10m" UpgradeEtrogBatchNumber = 0 +BatchProofL1BlockConfirmations = 2 [EthTxManager] ForcedGas = 0 From e13c7ad449cbf1fdc1c572123a69845fba622cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Tue, 20 Feb 2024 16:11:43 +0100 Subject: [PATCH 15/51] Feature remove executor errors (#3317) * remove executor errors * readd check --- event/event.go | 2 - jsonrpc/endpoints_eth.go | 2 +- pool/pool.go | 4 +- proto/src/proto/executor/v1/executor.proto | 6 - sequencer/batch.go | 4 +- sequencer/finalizer.go | 28 ----- sequencer/l2block.go | 6 +- state/batchV2.go | 4 +- state/convertersV2.go | 3 +- state/runtime/executor/errors.go | 12 -- state/runtime/executor/executor.pb.go | 70 ++++------- state/runtime/executor/executor_grpc.pb.go | 2 +- state/runtime/runtime.go | 6 - state/test/forkid_etrog/etrog_test.go | 139 --------------------- state/trace.go | 4 +- state/transaction.go | 12 +- state/types.go | 1 - test/contracts/auto/customModExp.sol | 24 ---- 18 files changed, 41 insertions(+), 288 deletions(-) delete mode 100644 test/contracts/auto/customModExp.sol diff --git a/event/event.go b/event/event.go index 840078749a..c69380db80 100644 --- a/event/event.go +++ b/event/event.go @@ -42,8 +42,6 @@ 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" // EventID_NodeOOC is triggered when an OOC at node level is detected EventID_NodeOOC EventID = "NODE OOC" diff --git a/jsonrpc/endpoints_eth.go b/jsonrpc/endpoints_eth.go index e999a0facf..4d9ffe0270 100644 --- a/jsonrpc/endpoints_eth.go +++ b/jsonrpc/endpoints_eth.go @@ -106,7 +106,7 @@ func (e *EthEndpoints) Call(arg *types.TxArgs, blockArg *types.BlockNumberOrHash result, err := e.state.ProcessUnsignedTransaction(ctx, tx, sender, blockToProcess, true, dbTx) if err != nil { errMsg := fmt.Sprintf("failed to execute the unsigned transaction: %v", err.Error()) - logError := !executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) && !(errors.Is(err, runtime.ErrOutOfGas) || errors.Is(err, runtime.ErrExecutorErrorOOG2)) + logError := !executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) && !errors.Is(err, runtime.ErrOutOfGas) return RPCErrorResponse(types.DefaultErrorCode, errMsg, nil, logError) } diff --git a/pool/pool.go b/pool/pool.go index ed0e9ace21..6f67982665 100644 --- a/pool/pool.go +++ b/pool/pool.go @@ -298,7 +298,7 @@ func (p *Pool) preExecuteTx(ctx context.Context, tx types.Transaction) (preExecu processBatchResponse, err := p.state.PreProcessTransaction(ctx, &tx, nil) if err != nil { isOOC := executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) - isOOG := errors.Is(err, runtime.ErrOutOfGas) || errors.Is(err, runtime.ErrExecutorErrorOOG2) + isOOG := errors.Is(err, runtime.ErrOutOfGas) if !isOOC && !isOOG { return response, err } else { @@ -324,7 +324,7 @@ func (p *Pool) preExecuteTx(ctx context.Context, tx types.Transaction) (preExecu if executor.IsROMOutOfCountersError(executor.RomErrorCode(errorToCheck)) { response.OOCError = err } - if errors.Is(errorToCheck, runtime.ErrOutOfGas) || errors.Is(errorToCheck, runtime.ErrExecutorErrorOOG2) { + if errors.Is(errorToCheck, runtime.ErrOutOfGas) { response.OOGError = err } } else { diff --git a/proto/src/proto/executor/v1/executor.proto b/proto/src/proto/executor/v1/executor.proto index b260ec1c6f..2fdd32ef35 100644 --- a/proto/src/proto/executor/v1/executor.proto +++ b/proto/src/proto/executor/v1/executor.proto @@ -863,10 +863,4 @@ 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 = 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/sequencer/batch.go b/sequencer/batch.go index 934f09c2dd..bb944dbd26 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -3,7 +3,6 @@ package sequencer import ( "context" "encoding/json" - "errors" "fmt" "time" @@ -12,7 +11,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" - "github.com/0xPolygonHermez/zkevm-node/state/runtime" "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/ethereum/go-ethereum/common" ) @@ -412,7 +410,7 @@ func (f *finalizer) batchSanityCheck(ctx context.Context, batchNum uint64, initi return nil, ErrProcessBatch } - if batchResponse.ExecutorError != nil && !errors.Is(batchResponse.ExecutorError, runtime.ErrExecutorErrorCloseBatch) { + if batchResponse.ExecutorError != nil { log.Errorf("executor error when reprocessing batch %d, error: %v", batch.BatchNumber, batchResponse.ExecutorError) reprocessError(batch) return nil, ErrExecutorError diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index 00fc589ee0..3a1e451939 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -2,7 +2,6 @@ package sequencer import ( "context" - "encoding/json" "errors" "fmt" "math/big" @@ -446,27 +445,6 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first } 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) @@ -603,15 +581,9 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx tx.EGPLog.GasPrice, tx.EGPLog.L1GasPrice, tx.EGPLog.L2GasPrice, tx.EGPLog.Reprocess, tx.EGPLog.GasPriceOC, tx.EGPLog.BalanceOC, egpEnabled, len(tx.RawTx), tx.HashStr, tx.EGPLog.Error) f.wipL2Block.addTx(tx) - f.wipBatch.countOfTxs++ - f.updateWorkerAfterSuccessfulProcessing(ctx, tx.Hash, tx.From, false, result) - if result.CloseBatch_V2 { - return nil, true, nil - } - return nil, false, nil } diff --git a/sequencer/l2block.go b/sequencer/l2block.go index 8b9ff14bdb..6cdc814753 100644 --- a/sequencer/l2block.go +++ b/sequencer/l2block.go @@ -2,7 +2,6 @@ package sequencer import ( "context" - "errors" "fmt" "time" @@ -12,7 +11,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" - "github.com/0xPolygonHermez/zkevm-node/state/runtime" "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/ethereum/go-ethereum/common" ) @@ -283,7 +281,7 @@ func (f *finalizer) executeL2Block(ctx context.Context, initialStateRoot common. return nil, 0, err } - if batchResponse.ExecutorError != nil && !errors.Is(batchResponse.ExecutorError, runtime.ErrExecutorErrorCloseBatch) { + if batchResponse.ExecutorError != nil { executeL2BLockError(batchResponse.ExecutorError) return nil, 0, ErrExecutorError } @@ -562,7 +560,7 @@ func (f *finalizer) executeNewWIPL2Block(ctx context.Context) (*state.ProcessBat return nil, err } - if batchResponse.ExecutorError != nil && !errors.Is(batchResponse.ExecutorError, runtime.ErrExecutorErrorCloseBatch) { + if batchResponse.ExecutorError != nil { return nil, ErrExecutorError } diff --git a/state/batchV2.go b/state/batchV2.go index 01d371f397..4f8108c5b9 100644 --- a/state/batchV2.go +++ b/state/batchV2.go @@ -168,7 +168,7 @@ func (s *State) ExecuteBatchV2(ctx context.Context, batch Batch, L1InfoTreeRoot if err != nil { log.Error("error executing batch: ", err) return nil, err - } else if processBatchResponse != nil && processBatchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && processBatchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { + } else if processBatchResponse != nil && processBatchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR { err = executor.ExecutorErr(processBatchResponse.Error) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponse.Error, processBatchRequest) } @@ -303,7 +303,7 @@ func (s *State) sendBatchRequestToExecutorV2(ctx context.Context, batchRequest * log.Errorf("error executor ProcessBatchV2 response: %v", batchResponse) } else { batchResponseToString := processBatchResponseToString(newBatchNum, batchResponse, elapsed) - if batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { + if batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR { err = executor.ExecutorErr(batchResponse.Error) log.Warnf("executor batch %d response, executor error: %v", newBatchNum, err) log.Warn(batchResponseToString) diff --git a/state/convertersV2.go b/state/convertersV2.go index 46b03bf3ab..9b19898d93 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 && batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH), + IsExecutorLevelError: batchResponse.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR, IsRomLevelError: isRomLevelError, IsRomOOCError: isRomOOCError, GasUsed_V2: batchResponse.GasUsed, @@ -65,7 +65,6 @@ 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 ace96ea969..a2e8f2d1d5 100644 --- a/state/runtime/executor/errors.go +++ b/state/runtime/executor/errors.go @@ -454,12 +454,6 @@ func ExecutorErr(errorCode ExecutorError) error { return runtime.ErrExecutorErrorInvalidDataStream case ExecutorError_EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE: 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 } @@ -700,12 +694,6 @@ func ExecutorErrorCode(err error) ExecutorError { 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 - 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 029c84186f..7ee33be204 100644 --- a/state/runtime/executor/executor.pb.go +++ b/state/runtime/executor/executor.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.31.0 -// protoc v4.25.1 +// protoc-gen-go v1.32.0 +// protoc v4.25.3 // source: executor.proto package executor @@ -438,12 +438,6 @@ const ( 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 - // 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. @@ -566,9 +560,6 @@ var ( 114: "EXECUTOR_ERROR_INVALID_CBOR", 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, @@ -688,9 +679,6 @@ var ( "EXECUTOR_ERROR_INVALID_CBOR": 114, "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, } ) @@ -4852,7 +4840,7 @@ var file_executor_proto_rawDesc = []byte{ 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, 0x9f, 0x2c, 0x0a, 0x0d, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, + 0x4d, 0x50, 0x10, 0x22, 0x2a, 0xb9, 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, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, @@ -5200,35 +5188,29 @@ var file_executor_proto_rawDesc = []byte{ 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, 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, + 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/executor/executor_grpc.pb.go b/state/runtime/executor/executor_grpc.pb.go index f1d2d5ff08..5333b33a0d 100644 --- a/state/runtime/executor/executor_grpc.pb.go +++ b/state/runtime/executor/executor_grpc.pb.go @@ -1,7 +1,7 @@ // Code generated by protoc-gen-go-grpc. DO NOT EDIT. // versions: // - protoc-gen-go-grpc v1.3.0 -// - protoc v4.25.1 +// - protoc v4.25.3 // source: executor.proto package executor diff --git a/state/runtime/runtime.go b/state/runtime/runtime.go index 63e446746e..f1c1bd80f3 100644 --- a/state/runtime/runtime.go +++ b/state/runtime/runtime.go @@ -319,12 +319,6 @@ var ( 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") - // ErrExecutorErrorOOG2 indicates that an out of gas has occurred - ErrExecutorErrorOOG2 = errors.New("out of gas 2") - // ErrExecutorErrorCloseBatch indicates that batch must be closed - ErrExecutorErrorCloseBatch = errors.New("close batch") // GRPC ERRORS // =========== diff --git a/state/test/forkid_etrog/etrog_test.go b/state/test/forkid_etrog/etrog_test.go index 4be5ba1abb..d8dfd77398 100644 --- a/state/test/forkid_etrog/etrog_test.go +++ b/state/test/forkid_etrog/etrog_test.go @@ -2,25 +2,17 @@ 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" ) @@ -139,134 +131,3 @@ 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/state/trace.go b/state/trace.go index 26b00a8048..88bea79c86 100644 --- a/state/trace.go +++ b/state/trace.go @@ -269,7 +269,7 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has endTime = time.Now() if err != nil { return nil, err - } else if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { + } else if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR { err = executor.ExecutorErr(processBatchResponseV2.Error) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2) return nil, err @@ -539,7 +539,7 @@ func (s *State) buildTrace(evm *fakevm.FakeEVM, result *runtime.ExecutionResult, if previousStep.Depth > step.Depth && previousStep.OpCode != "REVERT" { var gasUsed uint64 var err error - if errors.Is(previousStep.Error, runtime.ErrOutOfGas) || errors.Is(previousStep.Error, runtime.ErrExecutorErrorOOG2) { + if errors.Is(previousStep.Error, runtime.ErrOutOfGas) { itCtx, err := internalTxSteps.Pop() if err != nil { return nil, err diff --git a/state/transaction.go b/state/transaction.go index 488c13295f..7e3335822c 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -581,7 +581,7 @@ func (s *State) internalProcessUnsignedTransactionV2(ctx context.Context, tx *ty } } - if err == nil && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { + if err == nil && processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR { err = executor.ExecutorErr(processBatchResponseV2.Error) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2) return nil, err @@ -1012,21 +1012,15 @@ func (s *State) internalTestGasEstimationTransactionV2(ctx context.Context, batc txExecutionOnExecutorTime := time.Now() processBatchResponseV2, err := s.executorClient.ProcessBatchV2(ctx, processBatchRequestV2) log.Debugf("executor time: %vms", time.Since(txExecutionOnExecutorTime).Milliseconds()) - if err != nil && !errors.Is(err, runtime.ErrExecutorErrorOOG2) { + if err != nil { log.Errorf("error estimating gas: %v", err) return false, false, gasUsed, nil, err } - if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR && - processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_CLOSE_BATCH { - if processBatchResponseV2.Error == executor.ExecutorError_EXECUTOR_ERROR_OOG_2 { - return true, false, gasUsed, nil, nil - } - + if processBatchResponseV2.Error != executor.ExecutorError_EXECUTOR_ERROR_NO_ERROR { err = executor.ExecutorErr(processBatchResponseV2.Error) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2) return false, false, gasUsed, nil, err } - if processBatchResponseV2.ErrorRom != executor.RomError_ROM_ERROR_NO_ERROR { err = executor.RomErr(processBatchResponseV2.ErrorRom) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2) diff --git a/state/types.go b/state/types.go index e8897a2791..10b3f64cb2 100644 --- a/state/types.go +++ b/state/types.go @@ -65,7 +65,6 @@ type ProcessBatchResponse struct { ForkID uint64 InvalidBatch_V2 bool RomError_V2 error - CloseBatch_V2 bool } // ProcessBlockResponse represents the response of a block diff --git a/test/contracts/auto/customModExp.sol b/test/contracts/auto/customModExp.sol deleted file mode 100644 index b1926aa4f0..0000000000 --- a/test/contracts/auto/customModExp.sol +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-License-Identifier: MIT -pragma solidity >=0.7.0 <0.9.0; - -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 From 5a5a64223f007982483247ac8e723692b04f2ce7 Mon Sep 17 00:00:00 2001 From: Joan Esteban <129153821+joanestebanr@users.noreply.github.com> Date: Tue, 20 Feb 2024 22:15:21 +0100 Subject: [PATCH 16/51] support to elderberry fork (#3301) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * add new sequenceBatches parameters * update SMC Elderberry, contract dockers and genesis * elderberry seq-sender (#3312) * elderberry seq-sender * updated prover image to v5.0.0-RC4 * increase timeout to e2e-group7 --------- Co-authored-by: Toni Ramírez <58293609+ToniRamirezM@users.noreply.github.com> Co-authored-by: dPunisher --- docker-compose.yml | 2 +- etherman/etherman.go | 108 +- etherman/etherman_test.go | 18 +- .../smartcontracts/abi/etrogpolygonzkevm.abi | 1210 ++++++ etherman/smartcontracts/abi/polygonzkevm.abi | 2368 ++++++------ .../smartcontracts/bin/etrogpolygonzkevm.bin | 1 + etherman/smartcontracts/bin/polygonzkevm.bin | 2 +- .../etrogpolygonzkevm/etrogpolygonzkevm.go | 3258 +++++++++++++++++ .../polygonzkevm/polygonzkevm.go | 248 +- etherman/smartcontracts/script.sh | 1 + etherman/types.go | 8 + etherman/types/sequence.go | 2 +- sequencesender/interfaces.go | 4 +- sequencesender/mock_etherman.go | 40 +- sequencesender/sequencesender.go | 44 +- synchronizer/actions/elderberry/elderberry.go | 10 + .../elderberry/mocks/previous_processor.go | 141 + .../state_l1_sequence_batches_elderberry.go | 157 + .../processor_l1_sequence_batches.go | 126 + .../processor_l1_sequence_batches_test.go | 15 + .../etrog/processor_l1_sequence_batches.go | 5 +- .../mocks/state_full_interface.go | 60 + synchronizer/common/syncinterfaces/state.go | 1 + synchronizer/default_l1processors.go | 5 +- synchronizer/synchronizer.go | 6 +- synchronizer/synchronizer_test.go | 10 - test/Makefile | 8 +- test/config/test.genesis.config.json | 184 +- test/config/test.node.config.toml | 2 +- test/docker-compose.yml | 6 +- test/e2e/jsonrpc2_test.go | 4 + test/e2e/shared.go | 3 +- test/scripts/batchsender/main.go | 11 +- 33 files changed, 6485 insertions(+), 1583 deletions(-) create mode 100644 etherman/smartcontracts/abi/etrogpolygonzkevm.abi create mode 100644 etherman/smartcontracts/bin/etrogpolygonzkevm.bin create mode 100644 etherman/smartcontracts/etrogpolygonzkevm/etrogpolygonzkevm.go create mode 100644 synchronizer/actions/elderberry/elderberry.go create mode 100644 synchronizer/actions/elderberry/mocks/previous_processor.go create mode 100644 synchronizer/actions/elderberry/mocks/state_l1_sequence_batches_elderberry.go create mode 100644 synchronizer/actions/elderberry/processor_l1_sequence_batches.go create mode 100644 synchronizer/actions/elderberry/processor_l1_sequence_batches_test.go diff --git a/docker-compose.yml b/docker-compose.yml index e5dda3a1dc..36fbfe070d 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.14 + image: hermeznetwork/zkevm-prover:v5.0.0-RC4 depends_on: zkevm-state-db: condition: service_healthy diff --git a/etherman/etherman.go b/etherman/etherman.go index ab81da0f8d..aba46dcca0 100644 --- a/etherman/etherman.go +++ b/etherman/etherman.go @@ -1,6 +1,7 @@ package etherman import ( + "bytes" "context" "encoding/json" "errors" @@ -16,6 +17,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/etherman/etherscan" "github.com/0xPolygonHermez/zkevm-node/etherman/ethgasstation" "github.com/0xPolygonHermez/zkevm-node/etherman/metrics" + "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/etrogpolygonzkevm" "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/oldpolygonzkevm" "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/oldpolygonzkevmglobalexitroot" "github.com/0xPolygonHermez/zkevm-node/etherman/smartcontracts/pol" @@ -99,6 +101,11 @@ var ( beaconUpgradedSignatureHash = crypto.Keccak256Hash([]byte("BeaconUpgraded(address)")) upgradedSignatureHash = crypto.Keccak256Hash([]byte("Upgraded(address)")) + // methodIDSequenceBatchesEtrog: MethodID for sequenceBatches in Etrog + methodIDSequenceBatchesEtrog = []byte{0xec, 0xef, 0x3f, 0x99} // 0xecef3f99 + // methodIDSequenceBatchesElderberry: MethodID for sequenceBatches in Elderberry + methodIDSequenceBatchesElderberry = []byte{0xde, 0xf5, 0x7e, 0x54} // 0xdef57e54 sequenceBatches((bytes,bytes32,uint64,bytes32)[],uint64,uint64,address) + // ErrNotFound is used when the object is not found ErrNotFound = errors.New("not found") // ErrIsReadOnlyMode is used when the EtherMan client is in read-only mode. @@ -174,6 +181,7 @@ type externalGasProviders struct { type Client struct { EthClient ethereumClient OldZkEVM *oldpolygonzkevm.Oldpolygonzkevm + EtrogZKEVM *etrogpolygonzkevm.Etrogpolygonzkevm ZkEVM *polygonzkevm.Polygonzkevm RollupManager *polygonrollupmanager.Polygonrollupmanager GlobalExitRootManager *polygonzkevmglobalexitroot.Polygonzkevmglobalexitroot @@ -204,6 +212,11 @@ func NewClient(cfg Config, l1Config L1Config) (*Client, error) { log.Errorf("error creating Polygonzkevm client (%s). Error: %w", l1Config.ZkEVMAddr.String(), err) return nil, err } + etrogZkevm, err := etrogpolygonzkevm.NewEtrogpolygonzkevm(l1Config.RollupManagerAddr, ethClient) + if err != nil { + log.Errorf("error creating NewEtrogPolygonzkevm client (%s). Error: %w", l1Config.RollupManagerAddr.String(), err) + return nil, err + } oldZkevm, err := oldpolygonzkevm.NewOldpolygonzkevm(l1Config.RollupManagerAddr, ethClient) if err != nil { log.Errorf("error creating NewOldpolygonzkevm client (%s). Error: %w", l1Config.RollupManagerAddr.String(), err) @@ -254,6 +267,7 @@ func NewClient(cfg Config, l1Config L1Config) (*Client, error) { return &Client{ EthClient: ethClient, ZkEVM: zkevm, + EtrogZKEVM: etrogZkevm, OldZkEVM: oldZkevm, RollupManager: rollupManager, Pol: pol, @@ -680,7 +694,7 @@ func (etherMan *Client) addExistingRollup(ctx context.Context, vLog types.Log, b func (etherMan *Client) updateEtrogSequence(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error { log.Debug("updateEtrogSequence event detected") - updateEtrogSequence, err := etherMan.ZkEVM.ParseUpdateEtrogSequence(vLog) + updateEtrogSequence, err := etherMan.EtrogZKEVM.ParseUpdateEtrogSequence(vLog) if err != nil { log.Error("error parsing updateEtrogSequence event. Error: ", err) return err @@ -927,14 +941,14 @@ func (etherMan *Client) WaitTxToBeMined(ctx context.Context, tx *types.Transacti } // EstimateGasSequenceBatches estimates gas for sending batches -func (etherMan *Client) EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, l2Coinbase common.Address) (*types.Transaction, error) { +func (etherMan *Client) EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address) (*types.Transaction, error) { opts, err := etherMan.getAuthByAddress(sender) if err == ErrNotFound { return nil, ErrPrivateKeyNotFound } opts.NoSend = true - tx, err := etherMan.sequenceBatches(opts, sequences, l2Coinbase) + tx, err := etherMan.sequenceBatches(opts, sequences, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase) if err != nil { return nil, err } @@ -943,7 +957,7 @@ func (etherMan *Client) EstimateGasSequenceBatches(sender common.Address, sequen } // BuildSequenceBatchesTxData builds a []bytes to be sent to the PoE SC method SequenceBatches. -func (etherMan *Client) BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, l2Coinbase common.Address) (to *common.Address, data []byte, err error) { +func (etherMan *Client) BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address) (to *common.Address, data []byte, err error) { opts, err := etherMan.getAuthByAddress(sender) if err == ErrNotFound { return nil, nil, fmt.Errorf("failed to build sequence batches, err: %w", ErrPrivateKeyNotFound) @@ -954,7 +968,7 @@ func (etherMan *Client) BuildSequenceBatchesTxData(sender common.Address, sequen opts.GasLimit = uint64(1) opts.GasPrice = big.NewInt(1) - tx, err := etherMan.sequenceBatches(opts, sequences, l2Coinbase) + tx, err := etherMan.sequenceBatches(opts, sequences, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase) if err != nil { return nil, nil, err } @@ -962,7 +976,7 @@ func (etherMan *Client) BuildSequenceBatchesTxData(sender common.Address, sequen return tx.To(), tx.Data(), nil } -func (etherMan *Client) sequenceBatches(opts bind.TransactOpts, sequences []ethmanTypes.Sequence, l2Coinbase common.Address) (*types.Transaction, error) { +func (etherMan *Client) sequenceBatches(opts bind.TransactOpts, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, lastSequencedBatchNumber uint64, l2Coinbase common.Address) (*types.Transaction, error) { var batches []polygonzkevm.PolygonRollupBaseEtrogBatchData for _, seq := range sequences { var ger common.Hash @@ -979,7 +993,7 @@ func (etherMan *Client) sequenceBatches(opts bind.TransactOpts, sequences []ethm batches = append(batches, batch) } - tx, err := etherMan.ZkEVM.SequenceBatches(&opts, batches, l2Coinbase) + tx, err := etherMan.ZkEVM.SequenceBatches(&opts, batches, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase) if err != nil { log.Debugf("Batches to send: %+v", batches) log.Debug("l2CoinBase: ", l2Coinbase) @@ -988,7 +1002,7 @@ func (etherMan *Client) sequenceBatches(opts bind.TransactOpts, sequences []ethm if err2 != nil { log.Error("error getting abi. Error: ", err2) } - input, err3 := a.Pack("sequenceBatches", batches, l2Coinbase) + input, err3 := a.Pack("sequenceBatches", batches, maxSequenceTimestamp, lastSequencedBatchNumber, l2Coinbase) if err3 != nil { log.Error("error packing call. Error: ", err3) } @@ -1174,7 +1188,9 @@ func (etherMan *Client) forcedBatchEvent(ctx context.Context, vLog types.Log, bl } func (etherMan *Client) sequencedBatchesEvent(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error { - log.Debug("SequenceBatches event detected") + log.Debugf("SequenceBatches event detected: txHash: %s", common.Bytes2Hex(vLog.TxHash[:])) + //tx,isPending, err:=etherMan.EthClient.TransactionByHash(ctx, vLog.TxHash) + sb, err := etherMan.ZkEVM.ParseSequenceBatches(vLog) if err != nil { return err @@ -1195,9 +1211,20 @@ func (etherMan *Client) sequencedBatchesEvent(ctx context.Context, vLog types.Lo var sequences []SequencedBatch if sb.NumBatch != 1 { - sequences, err = decodeSequences(tx.Data(), sb.NumBatch, msg.From, vLog.TxHash, msg.Nonce, sb.L1InfoRoot) - if err != nil { - return fmt.Errorf("error decoding the sequences: %v", err) + methodId := tx.Data()[:4] + log.Debugf("MethodId: %s", common.Bytes2Hex(methodId)) + if bytes.Equal(methodId, methodIDSequenceBatchesEtrog) { + sequences, err = decodeSequencesEtrog(tx.Data(), sb.NumBatch, msg.From, vLog.TxHash, msg.Nonce, sb.L1InfoRoot) + if err != nil { + return fmt.Errorf("error decoding the sequences (etrog): %v", err) + } + } else if bytes.Equal(methodId, methodIDSequenceBatchesElderberry) { + sequences, err = decodeSequencesElderberry(tx.Data(), sb.NumBatch, msg.From, vLog.TxHash, msg.Nonce, sb.L1InfoRoot) + if err != nil { + return fmt.Errorf("error decoding the sequences (elderberry): %v", err) + } + } else { + return fmt.Errorf("error decoding the sequences: methodId %s unknown", common.Bytes2Hex(methodId)) } } else { log.Info("initial transaction sequence...") @@ -1278,7 +1305,62 @@ func (etherMan *Client) sequencedBatchesPreEtrogEvent(ctx context.Context, vLog return nil } -func decodeSequences(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64, l1InfoRoot common.Hash) ([]SequencedBatch, error) { +func decodeSequencesElderberry(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64, l1InfoRoot common.Hash) ([]SequencedBatch, error) { + // Extract coded txs. + // Load contract ABI + smcAbi, err := abi.JSON(strings.NewReader(polygonzkevm.PolygonzkevmABI)) + if err != nil { + return nil, err + } + + // Recover Method from signature and ABI + method, err := smcAbi.MethodById(txData[:4]) + if err != nil { + return nil, err + } + + // Unpack method inputs + data, err := method.Inputs.Unpack(txData[4:]) + if err != nil { + return nil, err + } + var sequences []polygonzkevm.PolygonRollupBaseEtrogBatchData + bytedata, err := json.Marshal(data[0]) + if err != nil { + return nil, err + } + err = json.Unmarshal(bytedata, &sequences) + if err != nil { + return nil, err + } + maxSequenceTimestamp := data[1].(uint64) + initSequencedBatchNumber := data[2].(uint64) + coinbase := (data[3]).(common.Address) + sequencedBatches := make([]SequencedBatch, len(sequences)) + + for i, seq := range sequences { + elderberry := SequencedBatchElderberryData{ + MaxSequenceTimestamp: maxSequenceTimestamp, + InitSequencedBatchNumber: initSequencedBatchNumber, + } + bn := lastBatchNumber - uint64(len(sequences)-(i+1)) + s := seq + sequencedBatches[i] = SequencedBatch{ + BatchNumber: bn, + L1InfoRoot: &l1InfoRoot, + SequencerAddr: sequencer, + TxHash: txHash, + Nonce: nonce, + Coinbase: coinbase, + PolygonRollupBaseEtrogBatchData: &s, + SequencedBatchElderberryData: &elderberry, + } + } + + return sequencedBatches, nil +} + +func decodeSequencesEtrog(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64, l1InfoRoot common.Hash) ([]SequencedBatch, error) { // Extract coded txs. // Load contract ABI smcAbi, err := abi.JSON(strings.NewReader(polygonzkevm.PolygonzkevmABI)) diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go index 653035e331..789e2831af 100644 --- a/etherman/etherman_test.go +++ b/etherman/etherman_test.go @@ -123,6 +123,9 @@ func TestForcedBatchEvent(t *testing.T) { assert.Equal(t, auth.From, blocks[0].ForcedBatches[0].Sequencer) } +// TODO: Review tests with Joan + +/* func TestSequencedBatchesEvent(t *testing.T) { // Set up testing environment etherman, ethBackend, auth, _, br := newTestingEnv() @@ -162,7 +165,8 @@ func TestSequencedBatchesEvent(t *testing.T) { }, polygonzkevm.PolygonRollupBaseEtrogBatchData{ Transactions: common.Hex2Bytes(rawTxs), }) - _, err = etherman.ZkEVM.SequenceBatches(auth, sequences, auth.From) + // TODO: Fix params + _, err = etherman.ZkEVM.SequenceBatches(auth, sequences, 0, 0, auth.From) require.NoError(t, err) // Mine the tx in a block @@ -200,7 +204,8 @@ func TestVerifyBatchEvent(t *testing.T) { tx := polygonzkevm.PolygonRollupBaseEtrogBatchData{ Transactions: common.Hex2Bytes(rawTxs), } - _, err = etherman.ZkEVM.SequenceBatches(auth, []polygonzkevm.PolygonRollupBaseEtrogBatchData{tx}, auth.From) + //TODO: Fix params + _, err = etherman.ZkEVM.SequenceBatches(auth, []polygonzkevm.PolygonRollupBaseEtrogBatchData{tx}, 0, 0, auth.From) require.NoError(t, err) // Mine the tx in a block @@ -228,6 +233,7 @@ func TestVerifyBatchEvent(t *testing.T) { assert.Equal(t, 0, order[blocks[1].BlockHash][0].Pos) assert.Equal(t, 0, order[blocks[1].BlockHash][1].Pos) } +*/ func TestSequenceForceBatchesEvent(t *testing.T) { // Set up testing environment @@ -310,9 +316,13 @@ func TestSendSequences(t *testing.T) { batchL2Data, err := state.EncodeTransactions([]types.Transaction{*tx1}, constants.EffectivePercentage, forkID6) require.NoError(t, err) sequence := ethmanTypes.Sequence{ - BatchL2Data: batchL2Data, + BatchNumber: 0, + BatchL2Data: batchL2Data, + LastL2BLockTimestamp: time.Now().Unix(), } - tx, err := etherman.sequenceBatches(*auth, []ethmanTypes.Sequence{sequence}, auth.From) + lastL2BlockTStamp := tx1.Time().Unix() + // TODO: fix params + tx, err := etherman.sequenceBatches(*auth, []ethmanTypes.Sequence{sequence}, uint64(lastL2BlockTStamp), uint64(1), auth.From) require.NoError(t, err) log.Debug("TX: ", tx.Hash()) ethBackend.Commit() diff --git a/etherman/smartcontracts/abi/etrogpolygonzkevm.abi b/etherman/smartcontracts/abi/etrogpolygonzkevm.abi new file mode 100644 index 0000000000..6b4f9c24df --- /dev/null +++ b/etherman/smartcontracts/abi/etrogpolygonzkevm.abi @@ -0,0 +1,1210 @@ +[ + { + "inputs": [ + { + "internalType": "contract IPolygonZkEVMGlobalExitRootV2", + "name": "_globalExitRootManager", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "_pol", + "type": "address" + }, + { + "internalType": "contract IPolygonZkEVMBridgeV2", + "name": "_bridgeAddress", + "type": "address" + }, + { + "internalType": "contract PolygonRollupManager", + "name": "_rollupManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BatchAlreadyVerified", + "type": "error" + }, + { + "inputs": [], + "name": "BatchNotSequencedOrNotSequenceEnd", + "type": "error" + }, + { + "inputs": [], + "name": "ExceedMaxVerifyBatches", + "type": "error" + }, + { + "inputs": [], + "name": "FinalNumBatchBelowLastVerifiedBatch", + "type": "error" + }, + { + "inputs": [], + "name": "FinalNumBatchDoesNotMatchPendingState", + "type": "error" + }, + { + "inputs": [], + "name": "FinalPendingStateNumInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchTimeoutNotExpired", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchesAlreadyActive", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchesDecentralized", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchesNotAllowedOnEmergencyState", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchesOverflow", + "type": "error" + }, + { + "inputs": [], + "name": "ForcedDataDoesNotMatch", + "type": "error" + }, + { + "inputs": [], + "name": "GasTokenNetworkMustBeZeroOnEther", + "type": "error" + }, + { + "inputs": [], + "name": "GlobalExitRootNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "HaltTimeoutNotExpired", + "type": "error" + }, + { + "inputs": [], + "name": "HaltTimeoutNotExpiredAfterEmergencyState", + "type": "error" + }, + { + "inputs": [], + "name": "HugeTokenMetadataNotSupported", + "type": "error" + }, + { + "inputs": [], + "name": "InitNumBatchAboveLastVerifiedBatch", + "type": "error" + }, + { + "inputs": [], + "name": "InitNumBatchDoesNotMatchPendingState", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitializeTransaction", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidProof", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRangeBatchTimeTarget", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRangeForceBatchTimeout", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRangeMultiplierBatchFee", + "type": "error" + }, + { + "inputs": [], + "name": "NewAccInputHashDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "NewPendingStateTimeoutMustBeLower", + "type": "error" + }, + { + "inputs": [], + "name": "NewStateRootNotInsidePrime", + "type": "error" + }, + { + "inputs": [], + "name": "NewTrustedAggregatorTimeoutMustBeLower", + "type": "error" + }, + { + "inputs": [], + "name": "NotEnoughMaticAmount", + "type": "error" + }, + { + "inputs": [], + "name": "NotEnoughPOLAmount", + "type": "error" + }, + { + "inputs": [], + "name": "OldAccInputHashDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "OldStateRootDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyAdmin", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingAdmin", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyRollupManager", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyTrustedAggregator", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyTrustedSequencer", + "type": "error" + }, + { + "inputs": [], + "name": "PendingStateDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "PendingStateInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "PendingStateNotConsolidable", + "type": "error" + }, + { + "inputs": [], + "name": "PendingStateTimeoutExceedHaltAggregationTimeout", + "type": "error" + }, + { + "inputs": [], + "name": "SequenceZeroBatches", + "type": "error" + }, + { + "inputs": [], + "name": "SequencedTimestampBelowForcedTimestamp", + "type": "error" + }, + { + "inputs": [], + "name": "SequencedTimestampInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "StoredRootMustBeDifferentThanNewRoot", + "type": "error" + }, + { + "inputs": [], + "name": "TransactionsLengthAboveMax", + "type": "error" + }, + { + "inputs": [], + "name": "TrustedAggregatorTimeoutExceedHaltAggregationTimeout", + "type": "error" + }, + { + "inputs": [], + "name": "TrustedAggregatorTimeoutNotExpired", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AcceptAdminRole", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "forceBatchNum", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "lastGlobalExitRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "sequencer", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + } + ], + "name": "ForceBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "lastGlobalExitRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "sequencer", + "type": "address" + } + ], + "name": "InitialSequenceBatches", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "numBatch", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "l1InfoRoot", + "type": "bytes32" + } + ], + "name": "SequenceBatches", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "numBatch", + "type": "uint64" + } + ], + "name": "SequenceForceBatches", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newForceBatchAddress", + "type": "address" + } + ], + "name": "SetForceBatchAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "newforceBatchTimeout", + "type": "uint64" + } + ], + "name": "SetForceBatchTimeout", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newTrustedSequencer", + "type": "address" + } + ], + "name": "SetTrustedSequencer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "newTrustedSequencerURL", + "type": "string" + } + ], + "name": "SetTrustedSequencerURL", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "TransferAdminRole", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "numBatch", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "lastGlobalExitRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "sequencer", + "type": "address" + } + ], + "name": "UpdateEtrogSequence", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "numBatch", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "stateRoot", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "aggregator", + "type": "address" + } + ], + "name": "VerifyBatches", + "type": "event" + }, + { + "inputs": [], + "name": "GLOBAL_EXIT_ROOT_MANAGER_L2", + "outputs": [ + { + "internalType": "contract IBasePolygonZkEVMGlobalExitRoot", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_BRIDGE_LIST_LEN_LEN", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_BRIDGE_PARAMS", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS_EMPTY_METADATA", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_CONSTANT_BYTES", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_CONSTANT_BYTES_EMPTY_METADATA", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_DATA_LEN_EMPTY_METADATA", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_EFFECTIVE_PERCENTAGE", + "outputs": [ + { + "internalType": "bytes1", + "name": "", + "type": "bytes1" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SET_UP_ETROG_TX", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SIGNATURE_INITIALIZE_TX_R", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SIGNATURE_INITIALIZE_TX_S", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SIGNATURE_INITIALIZE_TX_V", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptAdminRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bridgeAddress", + "outputs": [ + { + "internalType": "contract IPolygonZkEVMBridgeV2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "calculatePolPerForceBatch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "polAmount", + "type": "uint256" + } + ], + "name": "forceBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "forceBatchAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "forceBatchTimeout", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "name": "forcedBatches", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasTokenNetwork", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "networkID", + "type": "uint32" + }, + { + "internalType": "address", + "name": "_gasTokenAddress", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_gasTokenNetwork", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_gasTokenMetadata", + "type": "bytes" + } + ], + "name": "generateInitializeTransaction", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "globalExitRootManager", + "outputs": [ + { + "internalType": "contract IPolygonZkEVMGlobalExitRootV2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "address", + "name": "sequencer", + "type": "address" + }, + { + "internalType": "uint32", + "name": "networkID", + "type": "uint32" + }, + { + "internalType": "address", + "name": "_gasTokenAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "sequencerURL", + "type": "string" + }, + { + "internalType": "string", + "name": "_networkName", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "address", + "name": "_trustedSequencer", + "type": "address" + }, + { + "internalType": "string", + "name": "_trustedSequencerURL", + "type": "string" + }, + { + "internalType": "string", + "name": "_networkName", + "type": "string" + }, + { + "internalType": "bytes32", + "name": "_lastAccInputHash", + "type": "bytes32" + } + ], + "name": "initializeUpgrade", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastAccInputHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastForceBatch", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastForceBatchSequenced", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "networkName", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "lastVerifiedBatch", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "newStateRoot", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "aggregator", + "type": "address" + } + ], + "name": "onVerifyBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pol", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rollupManager", + "outputs": [ + { + "internalType": "contract PolygonRollupManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "forcedGlobalExitRoot", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "forcedTimestamp", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "forcedBlockHashL1", + "type": "bytes32" + } + ], + "internalType": "struct PolygonRollupBaseEtrog.BatchData[]", + "name": "batches", + "type": "tuple[]" + }, + { + "internalType": "address", + "name": "l2Coinbase", + "type": "address" + } + ], + "name": "sequenceBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "forcedGlobalExitRoot", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "forcedTimestamp", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "forcedBlockHashL1", + "type": "bytes32" + } + ], + "internalType": "struct PolygonRollupBaseEtrog.BatchData[]", + "name": "batches", + "type": "tuple[]" + } + ], + "name": "sequenceForceBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newForceBatchAddress", + "type": "address" + } + ], + "name": "setForceBatchAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "newforceBatchTimeout", + "type": "uint64" + } + ], + "name": "setForceBatchTimeout", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newTrustedSequencer", + "type": "address" + } + ], + "name": "setTrustedSequencer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newTrustedSequencerURL", + "type": "string" + } + ], + "name": "setTrustedSequencerURL", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "transferAdminRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "trustedSequencer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "trustedSequencerURL", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/etherman/smartcontracts/abi/polygonzkevm.abi b/etherman/smartcontracts/abi/polygonzkevm.abi index 6b4f9c24df..590fd198f1 100644 --- a/etherman/smartcontracts/abi/polygonzkevm.abi +++ b/etherman/smartcontracts/abi/polygonzkevm.abi @@ -1,1210 +1,1166 @@ [ - { - "inputs": [ - { - "internalType": "contract IPolygonZkEVMGlobalExitRootV2", - "name": "_globalExitRootManager", - "type": "address" - }, - { - "internalType": "contract IERC20Upgradeable", - "name": "_pol", - "type": "address" - }, - { - "internalType": "contract IPolygonZkEVMBridgeV2", - "name": "_bridgeAddress", - "type": "address" - }, - { - "internalType": "contract PolygonRollupManager", - "name": "_rollupManager", - "type": "address" - } + { + "inputs": [ + { + "internalType": "contract IPolygonZkEVMGlobalExitRootV2", + "name": "_globalExitRootManager", + "type": "address" + }, + { + "internalType": "contract IERC20Upgradeable", + "name": "_pol", + "type": "address" + }, + { + "internalType": "contract IPolygonZkEVMBridgeV2", + "name": "_bridgeAddress", + "type": "address" + }, + { + "internalType": "contract PolygonRollupManager", + "name": "_rollupManager", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "inputs": [], + "name": "BatchAlreadyVerified", + "type": "error" + }, + { + "inputs": [], + "name": "BatchNotSequencedOrNotSequenceEnd", + "type": "error" + }, + { + "inputs": [], + "name": "ExceedMaxVerifyBatches", + "type": "error" + }, + { + "inputs": [], + "name": "FinalNumBatchBelowLastVerifiedBatch", + "type": "error" + }, + { + "inputs": [], + "name": "FinalNumBatchDoesNotMatchPendingState", + "type": "error" + }, + { + "inputs": [], + "name": "FinalPendingStateNumInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchNotAllowed", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchTimeoutNotExpired", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchesAlreadyActive", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchesDecentralized", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchesNotAllowedOnEmergencyState", + "type": "error" + }, + { + "inputs": [], + "name": "ForceBatchesOverflow", + "type": "error" + }, + { + "inputs": [], + "name": "ForcedDataDoesNotMatch", + "type": "error" + }, + { + "inputs": [], + "name": "GasTokenNetworkMustBeZeroOnEther", + "type": "error" + }, + { + "inputs": [], + "name": "GlobalExitRootNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "HaltTimeoutNotExpired", + "type": "error" + }, + { + "inputs": [], + "name": "HaltTimeoutNotExpiredAfterEmergencyState", + "type": "error" + }, + { + "inputs": [], + "name": "HugeTokenMetadataNotSupported", + "type": "error" + }, + { + "inputs": [], + "name": "InitNumBatchAboveLastVerifiedBatch", + "type": "error" + }, + { + "inputs": [], + "name": "InitNumBatchDoesNotMatchPendingState", + "type": "error" + }, + { + "inputs": [], + "name": "InitSequencedBatchDoesNotMatch", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidInitializeTransaction", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidProof", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRangeBatchTimeTarget", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRangeForceBatchTimeout", + "type": "error" + }, + { + "inputs": [], + "name": "InvalidRangeMultiplierBatchFee", + "type": "error" + }, + { + "inputs": [], + "name": "MaxTimestampSequenceInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "NewAccInputHashDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "NewPendingStateTimeoutMustBeLower", + "type": "error" + }, + { + "inputs": [], + "name": "NewStateRootNotInsidePrime", + "type": "error" + }, + { + "inputs": [], + "name": "NewTrustedAggregatorTimeoutMustBeLower", + "type": "error" + }, + { + "inputs": [], + "name": "NotEnoughMaticAmount", + "type": "error" + }, + { + "inputs": [], + "name": "NotEnoughPOLAmount", + "type": "error" + }, + { + "inputs": [], + "name": "OldAccInputHashDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "OldStateRootDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyAdmin", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyPendingAdmin", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyRollupManager", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyTrustedAggregator", + "type": "error" + }, + { + "inputs": [], + "name": "OnlyTrustedSequencer", + "type": "error" + }, + { + "inputs": [], + "name": "PendingStateDoesNotExist", + "type": "error" + }, + { + "inputs": [], + "name": "PendingStateInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "PendingStateNotConsolidable", + "type": "error" + }, + { + "inputs": [], + "name": "PendingStateTimeoutExceedHaltAggregationTimeout", + "type": "error" + }, + { + "inputs": [], + "name": "SequenceZeroBatches", + "type": "error" + }, + { + "inputs": [], + "name": "SequencedTimestampBelowForcedTimestamp", + "type": "error" + }, + { + "inputs": [], + "name": "SequencedTimestampInvalid", + "type": "error" + }, + { + "inputs": [], + "name": "StoredRootMustBeDifferentThanNewRoot", + "type": "error" + }, + { + "inputs": [], + "name": "TransactionsLengthAboveMax", + "type": "error" + }, + { + "inputs": [], + "name": "TrustedAggregatorTimeoutExceedHaltAggregationTimeout", + "type": "error" + }, + { + "inputs": [], + "name": "TrustedAggregatorTimeoutNotExpired", + "type": "error" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newAdmin", + "type": "address" + } + ], + "name": "AcceptAdminRole", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "forceBatchNum", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "lastGlobalExitRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "sequencer", + "type": "address" + }, + { + "indexed": false, + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + } + ], + "name": "ForceBatch", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "lastGlobalExitRoot", + "type": "bytes32" + }, + { + "indexed": false, + "internalType": "address", + "name": "sequencer", + "type": "address" + } + ], + "name": "InitialSequenceBatches", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint8", + "name": "version", + "type": "uint8" + } + ], + "name": "Initialized", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "numBatch", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "l1InfoRoot", + "type": "bytes32" + } + ], + "name": "SequenceBatches", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "numBatch", + "type": "uint64" + } + ], + "name": "SequenceForceBatches", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newForceBatchAddress", + "type": "address" + } + ], + "name": "SetForceBatchAddress", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint64", + "name": "newforceBatchTimeout", + "type": "uint64" + } + ], + "name": "SetForceBatchTimeout", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newTrustedSequencer", + "type": "address" + } + ], + "name": "SetTrustedSequencer", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "string", + "name": "newTrustedSequencerURL", + "type": "string" + } + ], + "name": "SetTrustedSequencerURL", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "TransferAdminRole", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": true, + "internalType": "uint64", + "name": "numBatch", + "type": "uint64" + }, + { + "indexed": false, + "internalType": "bytes32", + "name": "stateRoot", + "type": "bytes32" + }, + { + "indexed": true, + "internalType": "address", + "name": "aggregator", + "type": "address" + } + ], + "name": "VerifyBatches", + "type": "event" + }, + { + "inputs": [], + "name": "GLOBAL_EXIT_ROOT_MANAGER_L2", + "outputs": [ + { + "internalType": "contract IBasePolygonZkEVMGlobalExitRoot", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_BRIDGE_LIST_LEN_LEN", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_BRIDGE_PARAMS", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS_EMPTY_METADATA", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_CONSTANT_BYTES", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_CONSTANT_BYTES_EMPTY_METADATA", + "outputs": [ + { + "internalType": "uint16", + "name": "", + "type": "uint16" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_DATA_LEN_EMPTY_METADATA", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "INITIALIZE_TX_EFFECTIVE_PERCENTAGE", + "outputs": [ + { + "internalType": "bytes1", + "name": "", + "type": "bytes1" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SIGNATURE_INITIALIZE_TX_R", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SIGNATURE_INITIALIZE_TX_S", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "SIGNATURE_INITIALIZE_TX_V", + "outputs": [ + { + "internalType": "uint8", + "name": "", + "type": "uint8" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "TIMESTAMP_RANGE", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "acceptAdminRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "admin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "bridgeAddress", + "outputs": [ + { + "internalType": "contract IPolygonZkEVMBridgeV2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "calculatePolPerForceBatch", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + }, + { + "internalType": "uint256", + "name": "polAmount", + "type": "uint256" + } + ], + "name": "forceBatch", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "forceBatchAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "forceBatchTimeout", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "name": "forcedBatches", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasTokenAddress", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "gasTokenNetwork", + "outputs": [ + { + "internalType": "uint32", + "name": "", + "type": "uint32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint32", + "name": "networkID", + "type": "uint32" + }, + { + "internalType": "address", + "name": "_gasTokenAddress", + "type": "address" + }, + { + "internalType": "uint32", + "name": "_gasTokenNetwork", + "type": "uint32" + }, + { + "internalType": "bytes", + "name": "_gasTokenMetadata", + "type": "bytes" + } + ], + "name": "generateInitializeTransaction", + "outputs": [ + { + "internalType": "bytes", + "name": "", + "type": "bytes" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "globalExitRootManager", + "outputs": [ + { + "internalType": "contract IPolygonZkEVMGlobalExitRootV2", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "_admin", + "type": "address" + }, + { + "internalType": "address", + "name": "sequencer", + "type": "address" + }, + { + "internalType": "uint32", + "name": "networkID", + "type": "uint32" + }, + { + "internalType": "address", + "name": "_gasTokenAddress", + "type": "address" + }, + { + "internalType": "string", + "name": "sequencerURL", + "type": "string" + }, + { + "internalType": "string", + "name": "_networkName", + "type": "string" + } + ], + "name": "initialize", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "lastAccInputHash", + "outputs": [ + { + "internalType": "bytes32", + "name": "", + "type": "bytes32" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastForceBatch", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "lastForceBatchSequenced", + "outputs": [ + { + "internalType": "uint64", + "name": "", + "type": "uint64" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "networkName", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "lastVerifiedBatch", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "newStateRoot", + "type": "bytes32" + }, + { + "internalType": "address", + "name": "aggregator", + "type": "address" + } + ], + "name": "onVerifyBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "pendingAdmin", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "pol", + "outputs": [ + { + "internalType": "contract IERC20Upgradeable", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "rollupManager", + "outputs": [ + { + "internalType": "contract PolygonRollupManager", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "forcedGlobalExitRoot", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "forcedTimestamp", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "forcedBlockHashL1", + "type": "bytes32" + } ], - "stateMutability": "nonpayable", - "type": "constructor" - }, - { - "inputs": [], - "name": "BatchAlreadyVerified", - "type": "error" - }, - { - "inputs": [], - "name": "BatchNotSequencedOrNotSequenceEnd", - "type": "error" - }, - { - "inputs": [], - "name": "ExceedMaxVerifyBatches", - "type": "error" - }, - { - "inputs": [], - "name": "FinalNumBatchBelowLastVerifiedBatch", - "type": "error" - }, - { - "inputs": [], - "name": "FinalNumBatchDoesNotMatchPendingState", - "type": "error" - }, - { - "inputs": [], - "name": "FinalPendingStateNumInvalid", - "type": "error" - }, - { - "inputs": [], - "name": "ForceBatchNotAllowed", - "type": "error" - }, - { - "inputs": [], - "name": "ForceBatchTimeoutNotExpired", - "type": "error" - }, - { - "inputs": [], - "name": "ForceBatchesAlreadyActive", - "type": "error" - }, - { - "inputs": [], - "name": "ForceBatchesDecentralized", - "type": "error" - }, - { - "inputs": [], - "name": "ForceBatchesNotAllowedOnEmergencyState", - "type": "error" - }, - { - "inputs": [], - "name": "ForceBatchesOverflow", - "type": "error" - }, - { - "inputs": [], - "name": "ForcedDataDoesNotMatch", - "type": "error" - }, - { - "inputs": [], - "name": "GasTokenNetworkMustBeZeroOnEther", - "type": "error" - }, - { - "inputs": [], - "name": "GlobalExitRootNotExist", - "type": "error" - }, - { - "inputs": [], - "name": "HaltTimeoutNotExpired", - "type": "error" - }, - { - "inputs": [], - "name": "HaltTimeoutNotExpiredAfterEmergencyState", - "type": "error" - }, - { - "inputs": [], - "name": "HugeTokenMetadataNotSupported", - "type": "error" - }, - { - "inputs": [], - "name": "InitNumBatchAboveLastVerifiedBatch", - "type": "error" - }, - { - "inputs": [], - "name": "InitNumBatchDoesNotMatchPendingState", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidInitializeTransaction", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidProof", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRangeBatchTimeTarget", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRangeForceBatchTimeout", - "type": "error" - }, - { - "inputs": [], - "name": "InvalidRangeMultiplierBatchFee", - "type": "error" - }, - { - "inputs": [], - "name": "NewAccInputHashDoesNotExist", - "type": "error" - }, - { - "inputs": [], - "name": "NewPendingStateTimeoutMustBeLower", - "type": "error" - }, - { - "inputs": [], - "name": "NewStateRootNotInsidePrime", - "type": "error" - }, - { - "inputs": [], - "name": "NewTrustedAggregatorTimeoutMustBeLower", - "type": "error" - }, - { - "inputs": [], - "name": "NotEnoughMaticAmount", - "type": "error" - }, - { - "inputs": [], - "name": "NotEnoughPOLAmount", - "type": "error" - }, - { - "inputs": [], - "name": "OldAccInputHashDoesNotExist", - "type": "error" - }, - { - "inputs": [], - "name": "OldStateRootDoesNotExist", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyAdmin", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyPendingAdmin", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyRollupManager", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyTrustedAggregator", - "type": "error" - }, - { - "inputs": [], - "name": "OnlyTrustedSequencer", - "type": "error" - }, - { - "inputs": [], - "name": "PendingStateDoesNotExist", - "type": "error" - }, - { - "inputs": [], - "name": "PendingStateInvalid", - "type": "error" - }, - { - "inputs": [], - "name": "PendingStateNotConsolidable", - "type": "error" - }, - { - "inputs": [], - "name": "PendingStateTimeoutExceedHaltAggregationTimeout", - "type": "error" - }, - { - "inputs": [], - "name": "SequenceZeroBatches", - "type": "error" - }, - { - "inputs": [], - "name": "SequencedTimestampBelowForcedTimestamp", - "type": "error" - }, - { - "inputs": [], - "name": "SequencedTimestampInvalid", - "type": "error" - }, - { - "inputs": [], - "name": "StoredRootMustBeDifferentThanNewRoot", - "type": "error" - }, - { - "inputs": [], - "name": "TransactionsLengthAboveMax", - "type": "error" - }, - { - "inputs": [], - "name": "TrustedAggregatorTimeoutExceedHaltAggregationTimeout", - "type": "error" - }, - { - "inputs": [], - "name": "TrustedAggregatorTimeoutNotExpired", - "type": "error" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newAdmin", - "type": "address" - } + "internalType": "struct PolygonRollupBaseEtrog.BatchData[]", + "name": "batches", + "type": "tuple[]" + }, + { + "internalType": "uint64", + "name": "maxSequenceTimestamp", + "type": "uint64" + }, + { + "internalType": "uint64", + "name": "initSequencedBatch", + "type": "uint64" + }, + { + "internalType": "address", + "name": "l2Coinbase", + "type": "address" + } + ], + "name": "sequenceBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "bytes", + "name": "transactions", + "type": "bytes" + }, + { + "internalType": "bytes32", + "name": "forcedGlobalExitRoot", + "type": "bytes32" + }, + { + "internalType": "uint64", + "name": "forcedTimestamp", + "type": "uint64" + }, + { + "internalType": "bytes32", + "name": "forcedBlockHashL1", + "type": "bytes32" + } ], - "name": "AcceptAdminRole", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint64", - "name": "forceBatchNum", - "type": "uint64" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "lastGlobalExitRoot", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "sequencer", - "type": "address" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "transactions", - "type": "bytes" - } - ], - "name": "ForceBatch", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "bytes", - "name": "transactions", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "lastGlobalExitRoot", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "sequencer", - "type": "address" - } - ], - "name": "InitialSequenceBatches", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint8", - "name": "version", - "type": "uint8" - } - ], - "name": "Initialized", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint64", - "name": "numBatch", - "type": "uint64" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "l1InfoRoot", - "type": "bytes32" - } - ], - "name": "SequenceBatches", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint64", - "name": "numBatch", - "type": "uint64" - } - ], - "name": "SequenceForceBatches", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newForceBatchAddress", - "type": "address" - } - ], - "name": "SetForceBatchAddress", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "newforceBatchTimeout", - "type": "uint64" - } - ], - "name": "SetForceBatchTimeout", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newTrustedSequencer", - "type": "address" - } - ], - "name": "SetTrustedSequencer", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "string", - "name": "newTrustedSequencerURL", - "type": "string" - } - ], - "name": "SetTrustedSequencerURL", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "address", - "name": "newPendingAdmin", - "type": "address" - } - ], - "name": "TransferAdminRole", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": false, - "internalType": "uint64", - "name": "numBatch", - "type": "uint64" - }, - { - "indexed": false, - "internalType": "bytes", - "name": "transactions", - "type": "bytes" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "lastGlobalExitRoot", - "type": "bytes32" - }, - { - "indexed": false, - "internalType": "address", - "name": "sequencer", - "type": "address" - } - ], - "name": "UpdateEtrogSequence", - "type": "event" - }, - { - "anonymous": false, - "inputs": [ - { - "indexed": true, - "internalType": "uint64", - "name": "numBatch", - "type": "uint64" - }, - { - "indexed": false, - "internalType": "bytes32", - "name": "stateRoot", - "type": "bytes32" - }, - { - "indexed": true, - "internalType": "address", - "name": "aggregator", - "type": "address" - } - ], - "name": "VerifyBatches", - "type": "event" - }, - { - "inputs": [], - "name": "GLOBAL_EXIT_ROOT_MANAGER_L2", - "outputs": [ - { - "internalType": "contract IBasePolygonZkEVMGlobalExitRoot", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INITIALIZE_TX_BRIDGE_LIST_LEN_LEN", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INITIALIZE_TX_BRIDGE_PARAMS", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS_EMPTY_METADATA", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INITIALIZE_TX_CONSTANT_BYTES", - "outputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INITIALIZE_TX_CONSTANT_BYTES_EMPTY_METADATA", - "outputs": [ - { - "internalType": "uint16", - "name": "", - "type": "uint16" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INITIALIZE_TX_DATA_LEN_EMPTY_METADATA", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "INITIALIZE_TX_EFFECTIVE_PERCENTAGE", - "outputs": [ - { - "internalType": "bytes1", - "name": "", - "type": "bytes1" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SET_UP_ETROG_TX", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SIGNATURE_INITIALIZE_TX_R", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SIGNATURE_INITIALIZE_TX_S", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "SIGNATURE_INITIALIZE_TX_V", - "outputs": [ - { - "internalType": "uint8", - "name": "", - "type": "uint8" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "acceptAdminRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "admin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "bridgeAddress", - "outputs": [ - { - "internalType": "contract IPolygonZkEVMBridgeV2", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "calculatePolPerForceBatch", - "outputs": [ - { - "internalType": "uint256", - "name": "", - "type": "uint256" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "bytes", - "name": "transactions", - "type": "bytes" - }, - { - "internalType": "uint256", - "name": "polAmount", - "type": "uint256" - } - ], - "name": "forceBatch", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "forceBatchAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "forceBatchTimeout", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "name": "forcedBatches", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "gasTokenAddress", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "gasTokenNetwork", - "outputs": [ - { - "internalType": "uint32", - "name": "", - "type": "uint32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint32", - "name": "networkID", - "type": "uint32" - }, - { - "internalType": "address", - "name": "_gasTokenAddress", - "type": "address" - }, - { - "internalType": "uint32", - "name": "_gasTokenNetwork", - "type": "uint32" - }, - { - "internalType": "bytes", - "name": "_gasTokenMetadata", - "type": "bytes" - } - ], - "name": "generateInitializeTransaction", - "outputs": [ - { - "internalType": "bytes", - "name": "", - "type": "bytes" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "globalExitRootManager", - "outputs": [ - { - "internalType": "contract IPolygonZkEVMGlobalExitRootV2", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - }, - { - "internalType": "address", - "name": "sequencer", - "type": "address" - }, - { - "internalType": "uint32", - "name": "networkID", - "type": "uint32" - }, - { - "internalType": "address", - "name": "_gasTokenAddress", - "type": "address" - }, - { - "internalType": "string", - "name": "sequencerURL", - "type": "string" - }, - { - "internalType": "string", - "name": "_networkName", - "type": "string" - } - ], - "name": "initialize", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "_admin", - "type": "address" - }, - { - "internalType": "address", - "name": "_trustedSequencer", - "type": "address" - }, - { - "internalType": "string", - "name": "_trustedSequencerURL", - "type": "string" - }, - { - "internalType": "string", - "name": "_networkName", - "type": "string" - }, - { - "internalType": "bytes32", - "name": "_lastAccInputHash", - "type": "bytes32" - } - ], - "name": "initializeUpgrade", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "lastAccInputHash", - "outputs": [ - { - "internalType": "bytes32", - "name": "", - "type": "bytes32" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "lastForceBatch", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "lastForceBatchSequenced", - "outputs": [ - { - "internalType": "uint64", - "name": "", - "type": "uint64" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "networkName", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "lastVerifiedBatch", - "type": "uint64" - }, - { - "internalType": "bytes32", - "name": "newStateRoot", - "type": "bytes32" - }, - { - "internalType": "address", - "name": "aggregator", - "type": "address" - } - ], - "name": "onVerifyBatches", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "pendingAdmin", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "pol", - "outputs": [ - { - "internalType": "contract IERC20Upgradeable", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "rollupManager", - "outputs": [ - { - "internalType": "contract PolygonRollupManager", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes", - "name": "transactions", - "type": "bytes" - }, - { - "internalType": "bytes32", - "name": "forcedGlobalExitRoot", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "forcedTimestamp", - "type": "uint64" - }, - { - "internalType": "bytes32", - "name": "forcedBlockHashL1", - "type": "bytes32" - } - ], - "internalType": "struct PolygonRollupBaseEtrog.BatchData[]", - "name": "batches", - "type": "tuple[]" - }, - { - "internalType": "address", - "name": "l2Coinbase", - "type": "address" - } - ], - "name": "sequenceBatches", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "components": [ - { - "internalType": "bytes", - "name": "transactions", - "type": "bytes" - }, - { - "internalType": "bytes32", - "name": "forcedGlobalExitRoot", - "type": "bytes32" - }, - { - "internalType": "uint64", - "name": "forcedTimestamp", - "type": "uint64" - }, - { - "internalType": "bytes32", - "name": "forcedBlockHashL1", - "type": "bytes32" - } - ], - "internalType": "struct PolygonRollupBaseEtrog.BatchData[]", - "name": "batches", - "type": "tuple[]" - } - ], - "name": "sequenceForceBatches", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newForceBatchAddress", - "type": "address" - } - ], - "name": "setForceBatchAddress", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "uint64", - "name": "newforceBatchTimeout", - "type": "uint64" - } - ], - "name": "setForceBatchTimeout", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newTrustedSequencer", - "type": "address" - } - ], - "name": "setTrustedSequencer", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "string", - "name": "newTrustedSequencerURL", - "type": "string" - } - ], - "name": "setTrustedSequencerURL", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [ - { - "internalType": "address", - "name": "newPendingAdmin", - "type": "address" - } - ], - "name": "transferAdminRole", - "outputs": [], - "stateMutability": "nonpayable", - "type": "function" - }, - { - "inputs": [], - "name": "trustedSequencer", - "outputs": [ - { - "internalType": "address", - "name": "", - "type": "address" - } - ], - "stateMutability": "view", - "type": "function" - }, - { - "inputs": [], - "name": "trustedSequencerURL", - "outputs": [ - { - "internalType": "string", - "name": "", - "type": "string" - } - ], - "stateMutability": "view", - "type": "function" - } + "internalType": "struct PolygonRollupBaseEtrog.BatchData[]", + "name": "batches", + "type": "tuple[]" + } + ], + "name": "sequenceForceBatches", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newForceBatchAddress", + "type": "address" + } + ], + "name": "setForceBatchAddress", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint64", + "name": "newforceBatchTimeout", + "type": "uint64" + } + ], + "name": "setForceBatchTimeout", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newTrustedSequencer", + "type": "address" + } + ], + "name": "setTrustedSequencer", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "newTrustedSequencerURL", + "type": "string" + } + ], + "name": "setTrustedSequencerURL", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address", + "name": "newPendingAdmin", + "type": "address" + } + ], + "name": "transferAdminRole", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "trustedSequencer", + "outputs": [ + { + "internalType": "address", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "trustedSequencerURL", + "outputs": [ + { + "internalType": "string", + "name": "", + "type": "string" + } + ], + "stateMutability": "view", + "type": "function" + } ] \ No newline at end of file diff --git a/etherman/smartcontracts/bin/etrogpolygonzkevm.bin b/etherman/smartcontracts/bin/etrogpolygonzkevm.bin new file mode 100644 index 0000000000..48be9467de --- /dev/null +++ b/etherman/smartcontracts/bin/etrogpolygonzkevm.bin @@ -0,0 +1 @@ +6101006040523480156200001257600080fd5b5060405162004a6138038062004a61833981016040819052620000359162000071565b6001600160a01b0393841660a052918316608052821660c0521660e052620000d9565b6001600160a01b03811681146200006e57600080fd5b50565b600080600080608085870312156200008857600080fd5b8451620000958162000058565b6020860151909450620000a88162000058565b6040860151909350620000bb8162000058565b6060860151909250620000ce8162000058565b939692955090935050565b60805160a05160c05160e05161488a620001d7600039600081816105060152818161098f01528181610afc01528181610c7d01528181610fd4015281816112de015281816118c101528181611d65015281816121bc015281816122b20152818161295701528181612a1f01528181613342015281816133bb015281816133dd01526134f5015260008181610673015281816114d2015281816115ac015281816124830152818161258b0152612e7c01526000818161073701528181610e450152818161173501528181612b6a0152612efe0152600081816107690152818161083b0152818161220501528181612b3e015261348b015261488a6000f3fe608060405234801561001057600080fd5b50600436106102f35760003560e01c80637a5460c511610191578063c7fffd4b116100e3578063e46761c411610097578063ecef3f9911610071578063ecef3f99146107b2578063f35dda47146107c5578063f851a440146107cd57600080fd5b8063e46761c414610764578063e7a7ed021461078b578063eaeb077b1461079f57600080fd5b8063cfa8ed47116100c8578063cfa8ed4714610712578063d02103ca14610732578063d7bc90ff1461075957600080fd5b8063c7fffd4b146106f7578063c89e42df146106ff57600080fd5b8063a3c573eb11610145578063af7f3e021161011f578063af7f3e02146106bb578063b0afe154146106c3578063c754c7ed146106cf57600080fd5b8063a3c573eb1461066e578063a652f26c14610695578063ada8f919146106a857600080fd5b806391cafe321161017657806391cafe321461062d5780639e001877146106405780639f26f8401461065b57600080fd5b80637a5460c5146105e95780638c3d73011461062557600080fd5b8063456052671161024a5780635d6717a5116101fe5780636e05d2cd116101d85780636e05d2cd146105ba5780636ff512cc146105c357806371257022146105d657600080fd5b80635d6717a51461057f578063676870d2146105925780636b8616ce1461059a57600080fd5b80634e4877061161022f5780634e4877061461052857806352bdeb6d1461053b578063542028d51461057757600080fd5b806345605267146104c857806349b7b8021461050157600080fd5b806326782247116102ac5780633c351e10116102865780633c351e10146104135780633cbc795b1461043357806340b5de6c1461047057600080fd5b806326782247146103995780632c111c06146103de57806332c2d153146103fe57600080fd5b806305835f37116102dd57806305835f371461032e578063107bf28c1461037757806311e892d41461037f57600080fd5b8062d0295d146102f85780630350896314610313575b600080fd5b6103006107f3565b6040519081526020015b60405180910390f35b61031b602081565b60405161ffff909116815260200161030a565b61036a6040518060400160405280600881526020017f80808401c9c3809400000000000000000000000000000000000000000000000081525081565b60405161030a91906139f2565b61036a6108ff565b61038760f981565b60405160ff909116815260200161030a565b6001546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030a565b6008546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b61041161040c366004613a47565b61098d565b005b6009546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b60095461045b9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161030a565b6104977fff0000000000000000000000000000000000000000000000000000000000000081565b6040517fff00000000000000000000000000000000000000000000000000000000000000909116815260200161030a565b6007546104e89068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161030a565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b610411610536366004613a89565b610a5c565b61036a6040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525081565b61036a610c6e565b61041161058d366004613bc0565b610c7b565b61031b601f81565b6103006105a8366004613a89565b60066020526000908152604090205481565b61030060055481565b6104116105d1366004613c51565b611212565b6104116105e4366004613c80565b6112dc565b61036a6040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525081565b610411611afd565b61041161063b366004613c51565b611bd0565b6103b973a40d5f56745a118d0906a34e69aec8c0db1cb8fa81565b610411610669366004613d79565b611ce9565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b61036a6106a3366004613dbb565b612382565b6104116106b6366004613c51565b612767565b61036a612831565b6103006405ca1ab1e081565b6007546104e890700100000000000000000000000000000000900467ffffffffffffffff1681565b61038760e481565b61041161070d366004613e30565b61284d565b6002546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b610300635ca1ab1e81565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b6007546104e89067ffffffffffffffff1681565b6104116107ad366004613e65565b6128e0565b6104116107c0366004613edd565b612db1565b610387601b81565b6000546103b99062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a69190613f29565b6007549091506000906108d19067ffffffffffffffff68010000000000000000820481169116613f71565b67ffffffffffffffff169050806000036108ee5760009250505090565b6108f88183613f99565b9250505090565b6004805461090c90613fd4565b80601f016020809104026020016040519081016040528092919081815260200182805461093890613fd4565b80156109855780601f1061095a57610100808354040283529160200191610985565b820191906000526020600020905b81548152906001019060200180831161096857829003601f168201915b505050505081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633146109fc576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168367ffffffffffffffff167f9c72852172521097ba7e1482e6b44b351323df0155f97f4ea18fcec28e1f596684604051610a4f91815260200190565b60405180910390a3505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314610ab3576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62093a8067ffffffffffffffff82161115610afa576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b899190614027565b610bea5760075467ffffffffffffffff700100000000000000000000000000000000909104811690821610610bea576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000067ffffffffffffffff8416908102919091179091556040519081527fa7eb6cb8a613eb4e8bddc1ac3d61ec6cf10898760f0b187bcca794c6ca6fa40b906020015b60405180910390a150565b6003805461090c90613fd4565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163314610cea576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff1615808015610d0a5750600054600160ff909116105b80610d245750303b158015610d24575060005460ff166001145b610db5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610e1357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60006040518060a00160405280606281526020016147f3606291399050600081805190602001209050600042905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610eae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed29190613f29565b90506000868483858d610ee6600143614049565b60408051602081019790975286019490945260608086019390935260c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000166080850152901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608883015240609c82015260bc01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815290829052805160209091012060058190557f9a908e73000000000000000000000000000000000000000000000000000000008252600160048301526024820181905291506000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af1158015611032573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110569190614062565b90508b600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508a600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555089600390816110e991906140c5565b5060046110f68a826140c5565b508b600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062069780600760106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507fd2c80353fc15ef62c6affc7cd6b7ab5b42c43290c50be3372e55ae552cecd19c8187858e60405161119994939291906141df565b60405180910390a1505050505050801561120a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314611269576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ff54144f9611984021529f814a1cb6a41e22c58351510a0d9f7e822618abb9cc090602001610c63565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16331461134b576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff161580801561136b5750600054600160ff909116105b806113855750303b158015611385575060005460ff166001145b611411576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610dac565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561146f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606073ffffffffffffffffffffffffffffffffffffffff8516156116d6576040517fc00f14ab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063c00f14ab90602401600060405180830381865afa158015611519573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261155f919081019061422f565b6040517f318aee3d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063318aee3d9060240160408051808303816000875af11580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a91906142a6565b915091508163ffffffff16600014611692576009805463ffffffff841674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff8416171790556116d3565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff89161790555b50505b60095460009061171e90889073ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900463ffffffff1685612382565b9050600081805190602001209050600042905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561179e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c29190613f29565b90506000808483858f6117d6600143614049565b60408051602081019790975286019490945260608086019390935260c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000166080850152901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608883015240609c82015260bc01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815290829052805160209091012060058190557f9a908e73000000000000000000000000000000000000000000000000000000008252600160048301526024820181905291507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af115801561191f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119439190614062565b508c600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555088600390816119d591906140c5565b5060046119e289826140c5565b508c600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062069780600760106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f060116213bcbf54ca19fd649dc84b59ab2bbd200ab199770e4d923e222a28e7f85838e604051611a83939291906142e0565b60405180910390a15050505050508015611af457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611b4e576040517fd1ec4b2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff1673ffffffffffffffffffffffffffffffffffffffff9092166201000081029290921790556040519081527f056dc487bbf0795d0bbb1b4f0af523a855503cff740bfb4d5475f7a90c091e8e9060200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314611c27576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085473ffffffffffffffffffffffffffffffffffffffff16611c76576040517fc89374d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f5fbd7dd171301c4a1611a84aac4ba86d119478560557755f7927595b082634fb90602001610c63565b60085473ffffffffffffffffffffffffffffffffffffffff168015801590611d27575073ffffffffffffffffffffffffffffffffffffffff81163314155b15611d5e576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4262093a807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166330c27dde6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df29190614062565b611dfc919061431f565b67ffffffffffffffff161115611e3e576040517f3d49ed4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816000819003611e7a576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e8811115611eb6576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60075467ffffffffffffffff80821691611ede91849168010000000000000000900416614340565b1115611f16576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546005546801000000000000000090910467ffffffffffffffff169060005b838110156121b6576000878783818110611f5357611f53614353565b9050602002810190611f659190614382565b611f6e906143c0565b905083611f7a81614449565b825180516020918201208185015160408087015160608801519151959a50929550600094611fe7948794929101938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8916600090815260069093529120549091508114612070576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8616600090815260066020526040812055612095600188614049565b84036121045742600760109054906101000a900467ffffffffffffffff1684604001516120c2919061431f565b67ffffffffffffffff161115612104576040517fc44a082100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018b90529285018790528481019390935260c01b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808401523390911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc0160405160208183030381529060405280519060200120945050505080806121ae90614470565b915050611f37565b5061222c7f0000000000000000000000000000000000000000000000000000000000000000846121e46107f3565b6121ee91906144a8565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001691906135ca565b60058190556007805467ffffffffffffffff841668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161790556040517f9a908e7300000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690639a908e73906122fe908790869060040167ffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af115801561231d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123419190614062565b60405190915067ffffffffffffffff8216907f648a61dd2438f072f5a1960939abd30f37aea80d2e94c9792ad142d3e0a490a490600090a250505050505050565b6060600085858573a40d5f56745a118d0906a34e69aec8c0db1cb8fa6000876040516024016123b6969594939291906144bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff811bff70000000000000000000000000000000000000000000000000000000017905283519091506060906000036125075760f9601f835161244b9190614522565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525060e4876040516020016124f1979695949392919061453d565b604051602081830303815290604052905061260b565b815161ffff1015612544576040517f248b8f8200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160f9612553602083614522565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525085886040516020016125f89796959493929190614620565b6040516020818303038152906040529150505b805160208083019190912060408051600080825293810180835292909252601b908201526405ca1ab1e06060820152635ca1ab1e608082015260019060a0016020604051602081039080840390855afa15801561266c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166126e4576040517fcd16196600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405160009061272a9084906405ca1ab1e090635ca1ab1e90601b907fff0000000000000000000000000000000000000000000000000000000000000090602001614703565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529450505050505b949350505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146127be576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa5b56b7906fd0a20e3f35120dd8343db1e12e037a6c90111c7e42885e82a1ce690602001610c63565b6040518060a00160405280606281526020016147f36062913981565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146128a4576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60036128b082826140c5565b507f6b8f723a4c7a5335cafae8a598a0aa0301be1387c037dccc085b62add6448b2081604051610c6391906139f2565b60085473ffffffffffffffffffffffffffffffffffffffff16801580159061291e575073ffffffffffffffffffffffffffffffffffffffff81163314155b15612955576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e49190614027565b15612a1b576040517f39258d1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663604691696040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aac9190613f29565b905082811115612ae8576040517f2354600f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611388841115612b24576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846136a3565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf79190613f29565b6007805491925067ffffffffffffffff909116906000612c1683614449565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550508585604051612c4d92919061475f565b6040519081900390208142612c63600143614049565b60408051602081019590955284019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166060830152406068820152608801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060075467ffffffffffffffff1660009081526006909352912055323303612d5b57600754604080518381523360208201526060818301819052600090820152905167ffffffffffffffff909216917ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc9319181900360800190a261120a565b60075460405167ffffffffffffffff909116907ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc93190612da190849033908b908b9061476f565b60405180910390a2505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314612e02576040517f11e7be1500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816000819003612e3e576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e8811115612e7a576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166379e2cf976040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612ee257600080fd5b505af1158015612ef6573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635ca1e1656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8b9190613f29565b60075460055491925042916801000000000000000090910467ffffffffffffffff16908160005b868110156132b45760008a8a83818110612fce57612fce614353565b9050602002810190612fe09190614382565b612fe9906143c0565b8051805160209091012060408201519192509067ffffffffffffffff16156131ce578561301581614449565b9650506000818360200151846040015185606001516040516020016130789493929190938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8a16600090815260069093529120549091508114613101576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018c90529285018790528481019390935260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166080840152908d901b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc01604051602081830303815290604052805190602001209550600660008867ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600090555061329f565b8151516201d4c0101561320d576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020810187905290810182905260608082018a905260c089901b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808301528b901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660888201526000609c82015260bc016040516020818303038152906040528051906020012094505b505080806132ac90614470565b915050612fb2565b5060075467ffffffffffffffff90811690841611156132ff576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60058290558567ffffffffffffffff848116908316146133b55760006133258386613f71565b905061333b67ffffffffffffffff821683614049565b91506133747f00000000000000000000000000000000000000000000000000000000000000008267ffffffffffffffff166121e46107f3565b50600780547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8716021790555b6134b3337f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663477fa2706040518163ffffffff1660e01b8152600401602060405180830381865afa158015613446573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346a9190613f29565b61347491906144a8565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169291906136a3565b6040517f9a908e7300000000000000000000000000000000000000000000000000000000815267ffffffffffffffff88166004820152602481018490526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af1158015613553573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135779190614062565b90508067ffffffffffffffff167f3e54d0825ed78523037d00a81759237eb436ce774bd546993ee67a1b67b6e766886040516135b591815260200190565b60405180910390a25050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261369e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613707565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526137019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161361c565b50505050565b6000613769826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138139092919063ffffffff16565b80519091501561369e57808060200190518101906137879190614027565b61369e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610dac565b606061275f8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161384791906147e0565b60006040518083038185875af1925050503d8060008114613884576040519150601f19603f3d011682016040523d82523d6000602084013e613889565b606091505b509150915061389a878383876138a5565b979650505050505050565b6060831561393b5782516000036139345773ffffffffffffffffffffffffffffffffffffffff85163b613934576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610dac565b508161275f565b61275f83838151156139505781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dac91906139f2565b60005b8381101561399f578181015183820152602001613987565b50506000910152565b600081518084526139c0816020860160208601613984565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a0560208301846139a8565b9392505050565b67ffffffffffffffff81168114613a2257600080fd5b50565b73ffffffffffffffffffffffffffffffffffffffff81168114613a2257600080fd5b600080600060608486031215613a5c57600080fd5b8335613a6781613a0c565b9250602084013591506040840135613a7e81613a25565b809150509250925092565b600060208284031215613a9b57600080fd5b8135613a0581613a0c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613b1c57613b1c613aa6565b604052919050565b600067ffffffffffffffff821115613b3e57613b3e613aa6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613b7b57600080fd5b8135613b8e613b8982613b24565b613ad5565b818152846020838601011115613ba357600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215613bd857600080fd5b8535613be381613a25565b94506020860135613bf381613a25565b9350604086013567ffffffffffffffff80821115613c1057600080fd5b613c1c89838a01613b6a565b94506060880135915080821115613c3257600080fd5b50613c3f88828901613b6a565b95989497509295608001359392505050565b600060208284031215613c6357600080fd5b8135613a0581613a25565b63ffffffff81168114613a2257600080fd5b60008060008060008060c08789031215613c9957600080fd5b8635613ca481613a25565b95506020870135613cb481613a25565b94506040870135613cc481613c6e565b93506060870135613cd481613a25565b9250608087013567ffffffffffffffff80821115613cf157600080fd5b613cfd8a838b01613b6a565b935060a0890135915080821115613d1357600080fd5b50613d2089828a01613b6a565b9150509295509295509295565b60008083601f840112613d3f57600080fd5b50813567ffffffffffffffff811115613d5757600080fd5b6020830191508360208260051b8501011115613d7257600080fd5b9250929050565b60008060208385031215613d8c57600080fd5b823567ffffffffffffffff811115613da357600080fd5b613daf85828601613d2d565b90969095509350505050565b60008060008060808587031215613dd157600080fd5b8435613ddc81613c6e565b93506020850135613dec81613a25565b92506040850135613dfc81613c6e565b9150606085013567ffffffffffffffff811115613e1857600080fd5b613e2487828801613b6a565b91505092959194509250565b600060208284031215613e4257600080fd5b813567ffffffffffffffff811115613e5957600080fd5b61275f84828501613b6a565b600080600060408486031215613e7a57600080fd5b833567ffffffffffffffff80821115613e9257600080fd5b818601915086601f830112613ea657600080fd5b813581811115613eb557600080fd5b876020828501011115613ec757600080fd5b6020928301989097509590910135949350505050565b600080600060408486031215613ef257600080fd5b833567ffffffffffffffff811115613f0957600080fd5b613f1586828701613d2d565b9094509250506020840135613a7e81613a25565b600060208284031215613f3b57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115613f9257613f92613f42565b5092915050565b600082613fcf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600181811c90821680613fe857607f821691505b602082108103614021577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561403957600080fd5b81518015158114613a0557600080fd5b8181038181111561405c5761405c613f42565b92915050565b60006020828403121561407457600080fd5b8151613a0581613a0c565b601f82111561369e57600081815260208120601f850160051c810160208610156140a65750805b601f850160051c820191505b8181101561120a578281556001016140b2565b815167ffffffffffffffff8111156140df576140df613aa6565b6140f3816140ed8454613fd4565b8461407f565b602080601f83116001811461414657600084156141105750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561120a565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561419357888601518255948401946001909101908401614174565b50858210156141cf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff8516815260806020820152600061420260808301866139a8565b905083604083015273ffffffffffffffffffffffffffffffffffffffff8316606083015295945050505050565b60006020828403121561424157600080fd5b815167ffffffffffffffff81111561425857600080fd5b8201601f8101841361426957600080fd5b8051614277613b8982613b24565b81815285602083850101111561428c57600080fd5b61429d826020830160208601613984565b95945050505050565b600080604083850312156142b957600080fd5b82516142c481613c6e565b60208401519092506142d581613a25565b809150509250929050565b6060815260006142f360608301866139a8565b905083602083015273ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b67ffffffffffffffff818116838216019080821115613f9257613f92613f42565b8082018082111561405c5761405c613f42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126143b657600080fd5b9190910192915050565b6000608082360312156143d257600080fd5b6040516080810167ffffffffffffffff82821081831117156143f6576143f6613aa6565b81604052843591508082111561440b57600080fd5b5061441836828601613b6a565b82525060208301356020820152604083013561443381613a0c565b6040820152606092830135928101929092525090565b600067ffffffffffffffff80831681810361446657614466613f42565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144a1576144a1613f42565b5060010190565b808202811582820484141761405c5761405c613f42565b600063ffffffff808916835273ffffffffffffffffffffffffffffffffffffffff8089166020850152818816604085015280871660608501528086166080850152505060c060a083015261451660c08301846139a8565b98975050505050505050565b61ffff818116838216019080821115613f9257613f92613f42565b60007fff00000000000000000000000000000000000000000000000000000000000000808a60f81b1683527fffff0000000000000000000000000000000000000000000000000000000000008960f01b16600184015287516145a6816003860160208c01613984565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b16600382015286516145e9816017840160208b01613984565b808201915050818660f81b1660178201528451915061460f826018830160208801613984565b016018019998505050505050505050565b7fff000000000000000000000000000000000000000000000000000000000000008860f81b16815260007fffff000000000000000000000000000000000000000000000000000000000000808960f01b1660018401528751614689816003860160208c01613984565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b16600382015286516146cc816017840160208b01613984565b808201915050818660f01b166017820152845191506146f2826019830160208801613984565b016019019998505050505050505050565b60008651614715818460208b01613984565b9190910194855250602084019290925260f81b7fff000000000000000000000000000000000000000000000000000000000000009081166040840152166041820152604201919050565b8183823760009101908152919050565b84815273ffffffffffffffffffffffffffffffffffffffff8416602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01601019392505050565b600082516143b681846020870161398456fedf2a8080944d5cf5032b2a844602278b01199ed191a86c93ff8080821092808000000000000000000000000000000000000000000000000000000005ca1ab1e000000000000000000000000000000000000000000000000000000005ca1ab1e01bffa26469706673582212201221389ded8ea187a66f83d3bd052755e28647dbf3bc616c9e91e0a8b7ecf74364736f6c63430008140033 \ No newline at end of file diff --git a/etherman/smartcontracts/bin/polygonzkevm.bin b/etherman/smartcontracts/bin/polygonzkevm.bin index 48be9467de..5f2b0209c9 100644 --- a/etherman/smartcontracts/bin/polygonzkevm.bin +++ b/etherman/smartcontracts/bin/polygonzkevm.bin @@ -1 +1 @@ -6101006040523480156200001257600080fd5b5060405162004a6138038062004a61833981016040819052620000359162000071565b6001600160a01b0393841660a052918316608052821660c0521660e052620000d9565b6001600160a01b03811681146200006e57600080fd5b50565b600080600080608085870312156200008857600080fd5b8451620000958162000058565b6020860151909450620000a88162000058565b6040860151909350620000bb8162000058565b6060860151909250620000ce8162000058565b939692955090935050565b60805160a05160c05160e05161488a620001d7600039600081816105060152818161098f01528181610afc01528181610c7d01528181610fd4015281816112de015281816118c101528181611d65015281816121bc015281816122b20152818161295701528181612a1f01528181613342015281816133bb015281816133dd01526134f5015260008181610673015281816114d2015281816115ac015281816124830152818161258b0152612e7c01526000818161073701528181610e450152818161173501528181612b6a0152612efe0152600081816107690152818161083b0152818161220501528181612b3e015261348b015261488a6000f3fe608060405234801561001057600080fd5b50600436106102f35760003560e01c80637a5460c511610191578063c7fffd4b116100e3578063e46761c411610097578063ecef3f9911610071578063ecef3f99146107b2578063f35dda47146107c5578063f851a440146107cd57600080fd5b8063e46761c414610764578063e7a7ed021461078b578063eaeb077b1461079f57600080fd5b8063cfa8ed47116100c8578063cfa8ed4714610712578063d02103ca14610732578063d7bc90ff1461075957600080fd5b8063c7fffd4b146106f7578063c89e42df146106ff57600080fd5b8063a3c573eb11610145578063af7f3e021161011f578063af7f3e02146106bb578063b0afe154146106c3578063c754c7ed146106cf57600080fd5b8063a3c573eb1461066e578063a652f26c14610695578063ada8f919146106a857600080fd5b806391cafe321161017657806391cafe321461062d5780639e001877146106405780639f26f8401461065b57600080fd5b80637a5460c5146105e95780638c3d73011461062557600080fd5b8063456052671161024a5780635d6717a5116101fe5780636e05d2cd116101d85780636e05d2cd146105ba5780636ff512cc146105c357806371257022146105d657600080fd5b80635d6717a51461057f578063676870d2146105925780636b8616ce1461059a57600080fd5b80634e4877061161022f5780634e4877061461052857806352bdeb6d1461053b578063542028d51461057757600080fd5b806345605267146104c857806349b7b8021461050157600080fd5b806326782247116102ac5780633c351e10116102865780633c351e10146104135780633cbc795b1461043357806340b5de6c1461047057600080fd5b806326782247146103995780632c111c06146103de57806332c2d153146103fe57600080fd5b806305835f37116102dd57806305835f371461032e578063107bf28c1461037757806311e892d41461037f57600080fd5b8062d0295d146102f85780630350896314610313575b600080fd5b6103006107f3565b6040519081526020015b60405180910390f35b61031b602081565b60405161ffff909116815260200161030a565b61036a6040518060400160405280600881526020017f80808401c9c3809400000000000000000000000000000000000000000000000081525081565b60405161030a91906139f2565b61036a6108ff565b61038760f981565b60405160ff909116815260200161030a565b6001546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030a565b6008546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b61041161040c366004613a47565b61098d565b005b6009546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b60095461045b9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161030a565b6104977fff0000000000000000000000000000000000000000000000000000000000000081565b6040517fff00000000000000000000000000000000000000000000000000000000000000909116815260200161030a565b6007546104e89068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161030a565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b610411610536366004613a89565b610a5c565b61036a6040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525081565b61036a610c6e565b61041161058d366004613bc0565b610c7b565b61031b601f81565b6103006105a8366004613a89565b60066020526000908152604090205481565b61030060055481565b6104116105d1366004613c51565b611212565b6104116105e4366004613c80565b6112dc565b61036a6040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525081565b610411611afd565b61041161063b366004613c51565b611bd0565b6103b973a40d5f56745a118d0906a34e69aec8c0db1cb8fa81565b610411610669366004613d79565b611ce9565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b61036a6106a3366004613dbb565b612382565b6104116106b6366004613c51565b612767565b61036a612831565b6103006405ca1ab1e081565b6007546104e890700100000000000000000000000000000000900467ffffffffffffffff1681565b61038760e481565b61041161070d366004613e30565b61284d565b6002546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b610300635ca1ab1e81565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b6007546104e89067ffffffffffffffff1681565b6104116107ad366004613e65565b6128e0565b6104116107c0366004613edd565b612db1565b610387601b81565b6000546103b99062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a69190613f29565b6007549091506000906108d19067ffffffffffffffff68010000000000000000820481169116613f71565b67ffffffffffffffff169050806000036108ee5760009250505090565b6108f88183613f99565b9250505090565b6004805461090c90613fd4565b80601f016020809104026020016040519081016040528092919081815260200182805461093890613fd4565b80156109855780601f1061095a57610100808354040283529160200191610985565b820191906000526020600020905b81548152906001019060200180831161096857829003601f168201915b505050505081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633146109fc576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168367ffffffffffffffff167f9c72852172521097ba7e1482e6b44b351323df0155f97f4ea18fcec28e1f596684604051610a4f91815260200190565b60405180910390a3505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314610ab3576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62093a8067ffffffffffffffff82161115610afa576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b899190614027565b610bea5760075467ffffffffffffffff700100000000000000000000000000000000909104811690821610610bea576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000067ffffffffffffffff8416908102919091179091556040519081527fa7eb6cb8a613eb4e8bddc1ac3d61ec6cf10898760f0b187bcca794c6ca6fa40b906020015b60405180910390a150565b6003805461090c90613fd4565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163314610cea576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff1615808015610d0a5750600054600160ff909116105b80610d245750303b158015610d24575060005460ff166001145b610db5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610e1357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60006040518060a00160405280606281526020016147f3606291399050600081805190602001209050600042905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610eae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed29190613f29565b90506000868483858d610ee6600143614049565b60408051602081019790975286019490945260608086019390935260c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000166080850152901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608883015240609c82015260bc01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815290829052805160209091012060058190557f9a908e73000000000000000000000000000000000000000000000000000000008252600160048301526024820181905291506000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af1158015611032573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110569190614062565b90508b600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508a600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555089600390816110e991906140c5565b5060046110f68a826140c5565b508b600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062069780600760106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507fd2c80353fc15ef62c6affc7cd6b7ab5b42c43290c50be3372e55ae552cecd19c8187858e60405161119994939291906141df565b60405180910390a1505050505050801561120a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314611269576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ff54144f9611984021529f814a1cb6a41e22c58351510a0d9f7e822618abb9cc090602001610c63565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16331461134b576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff161580801561136b5750600054600160ff909116105b806113855750303b158015611385575060005460ff166001145b611411576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610dac565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561146f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606073ffffffffffffffffffffffffffffffffffffffff8516156116d6576040517fc00f14ab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063c00f14ab90602401600060405180830381865afa158015611519573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261155f919081019061422f565b6040517f318aee3d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063318aee3d9060240160408051808303816000875af11580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a91906142a6565b915091508163ffffffff16600014611692576009805463ffffffff841674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff8416171790556116d3565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff89161790555b50505b60095460009061171e90889073ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900463ffffffff1685612382565b9050600081805190602001209050600042905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561179e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c29190613f29565b90506000808483858f6117d6600143614049565b60408051602081019790975286019490945260608086019390935260c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000166080850152901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608883015240609c82015260bc01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815290829052805160209091012060058190557f9a908e73000000000000000000000000000000000000000000000000000000008252600160048301526024820181905291507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af115801561191f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119439190614062565b508c600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555088600390816119d591906140c5565b5060046119e289826140c5565b508c600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062069780600760106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f060116213bcbf54ca19fd649dc84b59ab2bbd200ab199770e4d923e222a28e7f85838e604051611a83939291906142e0565b60405180910390a15050505050508015611af457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611b4e576040517fd1ec4b2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff1673ffffffffffffffffffffffffffffffffffffffff9092166201000081029290921790556040519081527f056dc487bbf0795d0bbb1b4f0af523a855503cff740bfb4d5475f7a90c091e8e9060200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314611c27576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085473ffffffffffffffffffffffffffffffffffffffff16611c76576040517fc89374d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f5fbd7dd171301c4a1611a84aac4ba86d119478560557755f7927595b082634fb90602001610c63565b60085473ffffffffffffffffffffffffffffffffffffffff168015801590611d27575073ffffffffffffffffffffffffffffffffffffffff81163314155b15611d5e576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4262093a807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166330c27dde6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df29190614062565b611dfc919061431f565b67ffffffffffffffff161115611e3e576040517f3d49ed4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816000819003611e7a576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e8811115611eb6576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60075467ffffffffffffffff80821691611ede91849168010000000000000000900416614340565b1115611f16576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546005546801000000000000000090910467ffffffffffffffff169060005b838110156121b6576000878783818110611f5357611f53614353565b9050602002810190611f659190614382565b611f6e906143c0565b905083611f7a81614449565b825180516020918201208185015160408087015160608801519151959a50929550600094611fe7948794929101938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8916600090815260069093529120549091508114612070576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8616600090815260066020526040812055612095600188614049565b84036121045742600760109054906101000a900467ffffffffffffffff1684604001516120c2919061431f565b67ffffffffffffffff161115612104576040517fc44a082100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018b90529285018790528481019390935260c01b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808401523390911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc0160405160208183030381529060405280519060200120945050505080806121ae90614470565b915050611f37565b5061222c7f0000000000000000000000000000000000000000000000000000000000000000846121e46107f3565b6121ee91906144a8565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001691906135ca565b60058190556007805467ffffffffffffffff841668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161790556040517f9a908e7300000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690639a908e73906122fe908790869060040167ffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af115801561231d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123419190614062565b60405190915067ffffffffffffffff8216907f648a61dd2438f072f5a1960939abd30f37aea80d2e94c9792ad142d3e0a490a490600090a250505050505050565b6060600085858573a40d5f56745a118d0906a34e69aec8c0db1cb8fa6000876040516024016123b6969594939291906144bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff811bff70000000000000000000000000000000000000000000000000000000017905283519091506060906000036125075760f9601f835161244b9190614522565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525060e4876040516020016124f1979695949392919061453d565b604051602081830303815290604052905061260b565b815161ffff1015612544576040517f248b8f8200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160f9612553602083614522565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525085886040516020016125f89796959493929190614620565b6040516020818303038152906040529150505b805160208083019190912060408051600080825293810180835292909252601b908201526405ca1ab1e06060820152635ca1ab1e608082015260019060a0016020604051602081039080840390855afa15801561266c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166126e4576040517fcd16196600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405160009061272a9084906405ca1ab1e090635ca1ab1e90601b907fff0000000000000000000000000000000000000000000000000000000000000090602001614703565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529450505050505b949350505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146127be576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa5b56b7906fd0a20e3f35120dd8343db1e12e037a6c90111c7e42885e82a1ce690602001610c63565b6040518060a00160405280606281526020016147f36062913981565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146128a4576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60036128b082826140c5565b507f6b8f723a4c7a5335cafae8a598a0aa0301be1387c037dccc085b62add6448b2081604051610c6391906139f2565b60085473ffffffffffffffffffffffffffffffffffffffff16801580159061291e575073ffffffffffffffffffffffffffffffffffffffff81163314155b15612955576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e49190614027565b15612a1b576040517f39258d1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663604691696040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aac9190613f29565b905082811115612ae8576040517f2354600f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611388841115612b24576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846136a3565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf79190613f29565b6007805491925067ffffffffffffffff909116906000612c1683614449565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550508585604051612c4d92919061475f565b6040519081900390208142612c63600143614049565b60408051602081019590955284019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166060830152406068820152608801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060075467ffffffffffffffff1660009081526006909352912055323303612d5b57600754604080518381523360208201526060818301819052600090820152905167ffffffffffffffff909216917ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc9319181900360800190a261120a565b60075460405167ffffffffffffffff909116907ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc93190612da190849033908b908b9061476f565b60405180910390a2505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314612e02576040517f11e7be1500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816000819003612e3e576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e8811115612e7a576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166379e2cf976040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612ee257600080fd5b505af1158015612ef6573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635ca1e1656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8b9190613f29565b60075460055491925042916801000000000000000090910467ffffffffffffffff16908160005b868110156132b45760008a8a83818110612fce57612fce614353565b9050602002810190612fe09190614382565b612fe9906143c0565b8051805160209091012060408201519192509067ffffffffffffffff16156131ce578561301581614449565b9650506000818360200151846040015185606001516040516020016130789493929190938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8a16600090815260069093529120549091508114613101576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018c90529285018790528481019390935260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166080840152908d901b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc01604051602081830303815290604052805190602001209550600660008867ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600090555061329f565b8151516201d4c0101561320d576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020810187905290810182905260608082018a905260c089901b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808301528b901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660888201526000609c82015260bc016040516020818303038152906040528051906020012094505b505080806132ac90614470565b915050612fb2565b5060075467ffffffffffffffff90811690841611156132ff576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60058290558567ffffffffffffffff848116908316146133b55760006133258386613f71565b905061333b67ffffffffffffffff821683614049565b91506133747f00000000000000000000000000000000000000000000000000000000000000008267ffffffffffffffff166121e46107f3565b50600780547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8716021790555b6134b3337f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663477fa2706040518163ffffffff1660e01b8152600401602060405180830381865afa158015613446573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346a9190613f29565b61347491906144a8565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169291906136a3565b6040517f9a908e7300000000000000000000000000000000000000000000000000000000815267ffffffffffffffff88166004820152602481018490526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af1158015613553573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135779190614062565b90508067ffffffffffffffff167f3e54d0825ed78523037d00a81759237eb436ce774bd546993ee67a1b67b6e766886040516135b591815260200190565b60405180910390a25050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261369e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613707565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526137019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161361c565b50505050565b6000613769826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138139092919063ffffffff16565b80519091501561369e57808060200190518101906137879190614027565b61369e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610dac565b606061275f8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161384791906147e0565b60006040518083038185875af1925050503d8060008114613884576040519150601f19603f3d011682016040523d82523d6000602084013e613889565b606091505b509150915061389a878383876138a5565b979650505050505050565b6060831561393b5782516000036139345773ffffffffffffffffffffffffffffffffffffffff85163b613934576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610dac565b508161275f565b61275f83838151156139505781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dac91906139f2565b60005b8381101561399f578181015183820152602001613987565b50506000910152565b600081518084526139c0816020860160208601613984565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a0560208301846139a8565b9392505050565b67ffffffffffffffff81168114613a2257600080fd5b50565b73ffffffffffffffffffffffffffffffffffffffff81168114613a2257600080fd5b600080600060608486031215613a5c57600080fd5b8335613a6781613a0c565b9250602084013591506040840135613a7e81613a25565b809150509250925092565b600060208284031215613a9b57600080fd5b8135613a0581613a0c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613b1c57613b1c613aa6565b604052919050565b600067ffffffffffffffff821115613b3e57613b3e613aa6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613b7b57600080fd5b8135613b8e613b8982613b24565b613ad5565b818152846020838601011115613ba357600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215613bd857600080fd5b8535613be381613a25565b94506020860135613bf381613a25565b9350604086013567ffffffffffffffff80821115613c1057600080fd5b613c1c89838a01613b6a565b94506060880135915080821115613c3257600080fd5b50613c3f88828901613b6a565b95989497509295608001359392505050565b600060208284031215613c6357600080fd5b8135613a0581613a25565b63ffffffff81168114613a2257600080fd5b60008060008060008060c08789031215613c9957600080fd5b8635613ca481613a25565b95506020870135613cb481613a25565b94506040870135613cc481613c6e565b93506060870135613cd481613a25565b9250608087013567ffffffffffffffff80821115613cf157600080fd5b613cfd8a838b01613b6a565b935060a0890135915080821115613d1357600080fd5b50613d2089828a01613b6a565b9150509295509295509295565b60008083601f840112613d3f57600080fd5b50813567ffffffffffffffff811115613d5757600080fd5b6020830191508360208260051b8501011115613d7257600080fd5b9250929050565b60008060208385031215613d8c57600080fd5b823567ffffffffffffffff811115613da357600080fd5b613daf85828601613d2d565b90969095509350505050565b60008060008060808587031215613dd157600080fd5b8435613ddc81613c6e565b93506020850135613dec81613a25565b92506040850135613dfc81613c6e565b9150606085013567ffffffffffffffff811115613e1857600080fd5b613e2487828801613b6a565b91505092959194509250565b600060208284031215613e4257600080fd5b813567ffffffffffffffff811115613e5957600080fd5b61275f84828501613b6a565b600080600060408486031215613e7a57600080fd5b833567ffffffffffffffff80821115613e9257600080fd5b818601915086601f830112613ea657600080fd5b813581811115613eb557600080fd5b876020828501011115613ec757600080fd5b6020928301989097509590910135949350505050565b600080600060408486031215613ef257600080fd5b833567ffffffffffffffff811115613f0957600080fd5b613f1586828701613d2d565b9094509250506020840135613a7e81613a25565b600060208284031215613f3b57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115613f9257613f92613f42565b5092915050565b600082613fcf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600181811c90821680613fe857607f821691505b602082108103614021577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561403957600080fd5b81518015158114613a0557600080fd5b8181038181111561405c5761405c613f42565b92915050565b60006020828403121561407457600080fd5b8151613a0581613a0c565b601f82111561369e57600081815260208120601f850160051c810160208610156140a65750805b601f850160051c820191505b8181101561120a578281556001016140b2565b815167ffffffffffffffff8111156140df576140df613aa6565b6140f3816140ed8454613fd4565b8461407f565b602080601f83116001811461414657600084156141105750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561120a565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561419357888601518255948401946001909101908401614174565b50858210156141cf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff8516815260806020820152600061420260808301866139a8565b905083604083015273ffffffffffffffffffffffffffffffffffffffff8316606083015295945050505050565b60006020828403121561424157600080fd5b815167ffffffffffffffff81111561425857600080fd5b8201601f8101841361426957600080fd5b8051614277613b8982613b24565b81815285602083850101111561428c57600080fd5b61429d826020830160208601613984565b95945050505050565b600080604083850312156142b957600080fd5b82516142c481613c6e565b60208401519092506142d581613a25565b809150509250929050565b6060815260006142f360608301866139a8565b905083602083015273ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b67ffffffffffffffff818116838216019080821115613f9257613f92613f42565b8082018082111561405c5761405c613f42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126143b657600080fd5b9190910192915050565b6000608082360312156143d257600080fd5b6040516080810167ffffffffffffffff82821081831117156143f6576143f6613aa6565b81604052843591508082111561440b57600080fd5b5061441836828601613b6a565b82525060208301356020820152604083013561443381613a0c565b6040820152606092830135928101929092525090565b600067ffffffffffffffff80831681810361446657614466613f42565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144a1576144a1613f42565b5060010190565b808202811582820484141761405c5761405c613f42565b600063ffffffff808916835273ffffffffffffffffffffffffffffffffffffffff8089166020850152818816604085015280871660608501528086166080850152505060c060a083015261451660c08301846139a8565b98975050505050505050565b61ffff818116838216019080821115613f9257613f92613f42565b60007fff00000000000000000000000000000000000000000000000000000000000000808a60f81b1683527fffff0000000000000000000000000000000000000000000000000000000000008960f01b16600184015287516145a6816003860160208c01613984565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b16600382015286516145e9816017840160208b01613984565b808201915050818660f81b1660178201528451915061460f826018830160208801613984565b016018019998505050505050505050565b7fff000000000000000000000000000000000000000000000000000000000000008860f81b16815260007fffff000000000000000000000000000000000000000000000000000000000000808960f01b1660018401528751614689816003860160208c01613984565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b16600382015286516146cc816017840160208b01613984565b808201915050818660f01b166017820152845191506146f2826019830160208801613984565b016019019998505050505050505050565b60008651614715818460208b01613984565b9190910194855250602084019290925260f81b7fff000000000000000000000000000000000000000000000000000000000000009081166040840152166041820152604201919050565b8183823760009101908152919050565b84815273ffffffffffffffffffffffffffffffffffffffff8416602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01601019392505050565b600082516143b681846020870161398456fedf2a8080944d5cf5032b2a844602278b01199ed191a86c93ff8080821092808000000000000000000000000000000000000000000000000000000005ca1ab1e000000000000000000000000000000000000000000000000000000005ca1ab1e01bffa26469706673582212201221389ded8ea187a66f83d3bd052755e28647dbf3bc616c9e91e0a8b7ecf74364736f6c63430008140033 \ No newline at end of file +0x6101006040523480156200001257600080fd5b506040516200440f3803806200440f833981016040819052620000359162000071565b6001600160a01b0393841660a052918316608052821660c0521660e052620000d9565b6001600160a01b03811681146200006e57600080fd5b50565b600080600080608085870312156200008857600080fd5b8451620000958162000058565b6020860151909450620000a88162000058565b6040860151909350620000bb8162000058565b6060860151909250620000ce8162000058565b939692955090935050565b60805160a05160c05160e05161424d620001c2600039600081816105030152818161097101528181610ade01528181610d290152818161130f015281816117b301528181611c0a01528181611d00015281816128ee015281816129670152818161298901528181612aa101528181612c440152612d0c01526000818161065d01528181610f2201528181610ffc01528181611ed101528181611fd9015261242b01526000818161071901528181611183015281816124ad0152612e5701526000818161075e0152818161081d01528181611c5301528181612a370152612e2b015261424d6000f3fe608060405234801561001057600080fd5b50600436106102e85760003560e01c80637125702211610191578063c7fffd4b116100e3578063def57e5411610097578063eaeb077b11610071578063eaeb077b14610794578063f35dda47146107a7578063f851a440146107af57600080fd5b8063def57e5414610746578063e46761c414610759578063e7a7ed021461078057600080fd5b8063cfa8ed47116100c8578063cfa8ed47146106f4578063d02103ca14610714578063d7bc90ff1461073b57600080fd5b8063c7fffd4b146106d9578063c89e42df146106e157600080fd5b80639f26f84011610145578063ada8f9191161011f578063ada8f91914610692578063b0afe154146106a5578063c754c7ed146106b157600080fd5b80639f26f84014610645578063a3c573eb14610658578063a652f26c1461067f57600080fd5b80638c3d7301116101765780638c3d73011461060f57806391cafe32146106175780639e0018771461062a57600080fd5b806371257022146105c05780637a5460c5146105d357600080fd5b806340b5de6c1161024a57806352bdeb6d116101fe5780636b8616ce116101d85780636b8616ce146105845780636e05d2cd146105a45780636ff512cc146105ad57600080fd5b806352bdeb6d14610538578063542028d514610574578063676870d21461057c57600080fd5b8063456052671161022f57806345605267146104c557806349b7b802146104fe5780634e4877061461052557600080fd5b806340b5de6c1461046557806342308fab146104bd57600080fd5b806326782247116102a157806332c2d1531161028657806332c2d153146103f35780633c351e10146104085780633cbc795b1461042857600080fd5b8063267822471461038e5780632c111c06146103d357600080fd5b806305835f37116102d257806305835f3714610323578063107bf28c1461036c57806311e892d41461037457600080fd5b8062d0295d146102ed5780630350896314610308575b600080fd5b6102f56107d5565b6040519081526020015b60405180910390f35b610310602081565b60405161ffff90911681526020016102ff565b61035f6040518060400160405280600881526020017f80808401c9c3809400000000000000000000000000000000000000000000000081525081565b6040516102ff91906134c7565b61035f6108e1565b61037c60f981565b60405160ff90911681526020016102ff565b6001546103ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102ff565b6008546103ae9073ffffffffffffffffffffffffffffffffffffffff1681565b61040661040136600461351c565b61096f565b005b6009546103ae9073ffffffffffffffffffffffffffffffffffffffff1681565b6009546104509074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102ff565b61048c7fff0000000000000000000000000000000000000000000000000000000000000081565b6040517fff0000000000000000000000000000000000000000000000000000000000000090911681526020016102ff565b6102f5602481565b6007546104e59068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016102ff565b6103ae7f000000000000000000000000000000000000000000000000000000000000000081565b61040661053336600461355e565b610a3e565b61035f6040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525081565b61035f610c50565b610310601f81565b6102f561059236600461355e565b60066020526000908152604090205481565b6102f560055481565b6104066105bb36600461357b565b610c5d565b6104066105ce3660046136c4565b610d27565b61035f6040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525081565b61040661154b565b61040661062536600461357b565b61161e565b6103ae73a40d5f56745a118d0906a34e69aec8c0db1cb8fa81565b6104066106533660046137bd565b611737565b6103ae7f000000000000000000000000000000000000000000000000000000000000000081565b61035f61068d3660046137ff565b611dd0565b6104066106a036600461357b565b6121b5565b6102f56405ca1ab1e081565b6007546104e590700100000000000000000000000000000000900467ffffffffffffffff1681565b61037c60e481565b6104066106ef366004613874565b61227f565b6002546103ae9073ffffffffffffffffffffffffffffffffffffffff1681565b6103ae7f000000000000000000000000000000000000000000000000000000000000000081565b6102f5635ca1ab1e81565b6104066107543660046138a9565b612312565b6103ae7f000000000000000000000000000000000000000000000000000000000000000081565b6007546104e59067ffffffffffffffff1681565b6104066107a2366004613926565b612bcd565b61037c601b81565b6000546103ae9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610864573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610888919061399e565b6007549091506000906108b39067ffffffffffffffff680100000000000000008204811691166139e6565b67ffffffffffffffff169050806000036108d05760009250505090565b6108da8183613a0e565b9250505090565b600480546108ee90613a49565b80601f016020809104026020016040519081016040528092919081815260200182805461091a90613a49565b80156109675780601f1061093c57610100808354040283529160200191610967565b820191906000526020600020905b81548152906001019060200180831161094a57829003601f168201915b505050505081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633146109de576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168367ffffffffffffffff167f9c72852172521097ba7e1482e6b44b351323df0155f97f4ea18fcec28e1f596684604051610a3191815260200190565b60405180910390a3505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314610a95576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62093a8067ffffffffffffffff82161115610adc576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6b9190613a9c565b610bcc5760075467ffffffffffffffff700100000000000000000000000000000000909104811690821610610bcc576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000067ffffffffffffffff8416908102919091179091556040519081527fa7eb6cb8a613eb4e8bddc1ac3d61ec6cf10898760f0b187bcca794c6ca6fa40b906020015b60405180910390a150565b600380546108ee90613a49565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314610cb4576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ff54144f9611984021529f814a1cb6a41e22c58351510a0d9f7e822618abb9cc090602001610c45565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163314610d96576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff1615808015610db65750600054600160ff909116105b80610dd05750303b158015610dd0575060005460ff166001145b610e61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610ebf57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606073ffffffffffffffffffffffffffffffffffffffff851615611124576040517fc00f14ab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063c00f14ab90602401600060405180830381865afa158015610f69573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610faf9190810190613abe565b6040517f318aee3d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063318aee3d906024016040805180830381865afa158015611044573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110689190613b35565b915091508163ffffffff166000146110e0576009805463ffffffff841674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff841617179055611121565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff89161790555b50505b60095460009061116c90889073ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900463ffffffff1685611dd0565b9050600081805190602001209050600042905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611210919061399e565b90506000808483858f611224600143613b6f565b60408051602081019790975286019490945260608086019390935260c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000166080850152901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608883015240609c82015260bc01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815290829052805160209091012060058190557f9a908e73000000000000000000000000000000000000000000000000000000008252600160048301526024820181905291507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af115801561136d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113919190613b88565b508c600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555088600390816114239190613beb565b5060046114308982613beb565b508c600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062069780600760106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f060116213bcbf54ca19fd649dc84b59ab2bbd200ab199770e4d923e222a28e7f85838e6040516114d193929190613d05565b60405180910390a1505050505050801561154257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461159c576040517fd1ec4b2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff1673ffffffffffffffffffffffffffffffffffffffff9092166201000081029290921790556040519081527f056dc487bbf0795d0bbb1b4f0af523a855503cff740bfb4d5475f7a90c091e8e9060200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314611675576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085473ffffffffffffffffffffffffffffffffffffffff166116c4576040517fc89374d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f5fbd7dd171301c4a1611a84aac4ba86d119478560557755f7927595b082634fb90602001610c45565b60085473ffffffffffffffffffffffffffffffffffffffff168015801590611775575073ffffffffffffffffffffffffffffffffffffffff81163314155b156117ac576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4262093a807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166330c27dde6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561181c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118409190613b88565b61184a9190613d44565b67ffffffffffffffff16111561188c576040517f3d49ed4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160008190036118c8576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e8811115611904576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60075467ffffffffffffffff8082169161192c91849168010000000000000000900416613d65565b1115611964576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546005546801000000000000000090910467ffffffffffffffff169060005b83811015611c045760008787838181106119a1576119a1613d78565b90506020028101906119b39190613da7565b6119bc90613de5565b9050836119c881613e6e565b825180516020918201208185015160408087015160608801519151959a50929550600094611a35948794929101938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8916600090815260069093529120549091508114611abe576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8616600090815260066020526040812055611ae3600188613b6f565b8403611b525742600760109054906101000a900467ffffffffffffffff168460400151611b109190613d44565b67ffffffffffffffff161115611b52576040517fc44a082100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018b90529285018790528481019390935260c01b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808401523390911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc016040516020818303038152906040528051906020012094505050508080611bfc90613e95565b915050611985565b50611c7a7f000000000000000000000000000000000000000000000000000000000000000084611c326107d5565b611c3c9190613ecd565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016919061309f565b60058190556007805467ffffffffffffffff841668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161790556040517f9a908e7300000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690639a908e7390611d4c908790869060040167ffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af1158015611d6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d8f9190613b88565b60405190915067ffffffffffffffff8216907f648a61dd2438f072f5a1960939abd30f37aea80d2e94c9792ad142d3e0a490a490600090a250505050505050565b6060600085858573a40d5f56745a118d0906a34e69aec8c0db1cb8fa600087604051602401611e0496959493929190613ee4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff811bff7000000000000000000000000000000000000000000000000000000001790528351909150606090600003611f555760f9601f8351611e999190613f47565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525060e487604051602001611f3f9796959493929190613f62565b6040516020818303038152906040529050612059565b815161ffff1015611f92576040517f248b8f8200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160f9611fa1602083613f47565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525085886040516020016120469796959493929190614045565b6040516020818303038152906040529150505b805160208083019190912060408051600080825293810180835292909252601b908201526405ca1ab1e06060820152635ca1ab1e608082015260019060a0016020604051602081039080840390855afa1580156120ba573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612132576040517fcd16196600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516000906121789084906405ca1ab1e090635ca1ab1e90601b907fff0000000000000000000000000000000000000000000000000000000000000090602001614128565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529450505050505b949350505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16331461220c576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa5b56b7906fd0a20e3f35120dd8343db1e12e037a6c90111c7e42885e82a1ce690602001610c45565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146122d6576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60036122e28282613beb565b507f6b8f723a4c7a5335cafae8a598a0aa0301be1387c037dccc085b62add6448b2081604051610c4591906134c7565b60025473ffffffffffffffffffffffffffffffffffffffff163314612363576040517f11e7be1500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600081900361239f576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e88111156123db576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e6602442613d65565b8467ffffffffffffffff161115612429576040517f0a00feb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166379e2cf976040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561249157600080fd5b505af11580156124a5573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635ca1e1656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612516573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253a919061399e565b60075460055491925068010000000000000000900467ffffffffffffffff16908160005b858110156128605760008b8b8381811061257a5761257a613d78565b905060200281019061258c9190613da7565b61259590613de5565b8051805160209091012060408201519192509067ffffffffffffffff161561277a57856125c181613e6e565b9650506000818360200151846040015185606001516040516020016126249493929190938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8a166000908152600690935291205490915081146126ad576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018c90529285018790528481019390935260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166080840152908c901b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc01604051602081830303815290604052805190602001209550600660008867ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600090555061284b565b8151516201d4c010156127b9576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160208101879052908101829052606080820189905260c08d901b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808301528a901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660888201526000609c82015260bc016040516020818303038152906040528051906020012094505b5050808061285890613e95565b91505061255e565b5060075467ffffffffffffffff90811690841611156128ab576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60058290558467ffffffffffffffff848116908316146129615760006128d183866139e6565b90506128e767ffffffffffffffff821683613b6f565b91506129207f00000000000000000000000000000000000000000000000000000000000000008267ffffffffffffffff16611c326107d5565b50600780547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8716021790555b612a5f337f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663477fa2706040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a16919061399e565b612a209190613ecd565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016929190613178565b6040517f9a908e7300000000000000000000000000000000000000000000000000000000815267ffffffffffffffff87166004820152602481018490526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af1158015612aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b239190613b88565b9050612b2f87826139e6565b67ffffffffffffffff168967ffffffffffffffff1614612b7b576040517f1a070d9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8067ffffffffffffffff167f3e54d0825ed78523037d00a81759237eb436ce774bd546993ee67a1b67b6e76687604051612bb791815260200190565b60405180910390a2505050505050505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff168015801590612c0b575073ffffffffffffffffffffffffffffffffffffffff81163314155b15612c42576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd19190613a9c565b15612d08576040517f39258d1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663604691696040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d99919061399e565b905082811115612dd5576040517f2354600f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611388841115612e11576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084613178565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ec0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee4919061399e565b6007805491925067ffffffffffffffff909116906000612f0383613e6e565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550508585604051612f3a929190614184565b6040519081900390208142612f50600143613b6f565b60408051602081019590955284019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166060830152406068820152608801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060075467ffffffffffffffff166000908152600690935291205532330361304857600754604080518381523360208201526060818301819052600090820152905167ffffffffffffffff909216917ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc9319181900360800190a2613097565b60075460405167ffffffffffffffff909116907ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc9319061308e90849033908b908b90614194565b60405180910390a25b505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526131739084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526131dc565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526131d69085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016130f1565b50505050565b600061323e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166132e89092919063ffffffff16565b805190915015613173578080602001905181019061325c9190613a9c565b613173576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610e58565b60606121ad8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161331c9190614205565b60006040518083038185875af1925050503d8060008114613359576040519150601f19603f3d011682016040523d82523d6000602084013e61335e565b606091505b509150915061336f8783838761337a565b979650505050505050565b606083156134105782516000036134095773ffffffffffffffffffffffffffffffffffffffff85163b613409576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610e58565b50816121ad565b6121ad83838151156134255781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5891906134c7565b60005b8381101561347457818101518382015260200161345c565b50506000910152565b60008151808452613495816020860160208601613459565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006134da602083018461347d565b9392505050565b67ffffffffffffffff811681146134f757600080fd5b50565b73ffffffffffffffffffffffffffffffffffffffff811681146134f757600080fd5b60008060006060848603121561353157600080fd5b833561353c816134e1565b9250602084013591506040840135613553816134fa565b809150509250925092565b60006020828403121561357057600080fd5b81356134da816134e1565b60006020828403121561358d57600080fd5b81356134da816134fa565b63ffffffff811681146134f757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613620576136206135aa565b604052919050565b600067ffffffffffffffff821115613642576136426135aa565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261367f57600080fd5b813561369261368d82613628565b6135d9565b8181528460208386010111156136a757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156136dd57600080fd5b86356136e8816134fa565b955060208701356136f8816134fa565b9450604087013561370881613598565b93506060870135613718816134fa565b9250608087013567ffffffffffffffff8082111561373557600080fd5b6137418a838b0161366e565b935060a089013591508082111561375757600080fd5b5061376489828a0161366e565b9150509295509295509295565b60008083601f84011261378357600080fd5b50813567ffffffffffffffff81111561379b57600080fd5b6020830191508360208260051b85010111156137b657600080fd5b9250929050565b600080602083850312156137d057600080fd5b823567ffffffffffffffff8111156137e757600080fd5b6137f385828601613771565b90969095509350505050565b6000806000806080858703121561381557600080fd5b843561382081613598565b93506020850135613830816134fa565b9250604085013561384081613598565b9150606085013567ffffffffffffffff81111561385c57600080fd5b6138688782880161366e565b91505092959194509250565b60006020828403121561388657600080fd5b813567ffffffffffffffff81111561389d57600080fd5b6121ad8482850161366e565b6000806000806000608086880312156138c157600080fd5b853567ffffffffffffffff8111156138d857600080fd5b6138e488828901613771565b90965094505060208601356138f8816134e1565b92506040860135613908816134e1565b91506060860135613918816134fa565b809150509295509295909350565b60008060006040848603121561393b57600080fd5b833567ffffffffffffffff8082111561395357600080fd5b818601915086601f83011261396757600080fd5b81358181111561397657600080fd5b87602082850101111561398857600080fd5b6020928301989097509590910135949350505050565b6000602082840312156139b057600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115613a0757613a076139b7565b5092915050565b600082613a44577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600181811c90821680613a5d57607f821691505b602082108103613a96577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613aae57600080fd5b815180151581146134da57600080fd5b600060208284031215613ad057600080fd5b815167ffffffffffffffff811115613ae757600080fd5b8201601f81018413613af857600080fd5b8051613b0661368d82613628565b818152856020838501011115613b1b57600080fd5b613b2c826020830160208601613459565b95945050505050565b60008060408385031215613b4857600080fd5b8251613b5381613598565b6020840151909250613b64816134fa565b809150509250929050565b81810381811115613b8257613b826139b7565b92915050565b600060208284031215613b9a57600080fd5b81516134da816134e1565b601f82111561317357600081815260208120601f850160051c81016020861015613bcc5750805b601f850160051c820191505b8181101561309757828155600101613bd8565b815167ffffffffffffffff811115613c0557613c056135aa565b613c1981613c138454613a49565b84613ba5565b602080601f831160018114613c6c5760008415613c365750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613097565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613cb957888601518255948401946001909101908401613c9a565b5085821015613cf557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b606081526000613d18606083018661347d565b905083602083015273ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b67ffffffffffffffff818116838216019080821115613a0757613a076139b7565b80820180821115613b8257613b826139b7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112613ddb57600080fd5b9190910192915050565b600060808236031215613df757600080fd5b6040516080810167ffffffffffffffff8282108183111715613e1b57613e1b6135aa565b816040528435915080821115613e3057600080fd5b50613e3d3682860161366e565b825250602083013560208201526040830135613e58816134e1565b6040820152606092830135928101929092525090565b600067ffffffffffffffff808316818103613e8b57613e8b6139b7565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613ec657613ec66139b7565b5060010190565b8082028115828204841417613b8257613b826139b7565b600063ffffffff808916835273ffffffffffffffffffffffffffffffffffffffff8089166020850152818816604085015280871660608501528086166080850152505060c060a0830152613f3b60c083018461347d565b98975050505050505050565b61ffff818116838216019080821115613a0757613a076139b7565b60007fff00000000000000000000000000000000000000000000000000000000000000808a60f81b1683527fffff0000000000000000000000000000000000000000000000000000000000008960f01b1660018401528751613fcb816003860160208c01613459565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b166003820152865161400e816017840160208b01613459565b808201915050818660f81b16601782015284519150614034826018830160208801613459565b016018019998505050505050505050565b7fff000000000000000000000000000000000000000000000000000000000000008860f81b16815260007fffff000000000000000000000000000000000000000000000000000000000000808960f01b16600184015287516140ae816003860160208c01613459565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b16600382015286516140f1816017840160208b01613459565b808201915050818660f01b16601782015284519150614117826019830160208801613459565b016019019998505050505050505050565b6000865161413a818460208b01613459565b9190910194855250602084019290925260f81b7fff000000000000000000000000000000000000000000000000000000000000009081166040840152166041820152604201919050565b8183823760009101908152919050565b84815273ffffffffffffffffffffffffffffffffffffffff8416602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01601019392505050565b60008251613ddb81846020870161345956fea26469706673582212208984c2308dba308dc344163eec692d3156ed8e3b7becdc49922152f5b72cca8764736f6c63430008140033 \ No newline at end of file diff --git a/etherman/smartcontracts/etrogpolygonzkevm/etrogpolygonzkevm.go b/etherman/smartcontracts/etrogpolygonzkevm/etrogpolygonzkevm.go new file mode 100644 index 0000000000..a3a6ed9829 --- /dev/null +++ b/etherman/smartcontracts/etrogpolygonzkevm/etrogpolygonzkevm.go @@ -0,0 +1,3258 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package etrogpolygonzkevm + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "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/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// PolygonRollupBaseEtrogBatchData is an auto generated low-level Go binding around an user-defined struct. +type PolygonRollupBaseEtrogBatchData struct { + Transactions []byte + ForcedGlobalExitRoot [32]byte + ForcedTimestamp uint64 + ForcedBlockHashL1 [32]byte +} + +// EtrogpolygonzkevmMetaData contains all meta data concerning the Etrogpolygonzkevm contract. +var EtrogpolygonzkevmMetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[{\"internalType\":\"contractIPolygonZkEVMGlobalExitRootV2\",\"name\":\"_globalExitRootManager\",\"type\":\"address\"},{\"internalType\":\"contractIERC20Upgradeable\",\"name\":\"_pol\",\"type\":\"address\"},{\"internalType\":\"contractIPolygonZkEVMBridgeV2\",\"name\":\"_bridgeAddress\",\"type\":\"address\"},{\"internalType\":\"contractPolygonRollupManager\",\"name\":\"_rollupManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BatchAlreadyVerified\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BatchNotSequencedOrNotSequenceEnd\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExceedMaxVerifyBatches\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FinalNumBatchBelowLastVerifiedBatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FinalNumBatchDoesNotMatchPendingState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FinalPendingStateNumInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchTimeoutNotExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesDecentralized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesNotAllowedOnEmergencyState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesOverflow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForcedDataDoesNotMatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasTokenNetworkMustBeZeroOnEther\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GlobalExitRootNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HaltTimeoutNotExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HaltTimeoutNotExpiredAfterEmergencyState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HugeTokenMetadataNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InitNumBatchAboveLastVerifiedBatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InitNumBatchDoesNotMatchPendingState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitializeTransaction\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRangeBatchTimeTarget\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRangeForceBatchTimeout\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRangeMultiplierBatchFee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewAccInputHashDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewPendingStateTimeoutMustBeLower\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewStateRootNotInsidePrime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewTrustedAggregatorTimeoutMustBeLower\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughMaticAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughPOLAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OldAccInputHashDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OldStateRootDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRollupManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyTrustedAggregator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyTrustedSequencer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateNotConsolidable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateTimeoutExceedHaltAggregationTimeout\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SequenceZeroBatches\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SequencedTimestampBelowForcedTimestamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SequencedTimestampInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StoredRootMustBeDifferentThanNewRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransactionsLengthAboveMax\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TrustedAggregatorTimeoutExceedHaltAggregationTimeout\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TrustedAggregatorTimeoutNotExpired\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AcceptAdminRole\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"forceBatchNum\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"lastGlobalExitRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"}],\"name\":\"ForceBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"lastGlobalExitRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"}],\"name\":\"InitialSequenceBatches\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"l1InfoRoot\",\"type\":\"bytes32\"}],\"name\":\"SequenceBatches\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"}],\"name\":\"SequenceForceBatches\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newForceBatchAddress\",\"type\":\"address\"}],\"name\":\"SetForceBatchAddress\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newforceBatchTimeout\",\"type\":\"uint64\"}],\"name\":\"SetForceBatchTimeout\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTrustedSequencer\",\"type\":\"address\"}],\"name\":\"SetTrustedSequencer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"newTrustedSequencerURL\",\"type\":\"string\"}],\"name\":\"SetTrustedSequencerURL\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPendingAdmin\",\"type\":\"address\"}],\"name\":\"TransferAdminRole\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"lastGlobalExitRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"}],\"name\":\"UpdateEtrogSequence\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"VerifyBatches\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GLOBAL_EXIT_ROOT_MANAGER_L2\",\"outputs\":[{\"internalType\":\"contractIBasePolygonZkEVMGlobalExitRoot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_LIST_LEN_LEN\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_PARAMS\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS_EMPTY_METADATA\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_CONSTANT_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_CONSTANT_BYTES_EMPTY_METADATA\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_DATA_LEN_EMPTY_METADATA\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_EFFECTIVE_PERCENTAGE\",\"outputs\":[{\"internalType\":\"bytes1\",\"name\":\"\",\"type\":\"bytes1\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SET_UP_ETROG_TX\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SIGNATURE_INITIALIZE_TX_R\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SIGNATURE_INITIALIZE_TX_S\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SIGNATURE_INITIALIZE_TX_V\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridgeAddress\",\"outputs\":[{\"internalType\":\"contractIPolygonZkEVMBridgeV2\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"calculatePolPerForceBatch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"polAmount\",\"type\":\"uint256\"}],\"name\":\"forceBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"forceBatchAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"forceBatchTimeout\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"forcedBatches\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gasTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gasTokenNetwork\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"networkID\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_gasTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_gasTokenNetwork\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_gasTokenMetadata\",\"type\":\"bytes\"}],\"name\":\"generateInitializeTransaction\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalExitRootManager\",\"outputs\":[{\"internalType\":\"contractIPolygonZkEVMGlobalExitRootV2\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkID\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_gasTokenAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"sequencerURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_networkName\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_trustedSequencer\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_trustedSequencerURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_networkName\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"_lastAccInputHash\",\"type\":\"bytes32\"}],\"name\":\"initializeUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastAccInputHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastForceBatch\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastForceBatchSequenced\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"networkName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBatch\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"newStateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"onVerifyBatches\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pol\",\"outputs\":[{\"internalType\":\"contractIERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rollupManager\",\"outputs\":[{\"internalType\":\"contractPolygonRollupManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"forcedGlobalExitRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"forcedTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"forcedBlockHashL1\",\"type\":\"bytes32\"}],\"internalType\":\"structPolygonRollupBaseEtrog.BatchData[]\",\"name\":\"batches\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"l2Coinbase\",\"type\":\"address\"}],\"name\":\"sequenceBatches\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"forcedGlobalExitRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"forcedTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"forcedBlockHashL1\",\"type\":\"bytes32\"}],\"internalType\":\"structPolygonRollupBaseEtrog.BatchData[]\",\"name\":\"batches\",\"type\":\"tuple[]\"}],\"name\":\"sequenceForceBatches\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newForceBatchAddress\",\"type\":\"address\"}],\"name\":\"setForceBatchAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"newforceBatchTimeout\",\"type\":\"uint64\"}],\"name\":\"setForceBatchTimeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newTrustedSequencer\",\"type\":\"address\"}],\"name\":\"setTrustedSequencer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"newTrustedSequencerURL\",\"type\":\"string\"}],\"name\":\"setTrustedSequencerURL\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPendingAdmin\",\"type\":\"address\"}],\"name\":\"transferAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trustedSequencer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trustedSequencerURL\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b5060405162004a6138038062004a61833981016040819052620000359162000071565b6001600160a01b0393841660a052918316608052821660c0521660e052620000d9565b6001600160a01b03811681146200006e57600080fd5b50565b600080600080608085870312156200008857600080fd5b8451620000958162000058565b6020860151909450620000a88162000058565b6040860151909350620000bb8162000058565b6060860151909250620000ce8162000058565b939692955090935050565b60805160a05160c05160e05161488a620001d7600039600081816105060152818161098f01528181610afc01528181610c7d01528181610fd4015281816112de015281816118c101528181611d65015281816121bc015281816122b20152818161295701528181612a1f01528181613342015281816133bb015281816133dd01526134f5015260008181610673015281816114d2015281816115ac015281816124830152818161258b0152612e7c01526000818161073701528181610e450152818161173501528181612b6a0152612efe0152600081816107690152818161083b0152818161220501528181612b3e015261348b015261488a6000f3fe608060405234801561001057600080fd5b50600436106102f35760003560e01c80637a5460c511610191578063c7fffd4b116100e3578063e46761c411610097578063ecef3f9911610071578063ecef3f99146107b2578063f35dda47146107c5578063f851a440146107cd57600080fd5b8063e46761c414610764578063e7a7ed021461078b578063eaeb077b1461079f57600080fd5b8063cfa8ed47116100c8578063cfa8ed4714610712578063d02103ca14610732578063d7bc90ff1461075957600080fd5b8063c7fffd4b146106f7578063c89e42df146106ff57600080fd5b8063a3c573eb11610145578063af7f3e021161011f578063af7f3e02146106bb578063b0afe154146106c3578063c754c7ed146106cf57600080fd5b8063a3c573eb1461066e578063a652f26c14610695578063ada8f919146106a857600080fd5b806391cafe321161017657806391cafe321461062d5780639e001877146106405780639f26f8401461065b57600080fd5b80637a5460c5146105e95780638c3d73011461062557600080fd5b8063456052671161024a5780635d6717a5116101fe5780636e05d2cd116101d85780636e05d2cd146105ba5780636ff512cc146105c357806371257022146105d657600080fd5b80635d6717a51461057f578063676870d2146105925780636b8616ce1461059a57600080fd5b80634e4877061161022f5780634e4877061461052857806352bdeb6d1461053b578063542028d51461057757600080fd5b806345605267146104c857806349b7b8021461050157600080fd5b806326782247116102ac5780633c351e10116102865780633c351e10146104135780633cbc795b1461043357806340b5de6c1461047057600080fd5b806326782247146103995780632c111c06146103de57806332c2d153146103fe57600080fd5b806305835f37116102dd57806305835f371461032e578063107bf28c1461037757806311e892d41461037f57600080fd5b8062d0295d146102f85780630350896314610313575b600080fd5b6103006107f3565b6040519081526020015b60405180910390f35b61031b602081565b60405161ffff909116815260200161030a565b61036a6040518060400160405280600881526020017f80808401c9c3809400000000000000000000000000000000000000000000000081525081565b60405161030a91906139f2565b61036a6108ff565b61038760f981565b60405160ff909116815260200161030a565b6001546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030a565b6008546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b61041161040c366004613a47565b61098d565b005b6009546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b60095461045b9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161030a565b6104977fff0000000000000000000000000000000000000000000000000000000000000081565b6040517fff00000000000000000000000000000000000000000000000000000000000000909116815260200161030a565b6007546104e89068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161030a565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b610411610536366004613a89565b610a5c565b61036a6040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525081565b61036a610c6e565b61041161058d366004613bc0565b610c7b565b61031b601f81565b6103006105a8366004613a89565b60066020526000908152604090205481565b61030060055481565b6104116105d1366004613c51565b611212565b6104116105e4366004613c80565b6112dc565b61036a6040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525081565b610411611afd565b61041161063b366004613c51565b611bd0565b6103b973a40d5f56745a118d0906a34e69aec8c0db1cb8fa81565b610411610669366004613d79565b611ce9565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b61036a6106a3366004613dbb565b612382565b6104116106b6366004613c51565b612767565b61036a612831565b6103006405ca1ab1e081565b6007546104e890700100000000000000000000000000000000900467ffffffffffffffff1681565b61038760e481565b61041161070d366004613e30565b61284d565b6002546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b610300635ca1ab1e81565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b6007546104e89067ffffffffffffffff1681565b6104116107ad366004613e65565b6128e0565b6104116107c0366004613edd565b612db1565b610387601b81565b6000546103b99062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a69190613f29565b6007549091506000906108d19067ffffffffffffffff68010000000000000000820481169116613f71565b67ffffffffffffffff169050806000036108ee5760009250505090565b6108f88183613f99565b9250505090565b6004805461090c90613fd4565b80601f016020809104026020016040519081016040528092919081815260200182805461093890613fd4565b80156109855780601f1061095a57610100808354040283529160200191610985565b820191906000526020600020905b81548152906001019060200180831161096857829003601f168201915b505050505081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633146109fc576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168367ffffffffffffffff167f9c72852172521097ba7e1482e6b44b351323df0155f97f4ea18fcec28e1f596684604051610a4f91815260200190565b60405180910390a3505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314610ab3576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62093a8067ffffffffffffffff82161115610afa576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b899190614027565b610bea5760075467ffffffffffffffff700100000000000000000000000000000000909104811690821610610bea576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000067ffffffffffffffff8416908102919091179091556040519081527fa7eb6cb8a613eb4e8bddc1ac3d61ec6cf10898760f0b187bcca794c6ca6fa40b906020015b60405180910390a150565b6003805461090c90613fd4565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163314610cea576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff1615808015610d0a5750600054600160ff909116105b80610d245750303b158015610d24575060005460ff166001145b610db5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610e1357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60006040518060a00160405280606281526020016147f3606291399050600081805190602001209050600042905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610eae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed29190613f29565b90506000868483858d610ee6600143614049565b60408051602081019790975286019490945260608086019390935260c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000166080850152901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608883015240609c82015260bc01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815290829052805160209091012060058190557f9a908e73000000000000000000000000000000000000000000000000000000008252600160048301526024820181905291506000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af1158015611032573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110569190614062565b90508b600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508a600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555089600390816110e991906140c5565b5060046110f68a826140c5565b508b600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062069780600760106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507fd2c80353fc15ef62c6affc7cd6b7ab5b42c43290c50be3372e55ae552cecd19c8187858e60405161119994939291906141df565b60405180910390a1505050505050801561120a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314611269576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ff54144f9611984021529f814a1cb6a41e22c58351510a0d9f7e822618abb9cc090602001610c63565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16331461134b576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff161580801561136b5750600054600160ff909116105b806113855750303b158015611385575060005460ff166001145b611411576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610dac565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561146f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606073ffffffffffffffffffffffffffffffffffffffff8516156116d6576040517fc00f14ab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063c00f14ab90602401600060405180830381865afa158015611519573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261155f919081019061422f565b6040517f318aee3d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063318aee3d9060240160408051808303816000875af11580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a91906142a6565b915091508163ffffffff16600014611692576009805463ffffffff841674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff8416171790556116d3565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff89161790555b50505b60095460009061171e90889073ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900463ffffffff1685612382565b9050600081805190602001209050600042905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561179e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c29190613f29565b90506000808483858f6117d6600143614049565b60408051602081019790975286019490945260608086019390935260c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000166080850152901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608883015240609c82015260bc01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815290829052805160209091012060058190557f9a908e73000000000000000000000000000000000000000000000000000000008252600160048301526024820181905291507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af115801561191f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119439190614062565b508c600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555088600390816119d591906140c5565b5060046119e289826140c5565b508c600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062069780600760106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f060116213bcbf54ca19fd649dc84b59ab2bbd200ab199770e4d923e222a28e7f85838e604051611a83939291906142e0565b60405180910390a15050505050508015611af457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611b4e576040517fd1ec4b2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff1673ffffffffffffffffffffffffffffffffffffffff9092166201000081029290921790556040519081527f056dc487bbf0795d0bbb1b4f0af523a855503cff740bfb4d5475f7a90c091e8e9060200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314611c27576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085473ffffffffffffffffffffffffffffffffffffffff16611c76576040517fc89374d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f5fbd7dd171301c4a1611a84aac4ba86d119478560557755f7927595b082634fb90602001610c63565b60085473ffffffffffffffffffffffffffffffffffffffff168015801590611d27575073ffffffffffffffffffffffffffffffffffffffff81163314155b15611d5e576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4262093a807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166330c27dde6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df29190614062565b611dfc919061431f565b67ffffffffffffffff161115611e3e576040517f3d49ed4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816000819003611e7a576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e8811115611eb6576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60075467ffffffffffffffff80821691611ede91849168010000000000000000900416614340565b1115611f16576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546005546801000000000000000090910467ffffffffffffffff169060005b838110156121b6576000878783818110611f5357611f53614353565b9050602002810190611f659190614382565b611f6e906143c0565b905083611f7a81614449565b825180516020918201208185015160408087015160608801519151959a50929550600094611fe7948794929101938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8916600090815260069093529120549091508114612070576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8616600090815260066020526040812055612095600188614049565b84036121045742600760109054906101000a900467ffffffffffffffff1684604001516120c2919061431f565b67ffffffffffffffff161115612104576040517fc44a082100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018b90529285018790528481019390935260c01b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808401523390911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc0160405160208183030381529060405280519060200120945050505080806121ae90614470565b915050611f37565b5061222c7f0000000000000000000000000000000000000000000000000000000000000000846121e46107f3565b6121ee91906144a8565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001691906135ca565b60058190556007805467ffffffffffffffff841668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161790556040517f9a908e7300000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690639a908e73906122fe908790869060040167ffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af115801561231d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123419190614062565b60405190915067ffffffffffffffff8216907f648a61dd2438f072f5a1960939abd30f37aea80d2e94c9792ad142d3e0a490a490600090a250505050505050565b6060600085858573a40d5f56745a118d0906a34e69aec8c0db1cb8fa6000876040516024016123b6969594939291906144bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff811bff70000000000000000000000000000000000000000000000000000000017905283519091506060906000036125075760f9601f835161244b9190614522565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525060e4876040516020016124f1979695949392919061453d565b604051602081830303815290604052905061260b565b815161ffff1015612544576040517f248b8f8200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160f9612553602083614522565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525085886040516020016125f89796959493929190614620565b6040516020818303038152906040529150505b805160208083019190912060408051600080825293810180835292909252601b908201526405ca1ab1e06060820152635ca1ab1e608082015260019060a0016020604051602081039080840390855afa15801561266c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166126e4576040517fcd16196600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405160009061272a9084906405ca1ab1e090635ca1ab1e90601b907fff0000000000000000000000000000000000000000000000000000000000000090602001614703565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529450505050505b949350505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146127be576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa5b56b7906fd0a20e3f35120dd8343db1e12e037a6c90111c7e42885e82a1ce690602001610c63565b6040518060a00160405280606281526020016147f36062913981565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146128a4576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60036128b082826140c5565b507f6b8f723a4c7a5335cafae8a598a0aa0301be1387c037dccc085b62add6448b2081604051610c6391906139f2565b60085473ffffffffffffffffffffffffffffffffffffffff16801580159061291e575073ffffffffffffffffffffffffffffffffffffffff81163314155b15612955576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e49190614027565b15612a1b576040517f39258d1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663604691696040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aac9190613f29565b905082811115612ae8576040517f2354600f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611388841115612b24576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846136a3565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf79190613f29565b6007805491925067ffffffffffffffff909116906000612c1683614449565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550508585604051612c4d92919061475f565b6040519081900390208142612c63600143614049565b60408051602081019590955284019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166060830152406068820152608801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060075467ffffffffffffffff1660009081526006909352912055323303612d5b57600754604080518381523360208201526060818301819052600090820152905167ffffffffffffffff909216917ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc9319181900360800190a261120a565b60075460405167ffffffffffffffff909116907ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc93190612da190849033908b908b9061476f565b60405180910390a2505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314612e02576040517f11e7be1500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816000819003612e3e576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e8811115612e7a576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166379e2cf976040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612ee257600080fd5b505af1158015612ef6573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635ca1e1656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8b9190613f29565b60075460055491925042916801000000000000000090910467ffffffffffffffff16908160005b868110156132b45760008a8a83818110612fce57612fce614353565b9050602002810190612fe09190614382565b612fe9906143c0565b8051805160209091012060408201519192509067ffffffffffffffff16156131ce578561301581614449565b9650506000818360200151846040015185606001516040516020016130789493929190938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8a16600090815260069093529120549091508114613101576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018c90529285018790528481019390935260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166080840152908d901b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc01604051602081830303815290604052805190602001209550600660008867ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600090555061329f565b8151516201d4c0101561320d576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020810187905290810182905260608082018a905260c089901b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808301528b901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660888201526000609c82015260bc016040516020818303038152906040528051906020012094505b505080806132ac90614470565b915050612fb2565b5060075467ffffffffffffffff90811690841611156132ff576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60058290558567ffffffffffffffff848116908316146133b55760006133258386613f71565b905061333b67ffffffffffffffff821683614049565b91506133747f00000000000000000000000000000000000000000000000000000000000000008267ffffffffffffffff166121e46107f3565b50600780547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8716021790555b6134b3337f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663477fa2706040518163ffffffff1660e01b8152600401602060405180830381865afa158015613446573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346a9190613f29565b61347491906144a8565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169291906136a3565b6040517f9a908e7300000000000000000000000000000000000000000000000000000000815267ffffffffffffffff88166004820152602481018490526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af1158015613553573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135779190614062565b90508067ffffffffffffffff167f3e54d0825ed78523037d00a81759237eb436ce774bd546993ee67a1b67b6e766886040516135b591815260200190565b60405180910390a25050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261369e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613707565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526137019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161361c565b50505050565b6000613769826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138139092919063ffffffff16565b80519091501561369e57808060200190518101906137879190614027565b61369e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610dac565b606061275f8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161384791906147e0565b60006040518083038185875af1925050503d8060008114613884576040519150601f19603f3d011682016040523d82523d6000602084013e613889565b606091505b509150915061389a878383876138a5565b979650505050505050565b6060831561393b5782516000036139345773ffffffffffffffffffffffffffffffffffffffff85163b613934576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610dac565b508161275f565b61275f83838151156139505781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dac91906139f2565b60005b8381101561399f578181015183820152602001613987565b50506000910152565b600081518084526139c0816020860160208601613984565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a0560208301846139a8565b9392505050565b67ffffffffffffffff81168114613a2257600080fd5b50565b73ffffffffffffffffffffffffffffffffffffffff81168114613a2257600080fd5b600080600060608486031215613a5c57600080fd5b8335613a6781613a0c565b9250602084013591506040840135613a7e81613a25565b809150509250925092565b600060208284031215613a9b57600080fd5b8135613a0581613a0c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613b1c57613b1c613aa6565b604052919050565b600067ffffffffffffffff821115613b3e57613b3e613aa6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613b7b57600080fd5b8135613b8e613b8982613b24565b613ad5565b818152846020838601011115613ba357600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215613bd857600080fd5b8535613be381613a25565b94506020860135613bf381613a25565b9350604086013567ffffffffffffffff80821115613c1057600080fd5b613c1c89838a01613b6a565b94506060880135915080821115613c3257600080fd5b50613c3f88828901613b6a565b95989497509295608001359392505050565b600060208284031215613c6357600080fd5b8135613a0581613a25565b63ffffffff81168114613a2257600080fd5b60008060008060008060c08789031215613c9957600080fd5b8635613ca481613a25565b95506020870135613cb481613a25565b94506040870135613cc481613c6e565b93506060870135613cd481613a25565b9250608087013567ffffffffffffffff80821115613cf157600080fd5b613cfd8a838b01613b6a565b935060a0890135915080821115613d1357600080fd5b50613d2089828a01613b6a565b9150509295509295509295565b60008083601f840112613d3f57600080fd5b50813567ffffffffffffffff811115613d5757600080fd5b6020830191508360208260051b8501011115613d7257600080fd5b9250929050565b60008060208385031215613d8c57600080fd5b823567ffffffffffffffff811115613da357600080fd5b613daf85828601613d2d565b90969095509350505050565b60008060008060808587031215613dd157600080fd5b8435613ddc81613c6e565b93506020850135613dec81613a25565b92506040850135613dfc81613c6e565b9150606085013567ffffffffffffffff811115613e1857600080fd5b613e2487828801613b6a565b91505092959194509250565b600060208284031215613e4257600080fd5b813567ffffffffffffffff811115613e5957600080fd5b61275f84828501613b6a565b600080600060408486031215613e7a57600080fd5b833567ffffffffffffffff80821115613e9257600080fd5b818601915086601f830112613ea657600080fd5b813581811115613eb557600080fd5b876020828501011115613ec757600080fd5b6020928301989097509590910135949350505050565b600080600060408486031215613ef257600080fd5b833567ffffffffffffffff811115613f0957600080fd5b613f1586828701613d2d565b9094509250506020840135613a7e81613a25565b600060208284031215613f3b57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115613f9257613f92613f42565b5092915050565b600082613fcf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600181811c90821680613fe857607f821691505b602082108103614021577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561403957600080fd5b81518015158114613a0557600080fd5b8181038181111561405c5761405c613f42565b92915050565b60006020828403121561407457600080fd5b8151613a0581613a0c565b601f82111561369e57600081815260208120601f850160051c810160208610156140a65750805b601f850160051c820191505b8181101561120a578281556001016140b2565b815167ffffffffffffffff8111156140df576140df613aa6565b6140f3816140ed8454613fd4565b8461407f565b602080601f83116001811461414657600084156141105750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561120a565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561419357888601518255948401946001909101908401614174565b50858210156141cf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff8516815260806020820152600061420260808301866139a8565b905083604083015273ffffffffffffffffffffffffffffffffffffffff8316606083015295945050505050565b60006020828403121561424157600080fd5b815167ffffffffffffffff81111561425857600080fd5b8201601f8101841361426957600080fd5b8051614277613b8982613b24565b81815285602083850101111561428c57600080fd5b61429d826020830160208601613984565b95945050505050565b600080604083850312156142b957600080fd5b82516142c481613c6e565b60208401519092506142d581613a25565b809150509250929050565b6060815260006142f360608301866139a8565b905083602083015273ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b67ffffffffffffffff818116838216019080821115613f9257613f92613f42565b8082018082111561405c5761405c613f42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126143b657600080fd5b9190910192915050565b6000608082360312156143d257600080fd5b6040516080810167ffffffffffffffff82821081831117156143f6576143f6613aa6565b81604052843591508082111561440b57600080fd5b5061441836828601613b6a565b82525060208301356020820152604083013561443381613a0c565b6040820152606092830135928101929092525090565b600067ffffffffffffffff80831681810361446657614466613f42565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144a1576144a1613f42565b5060010190565b808202811582820484141761405c5761405c613f42565b600063ffffffff808916835273ffffffffffffffffffffffffffffffffffffffff8089166020850152818816604085015280871660608501528086166080850152505060c060a083015261451660c08301846139a8565b98975050505050505050565b61ffff818116838216019080821115613f9257613f92613f42565b60007fff00000000000000000000000000000000000000000000000000000000000000808a60f81b1683527fffff0000000000000000000000000000000000000000000000000000000000008960f01b16600184015287516145a6816003860160208c01613984565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b16600382015286516145e9816017840160208b01613984565b808201915050818660f81b1660178201528451915061460f826018830160208801613984565b016018019998505050505050505050565b7fff000000000000000000000000000000000000000000000000000000000000008860f81b16815260007fffff000000000000000000000000000000000000000000000000000000000000808960f01b1660018401528751614689816003860160208c01613984565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b16600382015286516146cc816017840160208b01613984565b808201915050818660f01b166017820152845191506146f2826019830160208801613984565b016019019998505050505050505050565b60008651614715818460208b01613984565b9190910194855250602084019290925260f81b7fff000000000000000000000000000000000000000000000000000000000000009081166040840152166041820152604201919050565b8183823760009101908152919050565b84815273ffffffffffffffffffffffffffffffffffffffff8416602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01601019392505050565b600082516143b681846020870161398456fedf2a8080944d5cf5032b2a844602278b01199ed191a86c93ff8080821092808000000000000000000000000000000000000000000000000000000005ca1ab1e000000000000000000000000000000000000000000000000000000005ca1ab1e01bffa26469706673582212201221389ded8ea187a66f83d3bd052755e28647dbf3bc616c9e91e0a8b7ecf74364736f6c63430008140033", +} + +// EtrogpolygonzkevmABI is the input ABI used to generate the binding from. +// Deprecated: Use EtrogpolygonzkevmMetaData.ABI instead. +var EtrogpolygonzkevmABI = EtrogpolygonzkevmMetaData.ABI + +// EtrogpolygonzkevmBin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use EtrogpolygonzkevmMetaData.Bin instead. +var EtrogpolygonzkevmBin = EtrogpolygonzkevmMetaData.Bin + +// DeployEtrogpolygonzkevm deploys a new Ethereum contract, binding an instance of Etrogpolygonzkevm to it. +func DeployEtrogpolygonzkevm(auth *bind.TransactOpts, backend bind.ContractBackend, _globalExitRootManager common.Address, _pol common.Address, _bridgeAddress common.Address, _rollupManager common.Address) (common.Address, *types.Transaction, *Etrogpolygonzkevm, error) { + parsed, err := EtrogpolygonzkevmMetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(EtrogpolygonzkevmBin), backend, _globalExitRootManager, _pol, _bridgeAddress, _rollupManager) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Etrogpolygonzkevm{EtrogpolygonzkevmCaller: EtrogpolygonzkevmCaller{contract: contract}, EtrogpolygonzkevmTransactor: EtrogpolygonzkevmTransactor{contract: contract}, EtrogpolygonzkevmFilterer: EtrogpolygonzkevmFilterer{contract: contract}}, nil +} + +// Etrogpolygonzkevm is an auto generated Go binding around an Ethereum contract. +type Etrogpolygonzkevm struct { + EtrogpolygonzkevmCaller // Read-only binding to the contract + EtrogpolygonzkevmTransactor // Write-only binding to the contract + EtrogpolygonzkevmFilterer // Log filterer for contract events +} + +// EtrogpolygonzkevmCaller is an auto generated read-only Go binding around an Ethereum contract. +type EtrogpolygonzkevmCaller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EtrogpolygonzkevmTransactor is an auto generated write-only Go binding around an Ethereum contract. +type EtrogpolygonzkevmTransactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EtrogpolygonzkevmFilterer is an auto generated log filtering Go binding around an Ethereum contract events. +type EtrogpolygonzkevmFilterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// EtrogpolygonzkevmSession is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type EtrogpolygonzkevmSession struct { + Contract *Etrogpolygonzkevm // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// EtrogpolygonzkevmCallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type EtrogpolygonzkevmCallerSession struct { + Contract *EtrogpolygonzkevmCaller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// EtrogpolygonzkevmTransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type EtrogpolygonzkevmTransactorSession struct { + Contract *EtrogpolygonzkevmTransactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// EtrogpolygonzkevmRaw is an auto generated low-level Go binding around an Ethereum contract. +type EtrogpolygonzkevmRaw struct { + Contract *Etrogpolygonzkevm // Generic contract binding to access the raw methods on +} + +// EtrogpolygonzkevmCallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type EtrogpolygonzkevmCallerRaw struct { + Contract *EtrogpolygonzkevmCaller // Generic read-only contract binding to access the raw methods on +} + +// EtrogpolygonzkevmTransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type EtrogpolygonzkevmTransactorRaw struct { + Contract *EtrogpolygonzkevmTransactor // Generic write-only contract binding to access the raw methods on +} + +// NewEtrogpolygonzkevm creates a new instance of Etrogpolygonzkevm, bound to a specific deployed contract. +func NewEtrogpolygonzkevm(address common.Address, backend bind.ContractBackend) (*Etrogpolygonzkevm, error) { + contract, err := bindEtrogpolygonzkevm(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Etrogpolygonzkevm{EtrogpolygonzkevmCaller: EtrogpolygonzkevmCaller{contract: contract}, EtrogpolygonzkevmTransactor: EtrogpolygonzkevmTransactor{contract: contract}, EtrogpolygonzkevmFilterer: EtrogpolygonzkevmFilterer{contract: contract}}, nil +} + +// NewEtrogpolygonzkevmCaller creates a new read-only instance of Etrogpolygonzkevm, bound to a specific deployed contract. +func NewEtrogpolygonzkevmCaller(address common.Address, caller bind.ContractCaller) (*EtrogpolygonzkevmCaller, error) { + contract, err := bindEtrogpolygonzkevm(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmCaller{contract: contract}, nil +} + +// NewEtrogpolygonzkevmTransactor creates a new write-only instance of Etrogpolygonzkevm, bound to a specific deployed contract. +func NewEtrogpolygonzkevmTransactor(address common.Address, transactor bind.ContractTransactor) (*EtrogpolygonzkevmTransactor, error) { + contract, err := bindEtrogpolygonzkevm(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmTransactor{contract: contract}, nil +} + +// NewEtrogpolygonzkevmFilterer creates a new log filterer instance of Etrogpolygonzkevm, bound to a specific deployed contract. +func NewEtrogpolygonzkevmFilterer(address common.Address, filterer bind.ContractFilterer) (*EtrogpolygonzkevmFilterer, error) { + contract, err := bindEtrogpolygonzkevm(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmFilterer{contract: contract}, nil +} + +// bindEtrogpolygonzkevm binds a generic wrapper to an already deployed contract. +func bindEtrogpolygonzkevm(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := EtrogpolygonzkevmMetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Etrogpolygonzkevm *EtrogpolygonzkevmRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Etrogpolygonzkevm.Contract.EtrogpolygonzkevmCaller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Etrogpolygonzkevm *EtrogpolygonzkevmRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.EtrogpolygonzkevmTransactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Etrogpolygonzkevm *EtrogpolygonzkevmRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.EtrogpolygonzkevmTransactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Etrogpolygonzkevm.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.contract.Transact(opts, method, params...) +} + +// GLOBALEXITROOTMANAGERL2 is a free data retrieval call binding the contract method 0x9e001877. +// +// Solidity: function GLOBAL_EXIT_ROOT_MANAGER_L2() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) GLOBALEXITROOTMANAGERL2(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "GLOBAL_EXIT_ROOT_MANAGER_L2") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GLOBALEXITROOTMANAGERL2 is a free data retrieval call binding the contract method 0x9e001877. +// +// Solidity: function GLOBAL_EXIT_ROOT_MANAGER_L2() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) GLOBALEXITROOTMANAGERL2() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.GLOBALEXITROOTMANAGERL2(&_Etrogpolygonzkevm.CallOpts) +} + +// GLOBALEXITROOTMANAGERL2 is a free data retrieval call binding the contract method 0x9e001877. +// +// Solidity: function GLOBAL_EXIT_ROOT_MANAGER_L2() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) GLOBALEXITROOTMANAGERL2() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.GLOBALEXITROOTMANAGERL2(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXBRIDGELISTLENLEN is a free data retrieval call binding the contract method 0x11e892d4. +// +// Solidity: function INITIALIZE_TX_BRIDGE_LIST_LEN_LEN() view returns(uint8) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) INITIALIZETXBRIDGELISTLENLEN(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "INITIALIZE_TX_BRIDGE_LIST_LEN_LEN") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// INITIALIZETXBRIDGELISTLENLEN is a free data retrieval call binding the contract method 0x11e892d4. +// +// Solidity: function INITIALIZE_TX_BRIDGE_LIST_LEN_LEN() view returns(uint8) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) INITIALIZETXBRIDGELISTLENLEN() (uint8, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXBRIDGELISTLENLEN(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXBRIDGELISTLENLEN is a free data retrieval call binding the contract method 0x11e892d4. +// +// Solidity: function INITIALIZE_TX_BRIDGE_LIST_LEN_LEN() view returns(uint8) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) INITIALIZETXBRIDGELISTLENLEN() (uint8, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXBRIDGELISTLENLEN(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXBRIDGEPARAMS is a free data retrieval call binding the contract method 0x05835f37. +// +// Solidity: function INITIALIZE_TX_BRIDGE_PARAMS() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) INITIALIZETXBRIDGEPARAMS(opts *bind.CallOpts) ([]byte, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "INITIALIZE_TX_BRIDGE_PARAMS") + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// INITIALIZETXBRIDGEPARAMS is a free data retrieval call binding the contract method 0x05835f37. +// +// Solidity: function INITIALIZE_TX_BRIDGE_PARAMS() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) INITIALIZETXBRIDGEPARAMS() ([]byte, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXBRIDGEPARAMS(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXBRIDGEPARAMS is a free data retrieval call binding the contract method 0x05835f37. +// +// Solidity: function INITIALIZE_TX_BRIDGE_PARAMS() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) INITIALIZETXBRIDGEPARAMS() ([]byte, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXBRIDGEPARAMS(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESS is a free data retrieval call binding the contract method 0x7a5460c5. +// +// Solidity: function INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESS(opts *bind.CallOpts) ([]byte, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS") + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESS is a free data retrieval call binding the contract method 0x7a5460c5. +// +// Solidity: function INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESS() ([]byte, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESS(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESS is a free data retrieval call binding the contract method 0x7a5460c5. +// +// Solidity: function INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESS() ([]byte, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESS(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESSEMPTYMETADATA is a free data retrieval call binding the contract method 0x52bdeb6d. +// +// Solidity: function INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS_EMPTY_METADATA() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESSEMPTYMETADATA(opts *bind.CallOpts) ([]byte, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS_EMPTY_METADATA") + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESSEMPTYMETADATA is a free data retrieval call binding the contract method 0x52bdeb6d. +// +// Solidity: function INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS_EMPTY_METADATA() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESSEMPTYMETADATA() ([]byte, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESSEMPTYMETADATA(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESSEMPTYMETADATA is a free data retrieval call binding the contract method 0x52bdeb6d. +// +// Solidity: function INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS_EMPTY_METADATA() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESSEMPTYMETADATA() ([]byte, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXBRIDGEPARAMSAFTERBRIDGEADDRESSEMPTYMETADATA(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXCONSTANTBYTES is a free data retrieval call binding the contract method 0x03508963. +// +// Solidity: function INITIALIZE_TX_CONSTANT_BYTES() view returns(uint16) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) INITIALIZETXCONSTANTBYTES(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "INITIALIZE_TX_CONSTANT_BYTES") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// INITIALIZETXCONSTANTBYTES is a free data retrieval call binding the contract method 0x03508963. +// +// Solidity: function INITIALIZE_TX_CONSTANT_BYTES() view returns(uint16) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) INITIALIZETXCONSTANTBYTES() (uint16, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXCONSTANTBYTES(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXCONSTANTBYTES is a free data retrieval call binding the contract method 0x03508963. +// +// Solidity: function INITIALIZE_TX_CONSTANT_BYTES() view returns(uint16) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) INITIALIZETXCONSTANTBYTES() (uint16, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXCONSTANTBYTES(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXCONSTANTBYTESEMPTYMETADATA is a free data retrieval call binding the contract method 0x676870d2. +// +// Solidity: function INITIALIZE_TX_CONSTANT_BYTES_EMPTY_METADATA() view returns(uint16) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) INITIALIZETXCONSTANTBYTESEMPTYMETADATA(opts *bind.CallOpts) (uint16, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "INITIALIZE_TX_CONSTANT_BYTES_EMPTY_METADATA") + + if err != nil { + return *new(uint16), err + } + + out0 := *abi.ConvertType(out[0], new(uint16)).(*uint16) + + return out0, err + +} + +// INITIALIZETXCONSTANTBYTESEMPTYMETADATA is a free data retrieval call binding the contract method 0x676870d2. +// +// Solidity: function INITIALIZE_TX_CONSTANT_BYTES_EMPTY_METADATA() view returns(uint16) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) INITIALIZETXCONSTANTBYTESEMPTYMETADATA() (uint16, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXCONSTANTBYTESEMPTYMETADATA(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXCONSTANTBYTESEMPTYMETADATA is a free data retrieval call binding the contract method 0x676870d2. +// +// Solidity: function INITIALIZE_TX_CONSTANT_BYTES_EMPTY_METADATA() view returns(uint16) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) INITIALIZETXCONSTANTBYTESEMPTYMETADATA() (uint16, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXCONSTANTBYTESEMPTYMETADATA(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXDATALENEMPTYMETADATA is a free data retrieval call binding the contract method 0xc7fffd4b. +// +// Solidity: function INITIALIZE_TX_DATA_LEN_EMPTY_METADATA() view returns(uint8) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) INITIALIZETXDATALENEMPTYMETADATA(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "INITIALIZE_TX_DATA_LEN_EMPTY_METADATA") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// INITIALIZETXDATALENEMPTYMETADATA is a free data retrieval call binding the contract method 0xc7fffd4b. +// +// Solidity: function INITIALIZE_TX_DATA_LEN_EMPTY_METADATA() view returns(uint8) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) INITIALIZETXDATALENEMPTYMETADATA() (uint8, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXDATALENEMPTYMETADATA(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXDATALENEMPTYMETADATA is a free data retrieval call binding the contract method 0xc7fffd4b. +// +// Solidity: function INITIALIZE_TX_DATA_LEN_EMPTY_METADATA() view returns(uint8) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) INITIALIZETXDATALENEMPTYMETADATA() (uint8, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXDATALENEMPTYMETADATA(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXEFFECTIVEPERCENTAGE is a free data retrieval call binding the contract method 0x40b5de6c. +// +// Solidity: function INITIALIZE_TX_EFFECTIVE_PERCENTAGE() view returns(bytes1) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) INITIALIZETXEFFECTIVEPERCENTAGE(opts *bind.CallOpts) ([1]byte, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "INITIALIZE_TX_EFFECTIVE_PERCENTAGE") + + if err != nil { + return *new([1]byte), err + } + + out0 := *abi.ConvertType(out[0], new([1]byte)).(*[1]byte) + + return out0, err + +} + +// INITIALIZETXEFFECTIVEPERCENTAGE is a free data retrieval call binding the contract method 0x40b5de6c. +// +// Solidity: function INITIALIZE_TX_EFFECTIVE_PERCENTAGE() view returns(bytes1) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) INITIALIZETXEFFECTIVEPERCENTAGE() ([1]byte, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXEFFECTIVEPERCENTAGE(&_Etrogpolygonzkevm.CallOpts) +} + +// INITIALIZETXEFFECTIVEPERCENTAGE is a free data retrieval call binding the contract method 0x40b5de6c. +// +// Solidity: function INITIALIZE_TX_EFFECTIVE_PERCENTAGE() view returns(bytes1) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) INITIALIZETXEFFECTIVEPERCENTAGE() ([1]byte, error) { + return _Etrogpolygonzkevm.Contract.INITIALIZETXEFFECTIVEPERCENTAGE(&_Etrogpolygonzkevm.CallOpts) +} + +// SETUPETROGTX is a free data retrieval call binding the contract method 0xaf7f3e02. +// +// Solidity: function SET_UP_ETROG_TX() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) SETUPETROGTX(opts *bind.CallOpts) ([]byte, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "SET_UP_ETROG_TX") + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// SETUPETROGTX is a free data retrieval call binding the contract method 0xaf7f3e02. +// +// Solidity: function SET_UP_ETROG_TX() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) SETUPETROGTX() ([]byte, error) { + return _Etrogpolygonzkevm.Contract.SETUPETROGTX(&_Etrogpolygonzkevm.CallOpts) +} + +// SETUPETROGTX is a free data retrieval call binding the contract method 0xaf7f3e02. +// +// Solidity: function SET_UP_ETROG_TX() view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) SETUPETROGTX() ([]byte, error) { + return _Etrogpolygonzkevm.Contract.SETUPETROGTX(&_Etrogpolygonzkevm.CallOpts) +} + +// SIGNATUREINITIALIZETXR is a free data retrieval call binding the contract method 0xb0afe154. +// +// Solidity: function SIGNATURE_INITIALIZE_TX_R() view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) SIGNATUREINITIALIZETXR(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "SIGNATURE_INITIALIZE_TX_R") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// SIGNATUREINITIALIZETXR is a free data retrieval call binding the contract method 0xb0afe154. +// +// Solidity: function SIGNATURE_INITIALIZE_TX_R() view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) SIGNATUREINITIALIZETXR() ([32]byte, error) { + return _Etrogpolygonzkevm.Contract.SIGNATUREINITIALIZETXR(&_Etrogpolygonzkevm.CallOpts) +} + +// SIGNATUREINITIALIZETXR is a free data retrieval call binding the contract method 0xb0afe154. +// +// Solidity: function SIGNATURE_INITIALIZE_TX_R() view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) SIGNATUREINITIALIZETXR() ([32]byte, error) { + return _Etrogpolygonzkevm.Contract.SIGNATUREINITIALIZETXR(&_Etrogpolygonzkevm.CallOpts) +} + +// SIGNATUREINITIALIZETXS is a free data retrieval call binding the contract method 0xd7bc90ff. +// +// Solidity: function SIGNATURE_INITIALIZE_TX_S() view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) SIGNATUREINITIALIZETXS(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "SIGNATURE_INITIALIZE_TX_S") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// SIGNATUREINITIALIZETXS is a free data retrieval call binding the contract method 0xd7bc90ff. +// +// Solidity: function SIGNATURE_INITIALIZE_TX_S() view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) SIGNATUREINITIALIZETXS() ([32]byte, error) { + return _Etrogpolygonzkevm.Contract.SIGNATUREINITIALIZETXS(&_Etrogpolygonzkevm.CallOpts) +} + +// SIGNATUREINITIALIZETXS is a free data retrieval call binding the contract method 0xd7bc90ff. +// +// Solidity: function SIGNATURE_INITIALIZE_TX_S() view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) SIGNATUREINITIALIZETXS() ([32]byte, error) { + return _Etrogpolygonzkevm.Contract.SIGNATUREINITIALIZETXS(&_Etrogpolygonzkevm.CallOpts) +} + +// SIGNATUREINITIALIZETXV is a free data retrieval call binding the contract method 0xf35dda47. +// +// Solidity: function SIGNATURE_INITIALIZE_TX_V() view returns(uint8) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) SIGNATUREINITIALIZETXV(opts *bind.CallOpts) (uint8, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "SIGNATURE_INITIALIZE_TX_V") + + if err != nil { + return *new(uint8), err + } + + out0 := *abi.ConvertType(out[0], new(uint8)).(*uint8) + + return out0, err + +} + +// SIGNATUREINITIALIZETXV is a free data retrieval call binding the contract method 0xf35dda47. +// +// Solidity: function SIGNATURE_INITIALIZE_TX_V() view returns(uint8) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) SIGNATUREINITIALIZETXV() (uint8, error) { + return _Etrogpolygonzkevm.Contract.SIGNATUREINITIALIZETXV(&_Etrogpolygonzkevm.CallOpts) +} + +// SIGNATUREINITIALIZETXV is a free data retrieval call binding the contract method 0xf35dda47. +// +// Solidity: function SIGNATURE_INITIALIZE_TX_V() view returns(uint8) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) SIGNATUREINITIALIZETXV() (uint8, error) { + return _Etrogpolygonzkevm.Contract.SIGNATUREINITIALIZETXV(&_Etrogpolygonzkevm.CallOpts) +} + +// Admin is a free data retrieval call binding the contract method 0xf851a440. +// +// Solidity: function admin() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) Admin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "admin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Admin is a free data retrieval call binding the contract method 0xf851a440. +// +// Solidity: function admin() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) Admin() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.Admin(&_Etrogpolygonzkevm.CallOpts) +} + +// Admin is a free data retrieval call binding the contract method 0xf851a440. +// +// Solidity: function admin() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) Admin() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.Admin(&_Etrogpolygonzkevm.CallOpts) +} + +// BridgeAddress is a free data retrieval call binding the contract method 0xa3c573eb. +// +// Solidity: function bridgeAddress() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) BridgeAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "bridgeAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// BridgeAddress is a free data retrieval call binding the contract method 0xa3c573eb. +// +// Solidity: function bridgeAddress() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) BridgeAddress() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.BridgeAddress(&_Etrogpolygonzkevm.CallOpts) +} + +// BridgeAddress is a free data retrieval call binding the contract method 0xa3c573eb. +// +// Solidity: function bridgeAddress() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) BridgeAddress() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.BridgeAddress(&_Etrogpolygonzkevm.CallOpts) +} + +// CalculatePolPerForceBatch is a free data retrieval call binding the contract method 0x00d0295d. +// +// Solidity: function calculatePolPerForceBatch() view returns(uint256) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) CalculatePolPerForceBatch(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "calculatePolPerForceBatch") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// CalculatePolPerForceBatch is a free data retrieval call binding the contract method 0x00d0295d. +// +// Solidity: function calculatePolPerForceBatch() view returns(uint256) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) CalculatePolPerForceBatch() (*big.Int, error) { + return _Etrogpolygonzkevm.Contract.CalculatePolPerForceBatch(&_Etrogpolygonzkevm.CallOpts) +} + +// CalculatePolPerForceBatch is a free data retrieval call binding the contract method 0x00d0295d. +// +// Solidity: function calculatePolPerForceBatch() view returns(uint256) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) CalculatePolPerForceBatch() (*big.Int, error) { + return _Etrogpolygonzkevm.Contract.CalculatePolPerForceBatch(&_Etrogpolygonzkevm.CallOpts) +} + +// ForceBatchAddress is a free data retrieval call binding the contract method 0x2c111c06. +// +// Solidity: function forceBatchAddress() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) ForceBatchAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "forceBatchAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// ForceBatchAddress is a free data retrieval call binding the contract method 0x2c111c06. +// +// Solidity: function forceBatchAddress() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) ForceBatchAddress() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.ForceBatchAddress(&_Etrogpolygonzkevm.CallOpts) +} + +// ForceBatchAddress is a free data retrieval call binding the contract method 0x2c111c06. +// +// Solidity: function forceBatchAddress() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) ForceBatchAddress() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.ForceBatchAddress(&_Etrogpolygonzkevm.CallOpts) +} + +// ForceBatchTimeout is a free data retrieval call binding the contract method 0xc754c7ed. +// +// Solidity: function forceBatchTimeout() view returns(uint64) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) ForceBatchTimeout(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "forceBatchTimeout") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// ForceBatchTimeout is a free data retrieval call binding the contract method 0xc754c7ed. +// +// Solidity: function forceBatchTimeout() view returns(uint64) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) ForceBatchTimeout() (uint64, error) { + return _Etrogpolygonzkevm.Contract.ForceBatchTimeout(&_Etrogpolygonzkevm.CallOpts) +} + +// ForceBatchTimeout is a free data retrieval call binding the contract method 0xc754c7ed. +// +// Solidity: function forceBatchTimeout() view returns(uint64) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) ForceBatchTimeout() (uint64, error) { + return _Etrogpolygonzkevm.Contract.ForceBatchTimeout(&_Etrogpolygonzkevm.CallOpts) +} + +// ForcedBatches is a free data retrieval call binding the contract method 0x6b8616ce. +// +// Solidity: function forcedBatches(uint64 ) view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) ForcedBatches(opts *bind.CallOpts, arg0 uint64) ([32]byte, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "forcedBatches", arg0) + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// ForcedBatches is a free data retrieval call binding the contract method 0x6b8616ce. +// +// Solidity: function forcedBatches(uint64 ) view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) ForcedBatches(arg0 uint64) ([32]byte, error) { + return _Etrogpolygonzkevm.Contract.ForcedBatches(&_Etrogpolygonzkevm.CallOpts, arg0) +} + +// ForcedBatches is a free data retrieval call binding the contract method 0x6b8616ce. +// +// Solidity: function forcedBatches(uint64 ) view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) ForcedBatches(arg0 uint64) ([32]byte, error) { + return _Etrogpolygonzkevm.Contract.ForcedBatches(&_Etrogpolygonzkevm.CallOpts, arg0) +} + +// GasTokenAddress is a free data retrieval call binding the contract method 0x3c351e10. +// +// Solidity: function gasTokenAddress() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) GasTokenAddress(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "gasTokenAddress") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GasTokenAddress is a free data retrieval call binding the contract method 0x3c351e10. +// +// Solidity: function gasTokenAddress() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) GasTokenAddress() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.GasTokenAddress(&_Etrogpolygonzkevm.CallOpts) +} + +// GasTokenAddress is a free data retrieval call binding the contract method 0x3c351e10. +// +// Solidity: function gasTokenAddress() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) GasTokenAddress() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.GasTokenAddress(&_Etrogpolygonzkevm.CallOpts) +} + +// GasTokenNetwork is a free data retrieval call binding the contract method 0x3cbc795b. +// +// Solidity: function gasTokenNetwork() view returns(uint32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) GasTokenNetwork(opts *bind.CallOpts) (uint32, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "gasTokenNetwork") + + if err != nil { + return *new(uint32), err + } + + out0 := *abi.ConvertType(out[0], new(uint32)).(*uint32) + + return out0, err + +} + +// GasTokenNetwork is a free data retrieval call binding the contract method 0x3cbc795b. +// +// Solidity: function gasTokenNetwork() view returns(uint32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) GasTokenNetwork() (uint32, error) { + return _Etrogpolygonzkevm.Contract.GasTokenNetwork(&_Etrogpolygonzkevm.CallOpts) +} + +// GasTokenNetwork is a free data retrieval call binding the contract method 0x3cbc795b. +// +// Solidity: function gasTokenNetwork() view returns(uint32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) GasTokenNetwork() (uint32, error) { + return _Etrogpolygonzkevm.Contract.GasTokenNetwork(&_Etrogpolygonzkevm.CallOpts) +} + +// GenerateInitializeTransaction is a free data retrieval call binding the contract method 0xa652f26c. +// +// Solidity: function generateInitializeTransaction(uint32 networkID, address _gasTokenAddress, uint32 _gasTokenNetwork, bytes _gasTokenMetadata) view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) GenerateInitializeTransaction(opts *bind.CallOpts, networkID uint32, _gasTokenAddress common.Address, _gasTokenNetwork uint32, _gasTokenMetadata []byte) ([]byte, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "generateInitializeTransaction", networkID, _gasTokenAddress, _gasTokenNetwork, _gasTokenMetadata) + + if err != nil { + return *new([]byte), err + } + + out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) + + return out0, err + +} + +// GenerateInitializeTransaction is a free data retrieval call binding the contract method 0xa652f26c. +// +// Solidity: function generateInitializeTransaction(uint32 networkID, address _gasTokenAddress, uint32 _gasTokenNetwork, bytes _gasTokenMetadata) view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) GenerateInitializeTransaction(networkID uint32, _gasTokenAddress common.Address, _gasTokenNetwork uint32, _gasTokenMetadata []byte) ([]byte, error) { + return _Etrogpolygonzkevm.Contract.GenerateInitializeTransaction(&_Etrogpolygonzkevm.CallOpts, networkID, _gasTokenAddress, _gasTokenNetwork, _gasTokenMetadata) +} + +// GenerateInitializeTransaction is a free data retrieval call binding the contract method 0xa652f26c. +// +// Solidity: function generateInitializeTransaction(uint32 networkID, address _gasTokenAddress, uint32 _gasTokenNetwork, bytes _gasTokenMetadata) view returns(bytes) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) GenerateInitializeTransaction(networkID uint32, _gasTokenAddress common.Address, _gasTokenNetwork uint32, _gasTokenMetadata []byte) ([]byte, error) { + return _Etrogpolygonzkevm.Contract.GenerateInitializeTransaction(&_Etrogpolygonzkevm.CallOpts, networkID, _gasTokenAddress, _gasTokenNetwork, _gasTokenMetadata) +} + +// GlobalExitRootManager is a free data retrieval call binding the contract method 0xd02103ca. +// +// Solidity: function globalExitRootManager() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) GlobalExitRootManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "globalExitRootManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// GlobalExitRootManager is a free data retrieval call binding the contract method 0xd02103ca. +// +// Solidity: function globalExitRootManager() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) GlobalExitRootManager() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.GlobalExitRootManager(&_Etrogpolygonzkevm.CallOpts) +} + +// GlobalExitRootManager is a free data retrieval call binding the contract method 0xd02103ca. +// +// Solidity: function globalExitRootManager() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) GlobalExitRootManager() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.GlobalExitRootManager(&_Etrogpolygonzkevm.CallOpts) +} + +// LastAccInputHash is a free data retrieval call binding the contract method 0x6e05d2cd. +// +// Solidity: function lastAccInputHash() view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) LastAccInputHash(opts *bind.CallOpts) ([32]byte, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "lastAccInputHash") + + if err != nil { + return *new([32]byte), err + } + + out0 := *abi.ConvertType(out[0], new([32]byte)).(*[32]byte) + + return out0, err + +} + +// LastAccInputHash is a free data retrieval call binding the contract method 0x6e05d2cd. +// +// Solidity: function lastAccInputHash() view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) LastAccInputHash() ([32]byte, error) { + return _Etrogpolygonzkevm.Contract.LastAccInputHash(&_Etrogpolygonzkevm.CallOpts) +} + +// LastAccInputHash is a free data retrieval call binding the contract method 0x6e05d2cd. +// +// Solidity: function lastAccInputHash() view returns(bytes32) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) LastAccInputHash() ([32]byte, error) { + return _Etrogpolygonzkevm.Contract.LastAccInputHash(&_Etrogpolygonzkevm.CallOpts) +} + +// LastForceBatch is a free data retrieval call binding the contract method 0xe7a7ed02. +// +// Solidity: function lastForceBatch() view returns(uint64) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) LastForceBatch(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "lastForceBatch") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastForceBatch is a free data retrieval call binding the contract method 0xe7a7ed02. +// +// Solidity: function lastForceBatch() view returns(uint64) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) LastForceBatch() (uint64, error) { + return _Etrogpolygonzkevm.Contract.LastForceBatch(&_Etrogpolygonzkevm.CallOpts) +} + +// LastForceBatch is a free data retrieval call binding the contract method 0xe7a7ed02. +// +// Solidity: function lastForceBatch() view returns(uint64) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) LastForceBatch() (uint64, error) { + return _Etrogpolygonzkevm.Contract.LastForceBatch(&_Etrogpolygonzkevm.CallOpts) +} + +// LastForceBatchSequenced is a free data retrieval call binding the contract method 0x45605267. +// +// Solidity: function lastForceBatchSequenced() view returns(uint64) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) LastForceBatchSequenced(opts *bind.CallOpts) (uint64, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "lastForceBatchSequenced") + + if err != nil { + return *new(uint64), err + } + + out0 := *abi.ConvertType(out[0], new(uint64)).(*uint64) + + return out0, err + +} + +// LastForceBatchSequenced is a free data retrieval call binding the contract method 0x45605267. +// +// Solidity: function lastForceBatchSequenced() view returns(uint64) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) LastForceBatchSequenced() (uint64, error) { + return _Etrogpolygonzkevm.Contract.LastForceBatchSequenced(&_Etrogpolygonzkevm.CallOpts) +} + +// LastForceBatchSequenced is a free data retrieval call binding the contract method 0x45605267. +// +// Solidity: function lastForceBatchSequenced() view returns(uint64) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) LastForceBatchSequenced() (uint64, error) { + return _Etrogpolygonzkevm.Contract.LastForceBatchSequenced(&_Etrogpolygonzkevm.CallOpts) +} + +// NetworkName is a free data retrieval call binding the contract method 0x107bf28c. +// +// Solidity: function networkName() view returns(string) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) NetworkName(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "networkName") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// NetworkName is a free data retrieval call binding the contract method 0x107bf28c. +// +// Solidity: function networkName() view returns(string) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) NetworkName() (string, error) { + return _Etrogpolygonzkevm.Contract.NetworkName(&_Etrogpolygonzkevm.CallOpts) +} + +// NetworkName is a free data retrieval call binding the contract method 0x107bf28c. +// +// Solidity: function networkName() view returns(string) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) NetworkName() (string, error) { + return _Etrogpolygonzkevm.Contract.NetworkName(&_Etrogpolygonzkevm.CallOpts) +} + +// PendingAdmin is a free data retrieval call binding the contract method 0x26782247. +// +// Solidity: function pendingAdmin() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) PendingAdmin(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "pendingAdmin") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// PendingAdmin is a free data retrieval call binding the contract method 0x26782247. +// +// Solidity: function pendingAdmin() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) PendingAdmin() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.PendingAdmin(&_Etrogpolygonzkevm.CallOpts) +} + +// PendingAdmin is a free data retrieval call binding the contract method 0x26782247. +// +// Solidity: function pendingAdmin() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) PendingAdmin() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.PendingAdmin(&_Etrogpolygonzkevm.CallOpts) +} + +// Pol is a free data retrieval call binding the contract method 0xe46761c4. +// +// Solidity: function pol() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) Pol(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "pol") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// Pol is a free data retrieval call binding the contract method 0xe46761c4. +// +// Solidity: function pol() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) Pol() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.Pol(&_Etrogpolygonzkevm.CallOpts) +} + +// Pol is a free data retrieval call binding the contract method 0xe46761c4. +// +// Solidity: function pol() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) Pol() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.Pol(&_Etrogpolygonzkevm.CallOpts) +} + +// RollupManager is a free data retrieval call binding the contract method 0x49b7b802. +// +// Solidity: function rollupManager() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) RollupManager(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "rollupManager") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// RollupManager is a free data retrieval call binding the contract method 0x49b7b802. +// +// Solidity: function rollupManager() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) RollupManager() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.RollupManager(&_Etrogpolygonzkevm.CallOpts) +} + +// RollupManager is a free data retrieval call binding the contract method 0x49b7b802. +// +// Solidity: function rollupManager() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) RollupManager() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.RollupManager(&_Etrogpolygonzkevm.CallOpts) +} + +// TrustedSequencer is a free data retrieval call binding the contract method 0xcfa8ed47. +// +// Solidity: function trustedSequencer() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) TrustedSequencer(opts *bind.CallOpts) (common.Address, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "trustedSequencer") + + if err != nil { + return *new(common.Address), err + } + + out0 := *abi.ConvertType(out[0], new(common.Address)).(*common.Address) + + return out0, err + +} + +// TrustedSequencer is a free data retrieval call binding the contract method 0xcfa8ed47. +// +// Solidity: function trustedSequencer() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) TrustedSequencer() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.TrustedSequencer(&_Etrogpolygonzkevm.CallOpts) +} + +// TrustedSequencer is a free data retrieval call binding the contract method 0xcfa8ed47. +// +// Solidity: function trustedSequencer() view returns(address) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) TrustedSequencer() (common.Address, error) { + return _Etrogpolygonzkevm.Contract.TrustedSequencer(&_Etrogpolygonzkevm.CallOpts) +} + +// TrustedSequencerURL is a free data retrieval call binding the contract method 0x542028d5. +// +// Solidity: function trustedSequencerURL() view returns(string) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCaller) TrustedSequencerURL(opts *bind.CallOpts) (string, error) { + var out []interface{} + err := _Etrogpolygonzkevm.contract.Call(opts, &out, "trustedSequencerURL") + + if err != nil { + return *new(string), err + } + + out0 := *abi.ConvertType(out[0], new(string)).(*string) + + return out0, err + +} + +// TrustedSequencerURL is a free data retrieval call binding the contract method 0x542028d5. +// +// Solidity: function trustedSequencerURL() view returns(string) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) TrustedSequencerURL() (string, error) { + return _Etrogpolygonzkevm.Contract.TrustedSequencerURL(&_Etrogpolygonzkevm.CallOpts) +} + +// TrustedSequencerURL is a free data retrieval call binding the contract method 0x542028d5. +// +// Solidity: function trustedSequencerURL() view returns(string) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmCallerSession) TrustedSequencerURL() (string, error) { + return _Etrogpolygonzkevm.Contract.TrustedSequencerURL(&_Etrogpolygonzkevm.CallOpts) +} + +// AcceptAdminRole is a paid mutator transaction binding the contract method 0x8c3d7301. +// +// Solidity: function acceptAdminRole() returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) AcceptAdminRole(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "acceptAdminRole") +} + +// AcceptAdminRole is a paid mutator transaction binding the contract method 0x8c3d7301. +// +// Solidity: function acceptAdminRole() returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) AcceptAdminRole() (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.AcceptAdminRole(&_Etrogpolygonzkevm.TransactOpts) +} + +// AcceptAdminRole is a paid mutator transaction binding the contract method 0x8c3d7301. +// +// Solidity: function acceptAdminRole() returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) AcceptAdminRole() (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.AcceptAdminRole(&_Etrogpolygonzkevm.TransactOpts) +} + +// ForceBatch is a paid mutator transaction binding the contract method 0xeaeb077b. +// +// Solidity: function forceBatch(bytes transactions, uint256 polAmount) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) ForceBatch(opts *bind.TransactOpts, transactions []byte, polAmount *big.Int) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "forceBatch", transactions, polAmount) +} + +// ForceBatch is a paid mutator transaction binding the contract method 0xeaeb077b. +// +// Solidity: function forceBatch(bytes transactions, uint256 polAmount) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) ForceBatch(transactions []byte, polAmount *big.Int) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.ForceBatch(&_Etrogpolygonzkevm.TransactOpts, transactions, polAmount) +} + +// ForceBatch is a paid mutator transaction binding the contract method 0xeaeb077b. +// +// Solidity: function forceBatch(bytes transactions, uint256 polAmount) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) ForceBatch(transactions []byte, polAmount *big.Int) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.ForceBatch(&_Etrogpolygonzkevm.TransactOpts, transactions, polAmount) +} + +// Initialize is a paid mutator transaction binding the contract method 0x71257022. +// +// Solidity: function initialize(address _admin, address sequencer, uint32 networkID, address _gasTokenAddress, string sequencerURL, string _networkName) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) Initialize(opts *bind.TransactOpts, _admin common.Address, sequencer common.Address, networkID uint32, _gasTokenAddress common.Address, sequencerURL string, _networkName string) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "initialize", _admin, sequencer, networkID, _gasTokenAddress, sequencerURL, _networkName) +} + +// Initialize is a paid mutator transaction binding the contract method 0x71257022. +// +// Solidity: function initialize(address _admin, address sequencer, uint32 networkID, address _gasTokenAddress, string sequencerURL, string _networkName) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) Initialize(_admin common.Address, sequencer common.Address, networkID uint32, _gasTokenAddress common.Address, sequencerURL string, _networkName string) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.Initialize(&_Etrogpolygonzkevm.TransactOpts, _admin, sequencer, networkID, _gasTokenAddress, sequencerURL, _networkName) +} + +// Initialize is a paid mutator transaction binding the contract method 0x71257022. +// +// Solidity: function initialize(address _admin, address sequencer, uint32 networkID, address _gasTokenAddress, string sequencerURL, string _networkName) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) Initialize(_admin common.Address, sequencer common.Address, networkID uint32, _gasTokenAddress common.Address, sequencerURL string, _networkName string) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.Initialize(&_Etrogpolygonzkevm.TransactOpts, _admin, sequencer, networkID, _gasTokenAddress, sequencerURL, _networkName) +} + +// InitializeUpgrade is a paid mutator transaction binding the contract method 0x5d6717a5. +// +// Solidity: function initializeUpgrade(address _admin, address _trustedSequencer, string _trustedSequencerURL, string _networkName, bytes32 _lastAccInputHash) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) InitializeUpgrade(opts *bind.TransactOpts, _admin common.Address, _trustedSequencer common.Address, _trustedSequencerURL string, _networkName string, _lastAccInputHash [32]byte) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "initializeUpgrade", _admin, _trustedSequencer, _trustedSequencerURL, _networkName, _lastAccInputHash) +} + +// InitializeUpgrade is a paid mutator transaction binding the contract method 0x5d6717a5. +// +// Solidity: function initializeUpgrade(address _admin, address _trustedSequencer, string _trustedSequencerURL, string _networkName, bytes32 _lastAccInputHash) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) InitializeUpgrade(_admin common.Address, _trustedSequencer common.Address, _trustedSequencerURL string, _networkName string, _lastAccInputHash [32]byte) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.InitializeUpgrade(&_Etrogpolygonzkevm.TransactOpts, _admin, _trustedSequencer, _trustedSequencerURL, _networkName, _lastAccInputHash) +} + +// InitializeUpgrade is a paid mutator transaction binding the contract method 0x5d6717a5. +// +// Solidity: function initializeUpgrade(address _admin, address _trustedSequencer, string _trustedSequencerURL, string _networkName, bytes32 _lastAccInputHash) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) InitializeUpgrade(_admin common.Address, _trustedSequencer common.Address, _trustedSequencerURL string, _networkName string, _lastAccInputHash [32]byte) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.InitializeUpgrade(&_Etrogpolygonzkevm.TransactOpts, _admin, _trustedSequencer, _trustedSequencerURL, _networkName, _lastAccInputHash) +} + +// OnVerifyBatches is a paid mutator transaction binding the contract method 0x32c2d153. +// +// Solidity: function onVerifyBatches(uint64 lastVerifiedBatch, bytes32 newStateRoot, address aggregator) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) OnVerifyBatches(opts *bind.TransactOpts, lastVerifiedBatch uint64, newStateRoot [32]byte, aggregator common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "onVerifyBatches", lastVerifiedBatch, newStateRoot, aggregator) +} + +// OnVerifyBatches is a paid mutator transaction binding the contract method 0x32c2d153. +// +// Solidity: function onVerifyBatches(uint64 lastVerifiedBatch, bytes32 newStateRoot, address aggregator) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) OnVerifyBatches(lastVerifiedBatch uint64, newStateRoot [32]byte, aggregator common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.OnVerifyBatches(&_Etrogpolygonzkevm.TransactOpts, lastVerifiedBatch, newStateRoot, aggregator) +} + +// OnVerifyBatches is a paid mutator transaction binding the contract method 0x32c2d153. +// +// Solidity: function onVerifyBatches(uint64 lastVerifiedBatch, bytes32 newStateRoot, address aggregator) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) OnVerifyBatches(lastVerifiedBatch uint64, newStateRoot [32]byte, aggregator common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.OnVerifyBatches(&_Etrogpolygonzkevm.TransactOpts, lastVerifiedBatch, newStateRoot, aggregator) +} + +// SequenceBatches is a paid mutator transaction binding the contract method 0xecef3f99. +// +// Solidity: function sequenceBatches((bytes,bytes32,uint64,bytes32)[] batches, address l2Coinbase) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) SequenceBatches(opts *bind.TransactOpts, batches []PolygonRollupBaseEtrogBatchData, l2Coinbase common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "sequenceBatches", batches, l2Coinbase) +} + +// SequenceBatches is a paid mutator transaction binding the contract method 0xecef3f99. +// +// Solidity: function sequenceBatches((bytes,bytes32,uint64,bytes32)[] batches, address l2Coinbase) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) SequenceBatches(batches []PolygonRollupBaseEtrogBatchData, l2Coinbase common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SequenceBatches(&_Etrogpolygonzkevm.TransactOpts, batches, l2Coinbase) +} + +// SequenceBatches is a paid mutator transaction binding the contract method 0xecef3f99. +// +// Solidity: function sequenceBatches((bytes,bytes32,uint64,bytes32)[] batches, address l2Coinbase) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) SequenceBatches(batches []PolygonRollupBaseEtrogBatchData, l2Coinbase common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SequenceBatches(&_Etrogpolygonzkevm.TransactOpts, batches, l2Coinbase) +} + +// SequenceForceBatches is a paid mutator transaction binding the contract method 0x9f26f840. +// +// Solidity: function sequenceForceBatches((bytes,bytes32,uint64,bytes32)[] batches) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) SequenceForceBatches(opts *bind.TransactOpts, batches []PolygonRollupBaseEtrogBatchData) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "sequenceForceBatches", batches) +} + +// SequenceForceBatches is a paid mutator transaction binding the contract method 0x9f26f840. +// +// Solidity: function sequenceForceBatches((bytes,bytes32,uint64,bytes32)[] batches) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) SequenceForceBatches(batches []PolygonRollupBaseEtrogBatchData) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SequenceForceBatches(&_Etrogpolygonzkevm.TransactOpts, batches) +} + +// SequenceForceBatches is a paid mutator transaction binding the contract method 0x9f26f840. +// +// Solidity: function sequenceForceBatches((bytes,bytes32,uint64,bytes32)[] batches) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) SequenceForceBatches(batches []PolygonRollupBaseEtrogBatchData) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SequenceForceBatches(&_Etrogpolygonzkevm.TransactOpts, batches) +} + +// SetForceBatchAddress is a paid mutator transaction binding the contract method 0x91cafe32. +// +// Solidity: function setForceBatchAddress(address newForceBatchAddress) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) SetForceBatchAddress(opts *bind.TransactOpts, newForceBatchAddress common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "setForceBatchAddress", newForceBatchAddress) +} + +// SetForceBatchAddress is a paid mutator transaction binding the contract method 0x91cafe32. +// +// Solidity: function setForceBatchAddress(address newForceBatchAddress) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) SetForceBatchAddress(newForceBatchAddress common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SetForceBatchAddress(&_Etrogpolygonzkevm.TransactOpts, newForceBatchAddress) +} + +// SetForceBatchAddress is a paid mutator transaction binding the contract method 0x91cafe32. +// +// Solidity: function setForceBatchAddress(address newForceBatchAddress) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) SetForceBatchAddress(newForceBatchAddress common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SetForceBatchAddress(&_Etrogpolygonzkevm.TransactOpts, newForceBatchAddress) +} + +// SetForceBatchTimeout is a paid mutator transaction binding the contract method 0x4e487706. +// +// Solidity: function setForceBatchTimeout(uint64 newforceBatchTimeout) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) SetForceBatchTimeout(opts *bind.TransactOpts, newforceBatchTimeout uint64) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "setForceBatchTimeout", newforceBatchTimeout) +} + +// SetForceBatchTimeout is a paid mutator transaction binding the contract method 0x4e487706. +// +// Solidity: function setForceBatchTimeout(uint64 newforceBatchTimeout) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) SetForceBatchTimeout(newforceBatchTimeout uint64) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SetForceBatchTimeout(&_Etrogpolygonzkevm.TransactOpts, newforceBatchTimeout) +} + +// SetForceBatchTimeout is a paid mutator transaction binding the contract method 0x4e487706. +// +// Solidity: function setForceBatchTimeout(uint64 newforceBatchTimeout) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) SetForceBatchTimeout(newforceBatchTimeout uint64) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SetForceBatchTimeout(&_Etrogpolygonzkevm.TransactOpts, newforceBatchTimeout) +} + +// SetTrustedSequencer is a paid mutator transaction binding the contract method 0x6ff512cc. +// +// Solidity: function setTrustedSequencer(address newTrustedSequencer) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) SetTrustedSequencer(opts *bind.TransactOpts, newTrustedSequencer common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "setTrustedSequencer", newTrustedSequencer) +} + +// SetTrustedSequencer is a paid mutator transaction binding the contract method 0x6ff512cc. +// +// Solidity: function setTrustedSequencer(address newTrustedSequencer) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) SetTrustedSequencer(newTrustedSequencer common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SetTrustedSequencer(&_Etrogpolygonzkevm.TransactOpts, newTrustedSequencer) +} + +// SetTrustedSequencer is a paid mutator transaction binding the contract method 0x6ff512cc. +// +// Solidity: function setTrustedSequencer(address newTrustedSequencer) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) SetTrustedSequencer(newTrustedSequencer common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SetTrustedSequencer(&_Etrogpolygonzkevm.TransactOpts, newTrustedSequencer) +} + +// SetTrustedSequencerURL is a paid mutator transaction binding the contract method 0xc89e42df. +// +// Solidity: function setTrustedSequencerURL(string newTrustedSequencerURL) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) SetTrustedSequencerURL(opts *bind.TransactOpts, newTrustedSequencerURL string) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "setTrustedSequencerURL", newTrustedSequencerURL) +} + +// SetTrustedSequencerURL is a paid mutator transaction binding the contract method 0xc89e42df. +// +// Solidity: function setTrustedSequencerURL(string newTrustedSequencerURL) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) SetTrustedSequencerURL(newTrustedSequencerURL string) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SetTrustedSequencerURL(&_Etrogpolygonzkevm.TransactOpts, newTrustedSequencerURL) +} + +// SetTrustedSequencerURL is a paid mutator transaction binding the contract method 0xc89e42df. +// +// Solidity: function setTrustedSequencerURL(string newTrustedSequencerURL) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) SetTrustedSequencerURL(newTrustedSequencerURL string) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.SetTrustedSequencerURL(&_Etrogpolygonzkevm.TransactOpts, newTrustedSequencerURL) +} + +// TransferAdminRole is a paid mutator transaction binding the contract method 0xada8f919. +// +// Solidity: function transferAdminRole(address newPendingAdmin) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactor) TransferAdminRole(opts *bind.TransactOpts, newPendingAdmin common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.contract.Transact(opts, "transferAdminRole", newPendingAdmin) +} + +// TransferAdminRole is a paid mutator transaction binding the contract method 0xada8f919. +// +// Solidity: function transferAdminRole(address newPendingAdmin) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmSession) TransferAdminRole(newPendingAdmin common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.TransferAdminRole(&_Etrogpolygonzkevm.TransactOpts, newPendingAdmin) +} + +// TransferAdminRole is a paid mutator transaction binding the contract method 0xada8f919. +// +// Solidity: function transferAdminRole(address newPendingAdmin) returns() +func (_Etrogpolygonzkevm *EtrogpolygonzkevmTransactorSession) TransferAdminRole(newPendingAdmin common.Address) (*types.Transaction, error) { + return _Etrogpolygonzkevm.Contract.TransferAdminRole(&_Etrogpolygonzkevm.TransactOpts, newPendingAdmin) +} + +// EtrogpolygonzkevmAcceptAdminRoleIterator is returned from FilterAcceptAdminRole and is used to iterate over the raw logs and unpacked data for AcceptAdminRole events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmAcceptAdminRoleIterator struct { + Event *EtrogpolygonzkevmAcceptAdminRole // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmAcceptAdminRoleIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmAcceptAdminRole) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmAcceptAdminRole) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmAcceptAdminRoleIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmAcceptAdminRoleIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmAcceptAdminRole represents a AcceptAdminRole event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmAcceptAdminRole struct { + NewAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterAcceptAdminRole is a free log retrieval operation binding the contract event 0x056dc487bbf0795d0bbb1b4f0af523a855503cff740bfb4d5475f7a90c091e8e. +// +// Solidity: event AcceptAdminRole(address newAdmin) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterAcceptAdminRole(opts *bind.FilterOpts) (*EtrogpolygonzkevmAcceptAdminRoleIterator, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "AcceptAdminRole") + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmAcceptAdminRoleIterator{contract: _Etrogpolygonzkevm.contract, event: "AcceptAdminRole", logs: logs, sub: sub}, nil +} + +// WatchAcceptAdminRole is a free log subscription operation binding the contract event 0x056dc487bbf0795d0bbb1b4f0af523a855503cff740bfb4d5475f7a90c091e8e. +// +// Solidity: event AcceptAdminRole(address newAdmin) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchAcceptAdminRole(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmAcceptAdminRole) (event.Subscription, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "AcceptAdminRole") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmAcceptAdminRole) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "AcceptAdminRole", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseAcceptAdminRole is a log parse operation binding the contract event 0x056dc487bbf0795d0bbb1b4f0af523a855503cff740bfb4d5475f7a90c091e8e. +// +// Solidity: event AcceptAdminRole(address newAdmin) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseAcceptAdminRole(log types.Log) (*EtrogpolygonzkevmAcceptAdminRole, error) { + event := new(EtrogpolygonzkevmAcceptAdminRole) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "AcceptAdminRole", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmForceBatchIterator is returned from FilterForceBatch and is used to iterate over the raw logs and unpacked data for ForceBatch events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmForceBatchIterator struct { + Event *EtrogpolygonzkevmForceBatch // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmForceBatchIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmForceBatch) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmForceBatch) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmForceBatchIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmForceBatchIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmForceBatch represents a ForceBatch event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmForceBatch struct { + ForceBatchNum uint64 + LastGlobalExitRoot [32]byte + Sequencer common.Address + Transactions []byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterForceBatch is a free log retrieval operation binding the contract event 0xf94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc931. +// +// Solidity: event ForceBatch(uint64 indexed forceBatchNum, bytes32 lastGlobalExitRoot, address sequencer, bytes transactions) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterForceBatch(opts *bind.FilterOpts, forceBatchNum []uint64) (*EtrogpolygonzkevmForceBatchIterator, error) { + + var forceBatchNumRule []interface{} + for _, forceBatchNumItem := range forceBatchNum { + forceBatchNumRule = append(forceBatchNumRule, forceBatchNumItem) + } + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "ForceBatch", forceBatchNumRule) + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmForceBatchIterator{contract: _Etrogpolygonzkevm.contract, event: "ForceBatch", logs: logs, sub: sub}, nil +} + +// WatchForceBatch is a free log subscription operation binding the contract event 0xf94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc931. +// +// Solidity: event ForceBatch(uint64 indexed forceBatchNum, bytes32 lastGlobalExitRoot, address sequencer, bytes transactions) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchForceBatch(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmForceBatch, forceBatchNum []uint64) (event.Subscription, error) { + + var forceBatchNumRule []interface{} + for _, forceBatchNumItem := range forceBatchNum { + forceBatchNumRule = append(forceBatchNumRule, forceBatchNumItem) + } + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "ForceBatch", forceBatchNumRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmForceBatch) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "ForceBatch", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseForceBatch is a log parse operation binding the contract event 0xf94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc931. +// +// Solidity: event ForceBatch(uint64 indexed forceBatchNum, bytes32 lastGlobalExitRoot, address sequencer, bytes transactions) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseForceBatch(log types.Log) (*EtrogpolygonzkevmForceBatch, error) { + event := new(EtrogpolygonzkevmForceBatch) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "ForceBatch", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmInitialSequenceBatchesIterator is returned from FilterInitialSequenceBatches and is used to iterate over the raw logs and unpacked data for InitialSequenceBatches events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmInitialSequenceBatchesIterator struct { + Event *EtrogpolygonzkevmInitialSequenceBatches // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmInitialSequenceBatchesIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmInitialSequenceBatches) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmInitialSequenceBatches) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmInitialSequenceBatchesIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmInitialSequenceBatchesIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmInitialSequenceBatches represents a InitialSequenceBatches event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmInitialSequenceBatches struct { + Transactions []byte + LastGlobalExitRoot [32]byte + Sequencer common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialSequenceBatches is a free log retrieval operation binding the contract event 0x060116213bcbf54ca19fd649dc84b59ab2bbd200ab199770e4d923e222a28e7f. +// +// Solidity: event InitialSequenceBatches(bytes transactions, bytes32 lastGlobalExitRoot, address sequencer) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterInitialSequenceBatches(opts *bind.FilterOpts) (*EtrogpolygonzkevmInitialSequenceBatchesIterator, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "InitialSequenceBatches") + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmInitialSequenceBatchesIterator{contract: _Etrogpolygonzkevm.contract, event: "InitialSequenceBatches", logs: logs, sub: sub}, nil +} + +// WatchInitialSequenceBatches is a free log subscription operation binding the contract event 0x060116213bcbf54ca19fd649dc84b59ab2bbd200ab199770e4d923e222a28e7f. +// +// Solidity: event InitialSequenceBatches(bytes transactions, bytes32 lastGlobalExitRoot, address sequencer) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchInitialSequenceBatches(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmInitialSequenceBatches) (event.Subscription, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "InitialSequenceBatches") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmInitialSequenceBatches) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "InitialSequenceBatches", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialSequenceBatches is a log parse operation binding the contract event 0x060116213bcbf54ca19fd649dc84b59ab2bbd200ab199770e4d923e222a28e7f. +// +// Solidity: event InitialSequenceBatches(bytes transactions, bytes32 lastGlobalExitRoot, address sequencer) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseInitialSequenceBatches(log types.Log) (*EtrogpolygonzkevmInitialSequenceBatches, error) { + event := new(EtrogpolygonzkevmInitialSequenceBatches) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "InitialSequenceBatches", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmInitializedIterator is returned from FilterInitialized and is used to iterate over the raw logs and unpacked data for Initialized events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmInitializedIterator struct { + Event *EtrogpolygonzkevmInitialized // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmInitializedIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmInitialized) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmInitializedIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmInitializedIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmInitialized represents a Initialized event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmInitialized struct { + Version uint8 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterInitialized is a free log retrieval operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterInitialized(opts *bind.FilterOpts) (*EtrogpolygonzkevmInitializedIterator, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmInitializedIterator{contract: _Etrogpolygonzkevm.contract, event: "Initialized", logs: logs, sub: sub}, nil +} + +// WatchInitialized is a free log subscription operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchInitialized(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmInitialized) (event.Subscription, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "Initialized") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmInitialized) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "Initialized", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseInitialized is a log parse operation binding the contract event 0x7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb3847402498. +// +// Solidity: event Initialized(uint8 version) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseInitialized(log types.Log) (*EtrogpolygonzkevmInitialized, error) { + event := new(EtrogpolygonzkevmInitialized) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "Initialized", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmSequenceBatchesIterator is returned from FilterSequenceBatches and is used to iterate over the raw logs and unpacked data for SequenceBatches events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSequenceBatchesIterator struct { + Event *EtrogpolygonzkevmSequenceBatches // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmSequenceBatchesIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSequenceBatches) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSequenceBatches) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmSequenceBatchesIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmSequenceBatchesIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmSequenceBatches represents a SequenceBatches event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSequenceBatches struct { + NumBatch uint64 + L1InfoRoot [32]byte + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSequenceBatches is a free log retrieval operation binding the contract event 0x3e54d0825ed78523037d00a81759237eb436ce774bd546993ee67a1b67b6e766. +// +// Solidity: event SequenceBatches(uint64 indexed numBatch, bytes32 l1InfoRoot) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterSequenceBatches(opts *bind.FilterOpts, numBatch []uint64) (*EtrogpolygonzkevmSequenceBatchesIterator, error) { + + var numBatchRule []interface{} + for _, numBatchItem := range numBatch { + numBatchRule = append(numBatchRule, numBatchItem) + } + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "SequenceBatches", numBatchRule) + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmSequenceBatchesIterator{contract: _Etrogpolygonzkevm.contract, event: "SequenceBatches", logs: logs, sub: sub}, nil +} + +// WatchSequenceBatches is a free log subscription operation binding the contract event 0x3e54d0825ed78523037d00a81759237eb436ce774bd546993ee67a1b67b6e766. +// +// Solidity: event SequenceBatches(uint64 indexed numBatch, bytes32 l1InfoRoot) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchSequenceBatches(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmSequenceBatches, numBatch []uint64) (event.Subscription, error) { + + var numBatchRule []interface{} + for _, numBatchItem := range numBatch { + numBatchRule = append(numBatchRule, numBatchItem) + } + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "SequenceBatches", numBatchRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmSequenceBatches) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SequenceBatches", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSequenceBatches is a log parse operation binding the contract event 0x3e54d0825ed78523037d00a81759237eb436ce774bd546993ee67a1b67b6e766. +// +// Solidity: event SequenceBatches(uint64 indexed numBatch, bytes32 l1InfoRoot) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseSequenceBatches(log types.Log) (*EtrogpolygonzkevmSequenceBatches, error) { + event := new(EtrogpolygonzkevmSequenceBatches) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SequenceBatches", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmSequenceForceBatchesIterator is returned from FilterSequenceForceBatches and is used to iterate over the raw logs and unpacked data for SequenceForceBatches events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSequenceForceBatchesIterator struct { + Event *EtrogpolygonzkevmSequenceForceBatches // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmSequenceForceBatchesIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSequenceForceBatches) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSequenceForceBatches) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmSequenceForceBatchesIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmSequenceForceBatchesIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmSequenceForceBatches represents a SequenceForceBatches event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSequenceForceBatches struct { + NumBatch uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSequenceForceBatches is a free log retrieval operation binding the contract event 0x648a61dd2438f072f5a1960939abd30f37aea80d2e94c9792ad142d3e0a490a4. +// +// Solidity: event SequenceForceBatches(uint64 indexed numBatch) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterSequenceForceBatches(opts *bind.FilterOpts, numBatch []uint64) (*EtrogpolygonzkevmSequenceForceBatchesIterator, error) { + + var numBatchRule []interface{} + for _, numBatchItem := range numBatch { + numBatchRule = append(numBatchRule, numBatchItem) + } + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "SequenceForceBatches", numBatchRule) + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmSequenceForceBatchesIterator{contract: _Etrogpolygonzkevm.contract, event: "SequenceForceBatches", logs: logs, sub: sub}, nil +} + +// WatchSequenceForceBatches is a free log subscription operation binding the contract event 0x648a61dd2438f072f5a1960939abd30f37aea80d2e94c9792ad142d3e0a490a4. +// +// Solidity: event SequenceForceBatches(uint64 indexed numBatch) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchSequenceForceBatches(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmSequenceForceBatches, numBatch []uint64) (event.Subscription, error) { + + var numBatchRule []interface{} + for _, numBatchItem := range numBatch { + numBatchRule = append(numBatchRule, numBatchItem) + } + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "SequenceForceBatches", numBatchRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmSequenceForceBatches) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SequenceForceBatches", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSequenceForceBatches is a log parse operation binding the contract event 0x648a61dd2438f072f5a1960939abd30f37aea80d2e94c9792ad142d3e0a490a4. +// +// Solidity: event SequenceForceBatches(uint64 indexed numBatch) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseSequenceForceBatches(log types.Log) (*EtrogpolygonzkevmSequenceForceBatches, error) { + event := new(EtrogpolygonzkevmSequenceForceBatches) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SequenceForceBatches", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmSetForceBatchAddressIterator is returned from FilterSetForceBatchAddress and is used to iterate over the raw logs and unpacked data for SetForceBatchAddress events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSetForceBatchAddressIterator struct { + Event *EtrogpolygonzkevmSetForceBatchAddress // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmSetForceBatchAddressIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSetForceBatchAddress) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSetForceBatchAddress) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmSetForceBatchAddressIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmSetForceBatchAddressIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmSetForceBatchAddress represents a SetForceBatchAddress event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSetForceBatchAddress struct { + NewForceBatchAddress common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSetForceBatchAddress is a free log retrieval operation binding the contract event 0x5fbd7dd171301c4a1611a84aac4ba86d119478560557755f7927595b082634fb. +// +// Solidity: event SetForceBatchAddress(address newForceBatchAddress) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterSetForceBatchAddress(opts *bind.FilterOpts) (*EtrogpolygonzkevmSetForceBatchAddressIterator, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "SetForceBatchAddress") + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmSetForceBatchAddressIterator{contract: _Etrogpolygonzkevm.contract, event: "SetForceBatchAddress", logs: logs, sub: sub}, nil +} + +// WatchSetForceBatchAddress is a free log subscription operation binding the contract event 0x5fbd7dd171301c4a1611a84aac4ba86d119478560557755f7927595b082634fb. +// +// Solidity: event SetForceBatchAddress(address newForceBatchAddress) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchSetForceBatchAddress(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmSetForceBatchAddress) (event.Subscription, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "SetForceBatchAddress") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmSetForceBatchAddress) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SetForceBatchAddress", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSetForceBatchAddress is a log parse operation binding the contract event 0x5fbd7dd171301c4a1611a84aac4ba86d119478560557755f7927595b082634fb. +// +// Solidity: event SetForceBatchAddress(address newForceBatchAddress) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseSetForceBatchAddress(log types.Log) (*EtrogpolygonzkevmSetForceBatchAddress, error) { + event := new(EtrogpolygonzkevmSetForceBatchAddress) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SetForceBatchAddress", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmSetForceBatchTimeoutIterator is returned from FilterSetForceBatchTimeout and is used to iterate over the raw logs and unpacked data for SetForceBatchTimeout events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSetForceBatchTimeoutIterator struct { + Event *EtrogpolygonzkevmSetForceBatchTimeout // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmSetForceBatchTimeoutIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSetForceBatchTimeout) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSetForceBatchTimeout) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmSetForceBatchTimeoutIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmSetForceBatchTimeoutIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmSetForceBatchTimeout represents a SetForceBatchTimeout event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSetForceBatchTimeout struct { + NewforceBatchTimeout uint64 + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSetForceBatchTimeout is a free log retrieval operation binding the contract event 0xa7eb6cb8a613eb4e8bddc1ac3d61ec6cf10898760f0b187bcca794c6ca6fa40b. +// +// Solidity: event SetForceBatchTimeout(uint64 newforceBatchTimeout) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterSetForceBatchTimeout(opts *bind.FilterOpts) (*EtrogpolygonzkevmSetForceBatchTimeoutIterator, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "SetForceBatchTimeout") + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmSetForceBatchTimeoutIterator{contract: _Etrogpolygonzkevm.contract, event: "SetForceBatchTimeout", logs: logs, sub: sub}, nil +} + +// WatchSetForceBatchTimeout is a free log subscription operation binding the contract event 0xa7eb6cb8a613eb4e8bddc1ac3d61ec6cf10898760f0b187bcca794c6ca6fa40b. +// +// Solidity: event SetForceBatchTimeout(uint64 newforceBatchTimeout) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchSetForceBatchTimeout(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmSetForceBatchTimeout) (event.Subscription, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "SetForceBatchTimeout") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmSetForceBatchTimeout) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SetForceBatchTimeout", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSetForceBatchTimeout is a log parse operation binding the contract event 0xa7eb6cb8a613eb4e8bddc1ac3d61ec6cf10898760f0b187bcca794c6ca6fa40b. +// +// Solidity: event SetForceBatchTimeout(uint64 newforceBatchTimeout) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseSetForceBatchTimeout(log types.Log) (*EtrogpolygonzkevmSetForceBatchTimeout, error) { + event := new(EtrogpolygonzkevmSetForceBatchTimeout) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SetForceBatchTimeout", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmSetTrustedSequencerIterator is returned from FilterSetTrustedSequencer and is used to iterate over the raw logs and unpacked data for SetTrustedSequencer events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSetTrustedSequencerIterator struct { + Event *EtrogpolygonzkevmSetTrustedSequencer // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmSetTrustedSequencerIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSetTrustedSequencer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSetTrustedSequencer) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmSetTrustedSequencerIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmSetTrustedSequencerIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmSetTrustedSequencer represents a SetTrustedSequencer event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSetTrustedSequencer struct { + NewTrustedSequencer common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSetTrustedSequencer is a free log retrieval operation binding the contract event 0xf54144f9611984021529f814a1cb6a41e22c58351510a0d9f7e822618abb9cc0. +// +// Solidity: event SetTrustedSequencer(address newTrustedSequencer) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterSetTrustedSequencer(opts *bind.FilterOpts) (*EtrogpolygonzkevmSetTrustedSequencerIterator, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "SetTrustedSequencer") + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmSetTrustedSequencerIterator{contract: _Etrogpolygonzkevm.contract, event: "SetTrustedSequencer", logs: logs, sub: sub}, nil +} + +// WatchSetTrustedSequencer is a free log subscription operation binding the contract event 0xf54144f9611984021529f814a1cb6a41e22c58351510a0d9f7e822618abb9cc0. +// +// Solidity: event SetTrustedSequencer(address newTrustedSequencer) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchSetTrustedSequencer(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmSetTrustedSequencer) (event.Subscription, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "SetTrustedSequencer") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmSetTrustedSequencer) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SetTrustedSequencer", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSetTrustedSequencer is a log parse operation binding the contract event 0xf54144f9611984021529f814a1cb6a41e22c58351510a0d9f7e822618abb9cc0. +// +// Solidity: event SetTrustedSequencer(address newTrustedSequencer) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseSetTrustedSequencer(log types.Log) (*EtrogpolygonzkevmSetTrustedSequencer, error) { + event := new(EtrogpolygonzkevmSetTrustedSequencer) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SetTrustedSequencer", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmSetTrustedSequencerURLIterator is returned from FilterSetTrustedSequencerURL and is used to iterate over the raw logs and unpacked data for SetTrustedSequencerURL events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSetTrustedSequencerURLIterator struct { + Event *EtrogpolygonzkevmSetTrustedSequencerURL // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmSetTrustedSequencerURLIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSetTrustedSequencerURL) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmSetTrustedSequencerURL) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmSetTrustedSequencerURLIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmSetTrustedSequencerURLIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmSetTrustedSequencerURL represents a SetTrustedSequencerURL event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmSetTrustedSequencerURL struct { + NewTrustedSequencerURL string + Raw types.Log // Blockchain specific contextual infos +} + +// FilterSetTrustedSequencerURL is a free log retrieval operation binding the contract event 0x6b8f723a4c7a5335cafae8a598a0aa0301be1387c037dccc085b62add6448b20. +// +// Solidity: event SetTrustedSequencerURL(string newTrustedSequencerURL) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterSetTrustedSequencerURL(opts *bind.FilterOpts) (*EtrogpolygonzkevmSetTrustedSequencerURLIterator, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "SetTrustedSequencerURL") + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmSetTrustedSequencerURLIterator{contract: _Etrogpolygonzkevm.contract, event: "SetTrustedSequencerURL", logs: logs, sub: sub}, nil +} + +// WatchSetTrustedSequencerURL is a free log subscription operation binding the contract event 0x6b8f723a4c7a5335cafae8a598a0aa0301be1387c037dccc085b62add6448b20. +// +// Solidity: event SetTrustedSequencerURL(string newTrustedSequencerURL) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchSetTrustedSequencerURL(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmSetTrustedSequencerURL) (event.Subscription, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "SetTrustedSequencerURL") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmSetTrustedSequencerURL) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SetTrustedSequencerURL", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseSetTrustedSequencerURL is a log parse operation binding the contract event 0x6b8f723a4c7a5335cafae8a598a0aa0301be1387c037dccc085b62add6448b20. +// +// Solidity: event SetTrustedSequencerURL(string newTrustedSequencerURL) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseSetTrustedSequencerURL(log types.Log) (*EtrogpolygonzkevmSetTrustedSequencerURL, error) { + event := new(EtrogpolygonzkevmSetTrustedSequencerURL) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "SetTrustedSequencerURL", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmTransferAdminRoleIterator is returned from FilterTransferAdminRole and is used to iterate over the raw logs and unpacked data for TransferAdminRole events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmTransferAdminRoleIterator struct { + Event *EtrogpolygonzkevmTransferAdminRole // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmTransferAdminRoleIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmTransferAdminRole) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmTransferAdminRole) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmTransferAdminRoleIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmTransferAdminRoleIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmTransferAdminRole represents a TransferAdminRole event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmTransferAdminRole struct { + NewPendingAdmin common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterTransferAdminRole is a free log retrieval operation binding the contract event 0xa5b56b7906fd0a20e3f35120dd8343db1e12e037a6c90111c7e42885e82a1ce6. +// +// Solidity: event TransferAdminRole(address newPendingAdmin) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterTransferAdminRole(opts *bind.FilterOpts) (*EtrogpolygonzkevmTransferAdminRoleIterator, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "TransferAdminRole") + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmTransferAdminRoleIterator{contract: _Etrogpolygonzkevm.contract, event: "TransferAdminRole", logs: logs, sub: sub}, nil +} + +// WatchTransferAdminRole is a free log subscription operation binding the contract event 0xa5b56b7906fd0a20e3f35120dd8343db1e12e037a6c90111c7e42885e82a1ce6. +// +// Solidity: event TransferAdminRole(address newPendingAdmin) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchTransferAdminRole(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmTransferAdminRole) (event.Subscription, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "TransferAdminRole") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmTransferAdminRole) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "TransferAdminRole", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseTransferAdminRole is a log parse operation binding the contract event 0xa5b56b7906fd0a20e3f35120dd8343db1e12e037a6c90111c7e42885e82a1ce6. +// +// Solidity: event TransferAdminRole(address newPendingAdmin) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseTransferAdminRole(log types.Log) (*EtrogpolygonzkevmTransferAdminRole, error) { + event := new(EtrogpolygonzkevmTransferAdminRole) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "TransferAdminRole", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmUpdateEtrogSequenceIterator is returned from FilterUpdateEtrogSequence and is used to iterate over the raw logs and unpacked data for UpdateEtrogSequence events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmUpdateEtrogSequenceIterator struct { + Event *EtrogpolygonzkevmUpdateEtrogSequence // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmUpdateEtrogSequenceIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmUpdateEtrogSequence) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmUpdateEtrogSequence) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmUpdateEtrogSequenceIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmUpdateEtrogSequenceIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmUpdateEtrogSequence represents a UpdateEtrogSequence event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmUpdateEtrogSequence struct { + NumBatch uint64 + Transactions []byte + LastGlobalExitRoot [32]byte + Sequencer common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterUpdateEtrogSequence is a free log retrieval operation binding the contract event 0xd2c80353fc15ef62c6affc7cd6b7ab5b42c43290c50be3372e55ae552cecd19c. +// +// Solidity: event UpdateEtrogSequence(uint64 numBatch, bytes transactions, bytes32 lastGlobalExitRoot, address sequencer) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterUpdateEtrogSequence(opts *bind.FilterOpts) (*EtrogpolygonzkevmUpdateEtrogSequenceIterator, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "UpdateEtrogSequence") + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmUpdateEtrogSequenceIterator{contract: _Etrogpolygonzkevm.contract, event: "UpdateEtrogSequence", logs: logs, sub: sub}, nil +} + +// WatchUpdateEtrogSequence is a free log subscription operation binding the contract event 0xd2c80353fc15ef62c6affc7cd6b7ab5b42c43290c50be3372e55ae552cecd19c. +// +// Solidity: event UpdateEtrogSequence(uint64 numBatch, bytes transactions, bytes32 lastGlobalExitRoot, address sequencer) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchUpdateEtrogSequence(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmUpdateEtrogSequence) (event.Subscription, error) { + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "UpdateEtrogSequence") + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmUpdateEtrogSequence) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "UpdateEtrogSequence", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseUpdateEtrogSequence is a log parse operation binding the contract event 0xd2c80353fc15ef62c6affc7cd6b7ab5b42c43290c50be3372e55ae552cecd19c. +// +// Solidity: event UpdateEtrogSequence(uint64 numBatch, bytes transactions, bytes32 lastGlobalExitRoot, address sequencer) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseUpdateEtrogSequence(log types.Log) (*EtrogpolygonzkevmUpdateEtrogSequence, error) { + event := new(EtrogpolygonzkevmUpdateEtrogSequence) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "UpdateEtrogSequence", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} + +// EtrogpolygonzkevmVerifyBatchesIterator is returned from FilterVerifyBatches and is used to iterate over the raw logs and unpacked data for VerifyBatches events raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmVerifyBatchesIterator struct { + Event *EtrogpolygonzkevmVerifyBatches // Event containing the contract specifics and raw log + + contract *bind.BoundContract // Generic contract to use for unpacking event data + event string // Event name to use for unpacking event data + + logs chan types.Log // Log channel receiving the found contract events + sub ethereum.Subscription // Subscription for errors, completion and termination + done bool // Whether the subscription completed delivering logs + fail error // Occurred error to stop iteration +} + +// Next advances the iterator to the subsequent event, returning whether there +// are any more events found. In case of a retrieval or parsing error, false is +// returned and Error() can be queried for the exact failure. +func (it *EtrogpolygonzkevmVerifyBatchesIterator) Next() bool { + // If the iterator failed, stop iterating + if it.fail != nil { + return false + } + // If the iterator completed, deliver directly whatever's available + if it.done { + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmVerifyBatches) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + default: + return false + } + } + // Iterator still in progress, wait for either a data or an error event + select { + case log := <-it.logs: + it.Event = new(EtrogpolygonzkevmVerifyBatches) + if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { + it.fail = err + return false + } + it.Event.Raw = log + return true + + case err := <-it.sub.Err(): + it.done = true + it.fail = err + return it.Next() + } +} + +// Error returns any retrieval or parsing error occurred during filtering. +func (it *EtrogpolygonzkevmVerifyBatchesIterator) Error() error { + return it.fail +} + +// Close terminates the iteration process, releasing any pending underlying +// resources. +func (it *EtrogpolygonzkevmVerifyBatchesIterator) Close() error { + it.sub.Unsubscribe() + return nil +} + +// EtrogpolygonzkevmVerifyBatches represents a VerifyBatches event raised by the Etrogpolygonzkevm contract. +type EtrogpolygonzkevmVerifyBatches struct { + NumBatch uint64 + StateRoot [32]byte + Aggregator common.Address + Raw types.Log // Blockchain specific contextual infos +} + +// FilterVerifyBatches is a free log retrieval operation binding the contract event 0x9c72852172521097ba7e1482e6b44b351323df0155f97f4ea18fcec28e1f5966. +// +// Solidity: event VerifyBatches(uint64 indexed numBatch, bytes32 stateRoot, address indexed aggregator) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) FilterVerifyBatches(opts *bind.FilterOpts, numBatch []uint64, aggregator []common.Address) (*EtrogpolygonzkevmVerifyBatchesIterator, error) { + + var numBatchRule []interface{} + for _, numBatchItem := range numBatch { + numBatchRule = append(numBatchRule, numBatchItem) + } + + var aggregatorRule []interface{} + for _, aggregatorItem := range aggregator { + aggregatorRule = append(aggregatorRule, aggregatorItem) + } + + logs, sub, err := _Etrogpolygonzkevm.contract.FilterLogs(opts, "VerifyBatches", numBatchRule, aggregatorRule) + if err != nil { + return nil, err + } + return &EtrogpolygonzkevmVerifyBatchesIterator{contract: _Etrogpolygonzkevm.contract, event: "VerifyBatches", logs: logs, sub: sub}, nil +} + +// WatchVerifyBatches is a free log subscription operation binding the contract event 0x9c72852172521097ba7e1482e6b44b351323df0155f97f4ea18fcec28e1f5966. +// +// Solidity: event VerifyBatches(uint64 indexed numBatch, bytes32 stateRoot, address indexed aggregator) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) WatchVerifyBatches(opts *bind.WatchOpts, sink chan<- *EtrogpolygonzkevmVerifyBatches, numBatch []uint64, aggregator []common.Address) (event.Subscription, error) { + + var numBatchRule []interface{} + for _, numBatchItem := range numBatch { + numBatchRule = append(numBatchRule, numBatchItem) + } + + var aggregatorRule []interface{} + for _, aggregatorItem := range aggregator { + aggregatorRule = append(aggregatorRule, aggregatorItem) + } + + logs, sub, err := _Etrogpolygonzkevm.contract.WatchLogs(opts, "VerifyBatches", numBatchRule, aggregatorRule) + if err != nil { + return nil, err + } + return event.NewSubscription(func(quit <-chan struct{}) error { + defer sub.Unsubscribe() + for { + select { + case log := <-logs: + // New log arrived, parse the event and forward to the user + event := new(EtrogpolygonzkevmVerifyBatches) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "VerifyBatches", log); err != nil { + return err + } + event.Raw = log + + select { + case sink <- event: + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + case err := <-sub.Err(): + return err + case <-quit: + return nil + } + } + }), nil +} + +// ParseVerifyBatches is a log parse operation binding the contract event 0x9c72852172521097ba7e1482e6b44b351323df0155f97f4ea18fcec28e1f5966. +// +// Solidity: event VerifyBatches(uint64 indexed numBatch, bytes32 stateRoot, address indexed aggregator) +func (_Etrogpolygonzkevm *EtrogpolygonzkevmFilterer) ParseVerifyBatches(log types.Log) (*EtrogpolygonzkevmVerifyBatches, error) { + event := new(EtrogpolygonzkevmVerifyBatches) + if err := _Etrogpolygonzkevm.contract.UnpackLog(event, "VerifyBatches", log); err != nil { + return nil, err + } + event.Raw = log + return event, nil +} diff --git a/etherman/smartcontracts/polygonzkevm/polygonzkevm.go b/etherman/smartcontracts/polygonzkevm/polygonzkevm.go index 7076083f37..100fd7a5d6 100644 --- a/etherman/smartcontracts/polygonzkevm/polygonzkevm.go +++ b/etherman/smartcontracts/polygonzkevm/polygonzkevm.go @@ -39,8 +39,8 @@ type PolygonRollupBaseEtrogBatchData struct { // PolygonzkevmMetaData contains all meta data concerning the Polygonzkevm contract. var PolygonzkevmMetaData = &bind.MetaData{ - ABI: "[{\"inputs\":[{\"internalType\":\"contractIPolygonZkEVMGlobalExitRootV2\",\"name\":\"_globalExitRootManager\",\"type\":\"address\"},{\"internalType\":\"contractIERC20Upgradeable\",\"name\":\"_pol\",\"type\":\"address\"},{\"internalType\":\"contractIPolygonZkEVMBridgeV2\",\"name\":\"_bridgeAddress\",\"type\":\"address\"},{\"internalType\":\"contractPolygonRollupManager\",\"name\":\"_rollupManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BatchAlreadyVerified\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BatchNotSequencedOrNotSequenceEnd\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExceedMaxVerifyBatches\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FinalNumBatchBelowLastVerifiedBatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FinalNumBatchDoesNotMatchPendingState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FinalPendingStateNumInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchTimeoutNotExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesDecentralized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesNotAllowedOnEmergencyState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesOverflow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForcedDataDoesNotMatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasTokenNetworkMustBeZeroOnEther\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GlobalExitRootNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HaltTimeoutNotExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HaltTimeoutNotExpiredAfterEmergencyState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HugeTokenMetadataNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InitNumBatchAboveLastVerifiedBatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InitNumBatchDoesNotMatchPendingState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitializeTransaction\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRangeBatchTimeTarget\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRangeForceBatchTimeout\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRangeMultiplierBatchFee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewAccInputHashDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewPendingStateTimeoutMustBeLower\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewStateRootNotInsidePrime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewTrustedAggregatorTimeoutMustBeLower\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughMaticAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughPOLAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OldAccInputHashDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OldStateRootDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRollupManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyTrustedAggregator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyTrustedSequencer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateNotConsolidable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateTimeoutExceedHaltAggregationTimeout\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SequenceZeroBatches\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SequencedTimestampBelowForcedTimestamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SequencedTimestampInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StoredRootMustBeDifferentThanNewRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransactionsLengthAboveMax\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TrustedAggregatorTimeoutExceedHaltAggregationTimeout\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TrustedAggregatorTimeoutNotExpired\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AcceptAdminRole\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"forceBatchNum\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"lastGlobalExitRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"}],\"name\":\"ForceBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"lastGlobalExitRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"}],\"name\":\"InitialSequenceBatches\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"l1InfoRoot\",\"type\":\"bytes32\"}],\"name\":\"SequenceBatches\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"}],\"name\":\"SequenceForceBatches\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newForceBatchAddress\",\"type\":\"address\"}],\"name\":\"SetForceBatchAddress\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newforceBatchTimeout\",\"type\":\"uint64\"}],\"name\":\"SetForceBatchTimeout\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTrustedSequencer\",\"type\":\"address\"}],\"name\":\"SetTrustedSequencer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"newTrustedSequencerURL\",\"type\":\"string\"}],\"name\":\"SetTrustedSequencerURL\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPendingAdmin\",\"type\":\"address\"}],\"name\":\"TransferAdminRole\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"lastGlobalExitRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"}],\"name\":\"UpdateEtrogSequence\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"VerifyBatches\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GLOBAL_EXIT_ROOT_MANAGER_L2\",\"outputs\":[{\"internalType\":\"contractIBasePolygonZkEVMGlobalExitRoot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_LIST_LEN_LEN\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_PARAMS\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS_EMPTY_METADATA\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_CONSTANT_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_CONSTANT_BYTES_EMPTY_METADATA\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_DATA_LEN_EMPTY_METADATA\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_EFFECTIVE_PERCENTAGE\",\"outputs\":[{\"internalType\":\"bytes1\",\"name\":\"\",\"type\":\"bytes1\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SET_UP_ETROG_TX\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SIGNATURE_INITIALIZE_TX_R\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SIGNATURE_INITIALIZE_TX_S\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SIGNATURE_INITIALIZE_TX_V\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridgeAddress\",\"outputs\":[{\"internalType\":\"contractIPolygonZkEVMBridgeV2\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"calculatePolPerForceBatch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"polAmount\",\"type\":\"uint256\"}],\"name\":\"forceBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"forceBatchAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"forceBatchTimeout\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"forcedBatches\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gasTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gasTokenNetwork\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"networkID\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_gasTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_gasTokenNetwork\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_gasTokenMetadata\",\"type\":\"bytes\"}],\"name\":\"generateInitializeTransaction\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalExitRootManager\",\"outputs\":[{\"internalType\":\"contractIPolygonZkEVMGlobalExitRootV2\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkID\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_gasTokenAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"sequencerURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_networkName\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"_trustedSequencer\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"_trustedSequencerURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_networkName\",\"type\":\"string\"},{\"internalType\":\"bytes32\",\"name\":\"_lastAccInputHash\",\"type\":\"bytes32\"}],\"name\":\"initializeUpgrade\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastAccInputHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastForceBatch\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastForceBatchSequenced\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"networkName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBatch\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"newStateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"onVerifyBatches\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pol\",\"outputs\":[{\"internalType\":\"contractIERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rollupManager\",\"outputs\":[{\"internalType\":\"contractPolygonRollupManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"forcedGlobalExitRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"forcedTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"forcedBlockHashL1\",\"type\":\"bytes32\"}],\"internalType\":\"structPolygonRollupBaseEtrog.BatchData[]\",\"name\":\"batches\",\"type\":\"tuple[]\"},{\"internalType\":\"address\",\"name\":\"l2Coinbase\",\"type\":\"address\"}],\"name\":\"sequenceBatches\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"forcedGlobalExitRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"forcedTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"forcedBlockHashL1\",\"type\":\"bytes32\"}],\"internalType\":\"structPolygonRollupBaseEtrog.BatchData[]\",\"name\":\"batches\",\"type\":\"tuple[]\"}],\"name\":\"sequenceForceBatches\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newForceBatchAddress\",\"type\":\"address\"}],\"name\":\"setForceBatchAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"newforceBatchTimeout\",\"type\":\"uint64\"}],\"name\":\"setForceBatchTimeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newTrustedSequencer\",\"type\":\"address\"}],\"name\":\"setTrustedSequencer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"newTrustedSequencerURL\",\"type\":\"string\"}],\"name\":\"setTrustedSequencerURL\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPendingAdmin\",\"type\":\"address\"}],\"name\":\"transferAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trustedSequencer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trustedSequencerURL\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", - Bin: "0x6101006040523480156200001257600080fd5b5060405162004a6138038062004a61833981016040819052620000359162000071565b6001600160a01b0393841660a052918316608052821660c0521660e052620000d9565b6001600160a01b03811681146200006e57600080fd5b50565b600080600080608085870312156200008857600080fd5b8451620000958162000058565b6020860151909450620000a88162000058565b6040860151909350620000bb8162000058565b6060860151909250620000ce8162000058565b939692955090935050565b60805160a05160c05160e05161488a620001d7600039600081816105060152818161098f01528181610afc01528181610c7d01528181610fd4015281816112de015281816118c101528181611d65015281816121bc015281816122b20152818161295701528181612a1f01528181613342015281816133bb015281816133dd01526134f5015260008181610673015281816114d2015281816115ac015281816124830152818161258b0152612e7c01526000818161073701528181610e450152818161173501528181612b6a0152612efe0152600081816107690152818161083b0152818161220501528181612b3e015261348b015261488a6000f3fe608060405234801561001057600080fd5b50600436106102f35760003560e01c80637a5460c511610191578063c7fffd4b116100e3578063e46761c411610097578063ecef3f9911610071578063ecef3f99146107b2578063f35dda47146107c5578063f851a440146107cd57600080fd5b8063e46761c414610764578063e7a7ed021461078b578063eaeb077b1461079f57600080fd5b8063cfa8ed47116100c8578063cfa8ed4714610712578063d02103ca14610732578063d7bc90ff1461075957600080fd5b8063c7fffd4b146106f7578063c89e42df146106ff57600080fd5b8063a3c573eb11610145578063af7f3e021161011f578063af7f3e02146106bb578063b0afe154146106c3578063c754c7ed146106cf57600080fd5b8063a3c573eb1461066e578063a652f26c14610695578063ada8f919146106a857600080fd5b806391cafe321161017657806391cafe321461062d5780639e001877146106405780639f26f8401461065b57600080fd5b80637a5460c5146105e95780638c3d73011461062557600080fd5b8063456052671161024a5780635d6717a5116101fe5780636e05d2cd116101d85780636e05d2cd146105ba5780636ff512cc146105c357806371257022146105d657600080fd5b80635d6717a51461057f578063676870d2146105925780636b8616ce1461059a57600080fd5b80634e4877061161022f5780634e4877061461052857806352bdeb6d1461053b578063542028d51461057757600080fd5b806345605267146104c857806349b7b8021461050157600080fd5b806326782247116102ac5780633c351e10116102865780633c351e10146104135780633cbc795b1461043357806340b5de6c1461047057600080fd5b806326782247146103995780632c111c06146103de57806332c2d153146103fe57600080fd5b806305835f37116102dd57806305835f371461032e578063107bf28c1461037757806311e892d41461037f57600080fd5b8062d0295d146102f85780630350896314610313575b600080fd5b6103006107f3565b6040519081526020015b60405180910390f35b61031b602081565b60405161ffff909116815260200161030a565b61036a6040518060400160405280600881526020017f80808401c9c3809400000000000000000000000000000000000000000000000081525081565b60405161030a91906139f2565b61036a6108ff565b61038760f981565b60405160ff909116815260200161030a565b6001546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030a565b6008546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b61041161040c366004613a47565b61098d565b005b6009546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b60095461045b9074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff909116815260200161030a565b6104977fff0000000000000000000000000000000000000000000000000000000000000081565b6040517fff00000000000000000000000000000000000000000000000000000000000000909116815260200161030a565b6007546104e89068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff909116815260200161030a565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b610411610536366004613a89565b610a5c565b61036a6040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525081565b61036a610c6e565b61041161058d366004613bc0565b610c7b565b61031b601f81565b6103006105a8366004613a89565b60066020526000908152604090205481565b61030060055481565b6104116105d1366004613c51565b611212565b6104116105e4366004613c80565b6112dc565b61036a6040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525081565b610411611afd565b61041161063b366004613c51565b611bd0565b6103b973a40d5f56745a118d0906a34e69aec8c0db1cb8fa81565b610411610669366004613d79565b611ce9565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b61036a6106a3366004613dbb565b612382565b6104116106b6366004613c51565b612767565b61036a612831565b6103006405ca1ab1e081565b6007546104e890700100000000000000000000000000000000900467ffffffffffffffff1681565b61038760e481565b61041161070d366004613e30565b61284d565b6002546103b99073ffffffffffffffffffffffffffffffffffffffff1681565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b610300635ca1ab1e81565b6103b97f000000000000000000000000000000000000000000000000000000000000000081565b6007546104e89067ffffffffffffffff1681565b6104116107ad366004613e65565b6128e0565b6104116107c0366004613edd565b612db1565b610387601b81565b6000546103b99062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610882573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906108a69190613f29565b6007549091506000906108d19067ffffffffffffffff68010000000000000000820481169116613f71565b67ffffffffffffffff169050806000036108ee5760009250505090565b6108f88183613f99565b9250505090565b6004805461090c90613fd4565b80601f016020809104026020016040519081016040528092919081815260200182805461093890613fd4565b80156109855780601f1061095a57610100808354040283529160200191610985565b820191906000526020600020905b81548152906001019060200180831161096857829003601f168201915b505050505081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633146109fc576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168367ffffffffffffffff167f9c72852172521097ba7e1482e6b44b351323df0155f97f4ea18fcec28e1f596684604051610a4f91815260200190565b60405180910390a3505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314610ab3576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62093a8067ffffffffffffffff82161115610afa576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b65573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b899190614027565b610bea5760075467ffffffffffffffff700100000000000000000000000000000000909104811690821610610bea576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000067ffffffffffffffff8416908102919091179091556040519081527fa7eb6cb8a613eb4e8bddc1ac3d61ec6cf10898760f0b187bcca794c6ca6fa40b906020015b60405180910390a150565b6003805461090c90613fd4565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163314610cea576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff1615808015610d0a5750600054600160ff909116105b80610d245750303b158015610d24575060005460ff166001145b610db5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610e1357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b60006040518060a00160405280606281526020016147f3606291399050600081805190602001209050600042905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015610eae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ed29190613f29565b90506000868483858d610ee6600143614049565b60408051602081019790975286019490945260608086019390935260c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000166080850152901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608883015240609c82015260bc01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815290829052805160209091012060058190557f9a908e73000000000000000000000000000000000000000000000000000000008252600160048301526024820181905291506000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af1158015611032573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110569190614062565b90508b600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508a600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555089600390816110e991906140c5565b5060046110f68a826140c5565b508b600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062069780600760106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507fd2c80353fc15ef62c6affc7cd6b7ab5b42c43290c50be3372e55ae552cecd19c8187858e60405161119994939291906141df565b60405180910390a1505050505050801561120a57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b505050505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314611269576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ff54144f9611984021529f814a1cb6a41e22c58351510a0d9f7e822618abb9cc090602001610c63565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16331461134b576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff161580801561136b5750600054600160ff909116105b806113855750303b158015611385575060005460ff166001145b611411576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610dac565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055801561146f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606073ffffffffffffffffffffffffffffffffffffffff8516156116d6576040517fc00f14ab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063c00f14ab90602401600060405180830381865afa158015611519573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016820160405261155f919081019061422f565b6040517f318aee3d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063318aee3d9060240160408051808303816000875af11580156115f6573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061161a91906142a6565b915091508163ffffffff16600014611692576009805463ffffffff841674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff8416171790556116d3565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff89161790555b50505b60095460009061171e90889073ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900463ffffffff1685612382565b9050600081805190602001209050600042905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561179e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117c29190613f29565b90506000808483858f6117d6600143614049565b60408051602081019790975286019490945260608086019390935260c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000166080850152901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608883015240609c82015260bc01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815290829052805160209091012060058190557f9a908e73000000000000000000000000000000000000000000000000000000008252600160048301526024820181905291507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af115801561191f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906119439190614062565b508c600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555088600390816119d591906140c5565b5060046119e289826140c5565b508c600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062069780600760106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f060116213bcbf54ca19fd649dc84b59ab2bbd200ab199770e4d923e222a28e7f85838e604051611a83939291906142e0565b60405180910390a15050505050508015611af457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff163314611b4e576040517fd1ec4b2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff1673ffffffffffffffffffffffffffffffffffffffff9092166201000081029290921790556040519081527f056dc487bbf0795d0bbb1b4f0af523a855503cff740bfb4d5475f7a90c091e8e9060200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314611c27576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085473ffffffffffffffffffffffffffffffffffffffff16611c76576040517fc89374d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f5fbd7dd171301c4a1611a84aac4ba86d119478560557755f7927595b082634fb90602001610c63565b60085473ffffffffffffffffffffffffffffffffffffffff168015801590611d27575073ffffffffffffffffffffffffffffffffffffffff81163314155b15611d5e576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4262093a807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166330c27dde6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dce573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611df29190614062565b611dfc919061431f565b67ffffffffffffffff161115611e3e576040517f3d49ed4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816000819003611e7a576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e8811115611eb6576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60075467ffffffffffffffff80821691611ede91849168010000000000000000900416614340565b1115611f16576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546005546801000000000000000090910467ffffffffffffffff169060005b838110156121b6576000878783818110611f5357611f53614353565b9050602002810190611f659190614382565b611f6e906143c0565b905083611f7a81614449565b825180516020918201208185015160408087015160608801519151959a50929550600094611fe7948794929101938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8916600090815260069093529120549091508114612070576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8616600090815260066020526040812055612095600188614049565b84036121045742600760109054906101000a900467ffffffffffffffff1684604001516120c2919061431f565b67ffffffffffffffff161115612104576040517fc44a082100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018b90529285018790528481019390935260c01b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808401523390911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc0160405160208183030381529060405280519060200120945050505080806121ae90614470565b915050611f37565b5061222c7f0000000000000000000000000000000000000000000000000000000000000000846121e46107f3565b6121ee91906144a8565b73ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001691906135ca565b60058190556007805467ffffffffffffffff841668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161790556040517f9a908e7300000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690639a908e73906122fe908790869060040167ffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af115801561231d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123419190614062565b60405190915067ffffffffffffffff8216907f648a61dd2438f072f5a1960939abd30f37aea80d2e94c9792ad142d3e0a490a490600090a250505050505050565b6060600085858573a40d5f56745a118d0906a34e69aec8c0db1cb8fa6000876040516024016123b6969594939291906144bf565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff811bff70000000000000000000000000000000000000000000000000000000017905283519091506060906000036125075760f9601f835161244b9190614522565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525060e4876040516020016124f1979695949392919061453d565b604051602081830303815290604052905061260b565b815161ffff1015612544576040517f248b8f8200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160f9612553602083614522565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525085886040516020016125f89796959493929190614620565b6040516020818303038152906040529150505b805160208083019190912060408051600080825293810180835292909252601b908201526405ca1ab1e06060820152635ca1ab1e608082015260019060a0016020604051602081039080840390855afa15801561266c573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166126e4576040517fcd16196600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60405160009061272a9084906405ca1ab1e090635ca1ab1e90601b907fff0000000000000000000000000000000000000000000000000000000000000090602001614703565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529450505050505b949350505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146127be576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa5b56b7906fd0a20e3f35120dd8343db1e12e037a6c90111c7e42885e82a1ce690602001610c63565b6040518060a00160405280606281526020016147f36062913981565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146128a4576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60036128b082826140c5565b507f6b8f723a4c7a5335cafae8a598a0aa0301be1387c037dccc085b62add6448b2081604051610c6391906139f2565b60085473ffffffffffffffffffffffffffffffffffffffff16801580159061291e575073ffffffffffffffffffffffffffffffffffffffff81163314155b15612955576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129c0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129e49190614027565b15612a1b576040517f39258d1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663604691696040518163ffffffff1660e01b8152600401602060405180830381865afa158015612a88573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612aac9190613f29565b905082811115612ae8576040517f2354600f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611388841115612b24576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612b6673ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000163330846136a3565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612bd3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bf79190613f29565b6007805491925067ffffffffffffffff909116906000612c1683614449565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550508585604051612c4d92919061475f565b6040519081900390208142612c63600143614049565b60408051602081019590955284019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166060830152406068820152608801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060075467ffffffffffffffff1660009081526006909352912055323303612d5b57600754604080518381523360208201526060818301819052600090820152905167ffffffffffffffff909216917ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc9319181900360800190a261120a565b60075460405167ffffffffffffffff909116907ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc93190612da190849033908b908b9061476f565b60405180910390a2505050505050565b60025473ffffffffffffffffffffffffffffffffffffffff163314612e02576040517f11e7be1500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816000819003612e3e576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e8811115612e7a576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166379e2cf976040518163ffffffff1660e01b8152600401600060405180830381600087803b158015612ee257600080fd5b505af1158015612ef6573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635ca1e1656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612f67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8b9190613f29565b60075460055491925042916801000000000000000090910467ffffffffffffffff16908160005b868110156132b45760008a8a83818110612fce57612fce614353565b9050602002810190612fe09190614382565b612fe9906143c0565b8051805160209091012060408201519192509067ffffffffffffffff16156131ce578561301581614449565b9650506000818360200151846040015185606001516040516020016130789493929190938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8a16600090815260069093529120549091508114613101576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018c90529285018790528481019390935260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166080840152908d901b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc01604051602081830303815290604052805190602001209550600660008867ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600090555061329f565b8151516201d4c0101561320d576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516020810187905290810182905260608082018a905260c089901b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808301528b901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660888201526000609c82015260bc016040516020818303038152906040528051906020012094505b505080806132ac90614470565b915050612fb2565b5060075467ffffffffffffffff90811690841611156132ff576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60058290558567ffffffffffffffff848116908316146133b55760006133258386613f71565b905061333b67ffffffffffffffff821683614049565b91506133747f00000000000000000000000000000000000000000000000000000000000000008267ffffffffffffffff166121e46107f3565b50600780547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8716021790555b6134b3337f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663477fa2706040518163ffffffff1660e01b8152600401602060405180830381865afa158015613446573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061346a9190613f29565b61347491906144a8565b73ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169291906136a3565b6040517f9a908e7300000000000000000000000000000000000000000000000000000000815267ffffffffffffffff88166004820152602481018490526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af1158015613553573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906135779190614062565b90508067ffffffffffffffff167f3e54d0825ed78523037d00a81759237eb436ce774bd546993ee67a1b67b6e766886040516135b591815260200190565b60405180910390a25050505050505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff831660248201526044810182905261369e9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff0000000000000000000000000000000000000000000000000000000090931692909217909152613707565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526137019085907f23b872dd000000000000000000000000000000000000000000000000000000009060840161361c565b50505050565b6000613769826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166138139092919063ffffffff16565b80519091501561369e57808060200190518101906137879190614027565b61369e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610dac565b606061275f8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161384791906147e0565b60006040518083038185875af1925050503d8060008114613884576040519150601f19603f3d011682016040523d82523d6000602084013e613889565b606091505b509150915061389a878383876138a5565b979650505050505050565b6060831561393b5782516000036139345773ffffffffffffffffffffffffffffffffffffffff85163b613934576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610dac565b508161275f565b61275f83838151156139505781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dac91906139f2565b60005b8381101561399f578181015183820152602001613987565b50506000910152565b600081518084526139c0816020860160208601613984565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b602081526000613a0560208301846139a8565b9392505050565b67ffffffffffffffff81168114613a2257600080fd5b50565b73ffffffffffffffffffffffffffffffffffffffff81168114613a2257600080fd5b600080600060608486031215613a5c57600080fd5b8335613a6781613a0c565b9250602084013591506040840135613a7e81613a25565b809150509250925092565b600060208284031215613a9b57600080fd5b8135613a0581613a0c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613b1c57613b1c613aa6565b604052919050565b600067ffffffffffffffff821115613b3e57613b3e613aa6565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112613b7b57600080fd5b8135613b8e613b8982613b24565b613ad5565b818152846020838601011115613ba357600080fd5b816020850160208301376000918101602001919091529392505050565b600080600080600060a08688031215613bd857600080fd5b8535613be381613a25565b94506020860135613bf381613a25565b9350604086013567ffffffffffffffff80821115613c1057600080fd5b613c1c89838a01613b6a565b94506060880135915080821115613c3257600080fd5b50613c3f88828901613b6a565b95989497509295608001359392505050565b600060208284031215613c6357600080fd5b8135613a0581613a25565b63ffffffff81168114613a2257600080fd5b60008060008060008060c08789031215613c9957600080fd5b8635613ca481613a25565b95506020870135613cb481613a25565b94506040870135613cc481613c6e565b93506060870135613cd481613a25565b9250608087013567ffffffffffffffff80821115613cf157600080fd5b613cfd8a838b01613b6a565b935060a0890135915080821115613d1357600080fd5b50613d2089828a01613b6a565b9150509295509295509295565b60008083601f840112613d3f57600080fd5b50813567ffffffffffffffff811115613d5757600080fd5b6020830191508360208260051b8501011115613d7257600080fd5b9250929050565b60008060208385031215613d8c57600080fd5b823567ffffffffffffffff811115613da357600080fd5b613daf85828601613d2d565b90969095509350505050565b60008060008060808587031215613dd157600080fd5b8435613ddc81613c6e565b93506020850135613dec81613a25565b92506040850135613dfc81613c6e565b9150606085013567ffffffffffffffff811115613e1857600080fd5b613e2487828801613b6a565b91505092959194509250565b600060208284031215613e4257600080fd5b813567ffffffffffffffff811115613e5957600080fd5b61275f84828501613b6a565b600080600060408486031215613e7a57600080fd5b833567ffffffffffffffff80821115613e9257600080fd5b818601915086601f830112613ea657600080fd5b813581811115613eb557600080fd5b876020828501011115613ec757600080fd5b6020928301989097509590910135949350505050565b600080600060408486031215613ef257600080fd5b833567ffffffffffffffff811115613f0957600080fd5b613f1586828701613d2d565b9094509250506020840135613a7e81613a25565b600060208284031215613f3b57600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115613f9257613f92613f42565b5092915050565b600082613fcf577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600181811c90821680613fe857607f821691505b602082108103614021577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60006020828403121561403957600080fd5b81518015158114613a0557600080fd5b8181038181111561405c5761405c613f42565b92915050565b60006020828403121561407457600080fd5b8151613a0581613a0c565b601f82111561369e57600081815260208120601f850160051c810160208610156140a65750805b601f850160051c820191505b8181101561120a578281556001016140b2565b815167ffffffffffffffff8111156140df576140df613aa6565b6140f3816140ed8454613fd4565b8461407f565b602080601f83116001811461414657600084156141105750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b17855561120a565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b8281101561419357888601518255948401946001909101908401614174565b50858210156141cf57878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b67ffffffffffffffff8516815260806020820152600061420260808301866139a8565b905083604083015273ffffffffffffffffffffffffffffffffffffffff8316606083015295945050505050565b60006020828403121561424157600080fd5b815167ffffffffffffffff81111561425857600080fd5b8201601f8101841361426957600080fd5b8051614277613b8982613b24565b81815285602083850101111561428c57600080fd5b61429d826020830160208601613984565b95945050505050565b600080604083850312156142b957600080fd5b82516142c481613c6e565b60208401519092506142d581613a25565b809150509250929050565b6060815260006142f360608301866139a8565b905083602083015273ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b67ffffffffffffffff818116838216019080821115613f9257613f92613f42565b8082018082111561405c5761405c613f42565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff818336030181126143b657600080fd5b9190910192915050565b6000608082360312156143d257600080fd5b6040516080810167ffffffffffffffff82821081831117156143f6576143f6613aa6565b81604052843591508082111561440b57600080fd5b5061441836828601613b6a565b82525060208301356020820152604083013561443381613a0c565b6040820152606092830135928101929092525090565b600067ffffffffffffffff80831681810361446657614466613f42565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036144a1576144a1613f42565b5060010190565b808202811582820484141761405c5761405c613f42565b600063ffffffff808916835273ffffffffffffffffffffffffffffffffffffffff8089166020850152818816604085015280871660608501528086166080850152505060c060a083015261451660c08301846139a8565b98975050505050505050565b61ffff818116838216019080821115613f9257613f92613f42565b60007fff00000000000000000000000000000000000000000000000000000000000000808a60f81b1683527fffff0000000000000000000000000000000000000000000000000000000000008960f01b16600184015287516145a6816003860160208c01613984565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b16600382015286516145e9816017840160208b01613984565b808201915050818660f81b1660178201528451915061460f826018830160208801613984565b016018019998505050505050505050565b7fff000000000000000000000000000000000000000000000000000000000000008860f81b16815260007fffff000000000000000000000000000000000000000000000000000000000000808960f01b1660018401528751614689816003860160208c01613984565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b16600382015286516146cc816017840160208b01613984565b808201915050818660f01b166017820152845191506146f2826019830160208801613984565b016019019998505050505050505050565b60008651614715818460208b01613984565b9190910194855250602084019290925260f81b7fff000000000000000000000000000000000000000000000000000000000000009081166040840152166041820152604201919050565b8183823760009101908152919050565b84815273ffffffffffffffffffffffffffffffffffffffff8416602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01601019392505050565b600082516143b681846020870161398456fedf2a8080944d5cf5032b2a844602278b01199ed191a86c93ff8080821092808000000000000000000000000000000000000000000000000000000005ca1ab1e000000000000000000000000000000000000000000000000000000005ca1ab1e01bffa26469706673582212201221389ded8ea187a66f83d3bd052755e28647dbf3bc616c9e91e0a8b7ecf74364736f6c63430008140033", + ABI: "[{\"inputs\":[{\"internalType\":\"contractIPolygonZkEVMGlobalExitRootV2\",\"name\":\"_globalExitRootManager\",\"type\":\"address\"},{\"internalType\":\"contractIERC20Upgradeable\",\"name\":\"_pol\",\"type\":\"address\"},{\"internalType\":\"contractIPolygonZkEVMBridgeV2\",\"name\":\"_bridgeAddress\",\"type\":\"address\"},{\"internalType\":\"contractPolygonRollupManager\",\"name\":\"_rollupManager\",\"type\":\"address\"}],\"stateMutability\":\"nonpayable\",\"type\":\"constructor\"},{\"inputs\":[],\"name\":\"BatchAlreadyVerified\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"BatchNotSequencedOrNotSequenceEnd\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ExceedMaxVerifyBatches\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FinalNumBatchBelowLastVerifiedBatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FinalNumBatchDoesNotMatchPendingState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"FinalPendingStateNumInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchNotAllowed\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchTimeoutNotExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesAlreadyActive\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesDecentralized\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesNotAllowedOnEmergencyState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForceBatchesOverflow\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"ForcedDataDoesNotMatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GasTokenNetworkMustBeZeroOnEther\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"GlobalExitRootNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HaltTimeoutNotExpired\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HaltTimeoutNotExpiredAfterEmergencyState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"HugeTokenMetadataNotSupported\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InitNumBatchAboveLastVerifiedBatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InitNumBatchDoesNotMatchPendingState\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InitSequencedBatchDoesNotMatch\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidInitializeTransaction\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidProof\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRangeBatchTimeTarget\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRangeForceBatchTimeout\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"InvalidRangeMultiplierBatchFee\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"MaxTimestampSequenceInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewAccInputHashDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewPendingStateTimeoutMustBeLower\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewStateRootNotInsidePrime\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NewTrustedAggregatorTimeoutMustBeLower\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughMaticAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"NotEnoughPOLAmount\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OldAccInputHashDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OldStateRootDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyPendingAdmin\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyRollupManager\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyTrustedAggregator\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"OnlyTrustedSequencer\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateDoesNotExist\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateNotConsolidable\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"PendingStateTimeoutExceedHaltAggregationTimeout\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SequenceZeroBatches\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SequencedTimestampBelowForcedTimestamp\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"SequencedTimestampInvalid\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"StoredRootMustBeDifferentThanNewRoot\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TransactionsLengthAboveMax\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TrustedAggregatorTimeoutExceedHaltAggregationTimeout\",\"type\":\"error\"},{\"inputs\":[],\"name\":\"TrustedAggregatorTimeoutNotExpired\",\"type\":\"error\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newAdmin\",\"type\":\"address\"}],\"name\":\"AcceptAdminRole\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"forceBatchNum\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"lastGlobalExitRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"},{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"}],\"name\":\"ForceBatch\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"lastGlobalExitRoot\",\"type\":\"bytes32\"},{\"indexed\":false,\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"}],\"name\":\"InitialSequenceBatches\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint8\",\"name\":\"version\",\"type\":\"uint8\"}],\"name\":\"Initialized\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"l1InfoRoot\",\"type\":\"bytes32\"}],\"name\":\"SequenceBatches\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"}],\"name\":\"SequenceForceBatches\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newForceBatchAddress\",\"type\":\"address\"}],\"name\":\"SetForceBatchAddress\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"uint64\",\"name\":\"newforceBatchTimeout\",\"type\":\"uint64\"}],\"name\":\"SetForceBatchTimeout\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newTrustedSequencer\",\"type\":\"address\"}],\"name\":\"SetTrustedSequencer\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"string\",\"name\":\"newTrustedSequencerURL\",\"type\":\"string\"}],\"name\":\"SetTrustedSequencerURL\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":false,\"internalType\":\"address\",\"name\":\"newPendingAdmin\",\"type\":\"address\"}],\"name\":\"TransferAdminRole\",\"type\":\"event\"},{\"anonymous\":false,\"inputs\":[{\"indexed\":true,\"internalType\":\"uint64\",\"name\":\"numBatch\",\"type\":\"uint64\"},{\"indexed\":false,\"internalType\":\"bytes32\",\"name\":\"stateRoot\",\"type\":\"bytes32\"},{\"indexed\":true,\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"VerifyBatches\",\"type\":\"event\"},{\"inputs\":[],\"name\":\"GLOBAL_EXIT_ROOT_MANAGER_L2\",\"outputs\":[{\"internalType\":\"contractIBasePolygonZkEVMGlobalExitRoot\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_LIST_LEN_LEN\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_PARAMS\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_BRIDGE_PARAMS_AFTER_BRIDGE_ADDRESS_EMPTY_METADATA\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_CONSTANT_BYTES\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_CONSTANT_BYTES_EMPTY_METADATA\",\"outputs\":[{\"internalType\":\"uint16\",\"name\":\"\",\"type\":\"uint16\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_DATA_LEN_EMPTY_METADATA\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"INITIALIZE_TX_EFFECTIVE_PERCENTAGE\",\"outputs\":[{\"internalType\":\"bytes1\",\"name\":\"\",\"type\":\"bytes1\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SIGNATURE_INITIALIZE_TX_R\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SIGNATURE_INITIALIZE_TX_S\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"SIGNATURE_INITIALIZE_TX_V\",\"outputs\":[{\"internalType\":\"uint8\",\"name\":\"\",\"type\":\"uint8\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"TIMESTAMP_RANGE\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"acceptAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"admin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"bridgeAddress\",\"outputs\":[{\"internalType\":\"contractIPolygonZkEVMBridgeV2\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"calculatePolPerForceBatch\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"internalType\":\"uint256\",\"name\":\"polAmount\",\"type\":\"uint256\"}],\"name\":\"forceBatch\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"forceBatchAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"forceBatchTimeout\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"name\":\"forcedBatches\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gasTokenAddress\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"gasTokenNetwork\",\"outputs\":[{\"internalType\":\"uint32\",\"name\":\"\",\"type\":\"uint32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint32\",\"name\":\"networkID\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_gasTokenAddress\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"_gasTokenNetwork\",\"type\":\"uint32\"},{\"internalType\":\"bytes\",\"name\":\"_gasTokenMetadata\",\"type\":\"bytes\"}],\"name\":\"generateInitializeTransaction\",\"outputs\":[{\"internalType\":\"bytes\",\"name\":\"\",\"type\":\"bytes\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"globalExitRootManager\",\"outputs\":[{\"internalType\":\"contractIPolygonZkEVMGlobalExitRootV2\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_admin\",\"type\":\"address\"},{\"internalType\":\"address\",\"name\":\"sequencer\",\"type\":\"address\"},{\"internalType\":\"uint32\",\"name\":\"networkID\",\"type\":\"uint32\"},{\"internalType\":\"address\",\"name\":\"_gasTokenAddress\",\"type\":\"address\"},{\"internalType\":\"string\",\"name\":\"sequencerURL\",\"type\":\"string\"},{\"internalType\":\"string\",\"name\":\"_networkName\",\"type\":\"string\"}],\"name\":\"initialize\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastAccInputHash\",\"outputs\":[{\"internalType\":\"bytes32\",\"name\":\"\",\"type\":\"bytes32\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastForceBatch\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"lastForceBatchSequenced\",\"outputs\":[{\"internalType\":\"uint64\",\"name\":\"\",\"type\":\"uint64\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"networkName\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"lastVerifiedBatch\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"newStateRoot\",\"type\":\"bytes32\"},{\"internalType\":\"address\",\"name\":\"aggregator\",\"type\":\"address\"}],\"name\":\"onVerifyBatches\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pendingAdmin\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"pol\",\"outputs\":[{\"internalType\":\"contractIERC20Upgradeable\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"rollupManager\",\"outputs\":[{\"internalType\":\"contractPolygonRollupManager\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"forcedGlobalExitRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"forcedTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"forcedBlockHashL1\",\"type\":\"bytes32\"}],\"internalType\":\"structPolygonRollupBaseEtrog.BatchData[]\",\"name\":\"batches\",\"type\":\"tuple[]\"},{\"internalType\":\"uint64\",\"name\":\"maxSequenceTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"uint64\",\"name\":\"initSequencedBatch\",\"type\":\"uint64\"},{\"internalType\":\"address\",\"name\":\"l2Coinbase\",\"type\":\"address\"}],\"name\":\"sequenceBatches\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"components\":[{\"internalType\":\"bytes\",\"name\":\"transactions\",\"type\":\"bytes\"},{\"internalType\":\"bytes32\",\"name\":\"forcedGlobalExitRoot\",\"type\":\"bytes32\"},{\"internalType\":\"uint64\",\"name\":\"forcedTimestamp\",\"type\":\"uint64\"},{\"internalType\":\"bytes32\",\"name\":\"forcedBlockHashL1\",\"type\":\"bytes32\"}],\"internalType\":\"structPolygonRollupBaseEtrog.BatchData[]\",\"name\":\"batches\",\"type\":\"tuple[]\"}],\"name\":\"sequenceForceBatches\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newForceBatchAddress\",\"type\":\"address\"}],\"name\":\"setForceBatchAddress\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"uint64\",\"name\":\"newforceBatchTimeout\",\"type\":\"uint64\"}],\"name\":\"setForceBatchTimeout\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newTrustedSequencer\",\"type\":\"address\"}],\"name\":\"setTrustedSequencer\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"string\",\"name\":\"newTrustedSequencerURL\",\"type\":\"string\"}],\"name\":\"setTrustedSequencerURL\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[{\"internalType\":\"address\",\"name\":\"newPendingAdmin\",\"type\":\"address\"}],\"name\":\"transferAdminRole\",\"outputs\":[],\"stateMutability\":\"nonpayable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trustedSequencer\",\"outputs\":[{\"internalType\":\"address\",\"name\":\"\",\"type\":\"address\"}],\"stateMutability\":\"view\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"trustedSequencerURL\",\"outputs\":[{\"internalType\":\"string\",\"name\":\"\",\"type\":\"string\"}],\"stateMutability\":\"view\",\"type\":\"function\"}]", + Bin: "0x6101006040523480156200001257600080fd5b506040516200440f3803806200440f833981016040819052620000359162000071565b6001600160a01b0393841660a052918316608052821660c0521660e052620000d9565b6001600160a01b03811681146200006e57600080fd5b50565b600080600080608085870312156200008857600080fd5b8451620000958162000058565b6020860151909450620000a88162000058565b6040860151909350620000bb8162000058565b6060860151909250620000ce8162000058565b939692955090935050565b60805160a05160c05160e05161424d620001c2600039600081816105030152818161097101528181610ade01528181610d290152818161130f015281816117b301528181611c0a01528181611d00015281816128ee015281816129670152818161298901528181612aa101528181612c440152612d0c01526000818161065d01528181610f2201528181610ffc01528181611ed101528181611fd9015261242b01526000818161071901528181611183015281816124ad0152612e5701526000818161075e0152818161081d01528181611c5301528181612a370152612e2b015261424d6000f3fe608060405234801561001057600080fd5b50600436106102e85760003560e01c80637125702211610191578063c7fffd4b116100e3578063def57e5411610097578063eaeb077b11610071578063eaeb077b14610794578063f35dda47146107a7578063f851a440146107af57600080fd5b8063def57e5414610746578063e46761c414610759578063e7a7ed021461078057600080fd5b8063cfa8ed47116100c8578063cfa8ed47146106f4578063d02103ca14610714578063d7bc90ff1461073b57600080fd5b8063c7fffd4b146106d9578063c89e42df146106e157600080fd5b80639f26f84011610145578063ada8f9191161011f578063ada8f91914610692578063b0afe154146106a5578063c754c7ed146106b157600080fd5b80639f26f84014610645578063a3c573eb14610658578063a652f26c1461067f57600080fd5b80638c3d7301116101765780638c3d73011461060f57806391cafe32146106175780639e0018771461062a57600080fd5b806371257022146105c05780637a5460c5146105d357600080fd5b806340b5de6c1161024a57806352bdeb6d116101fe5780636b8616ce116101d85780636b8616ce146105845780636e05d2cd146105a45780636ff512cc146105ad57600080fd5b806352bdeb6d14610538578063542028d514610574578063676870d21461057c57600080fd5b8063456052671161022f57806345605267146104c557806349b7b802146104fe5780634e4877061461052557600080fd5b806340b5de6c1461046557806342308fab146104bd57600080fd5b806326782247116102a157806332c2d1531161028657806332c2d153146103f35780633c351e10146104085780633cbc795b1461042857600080fd5b8063267822471461038e5780632c111c06146103d357600080fd5b806305835f37116102d257806305835f3714610323578063107bf28c1461036c57806311e892d41461037457600080fd5b8062d0295d146102ed5780630350896314610308575b600080fd5b6102f56107d5565b6040519081526020015b60405180910390f35b610310602081565b60405161ffff90911681526020016102ff565b61035f6040518060400160405280600881526020017f80808401c9c3809400000000000000000000000000000000000000000000000081525081565b6040516102ff91906134c7565b61035f6108e1565b61037c60f981565b60405160ff90911681526020016102ff565b6001546103ae9073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102ff565b6008546103ae9073ffffffffffffffffffffffffffffffffffffffff1681565b61040661040136600461351c565b61096f565b005b6009546103ae9073ffffffffffffffffffffffffffffffffffffffff1681565b6009546104509074010000000000000000000000000000000000000000900463ffffffff1681565b60405163ffffffff90911681526020016102ff565b61048c7fff0000000000000000000000000000000000000000000000000000000000000081565b6040517fff0000000000000000000000000000000000000000000000000000000000000090911681526020016102ff565b6102f5602481565b6007546104e59068010000000000000000900467ffffffffffffffff1681565b60405167ffffffffffffffff90911681526020016102ff565b6103ae7f000000000000000000000000000000000000000000000000000000000000000081565b61040661053336600461355e565b610a3e565b61035f6040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525081565b61035f610c50565b610310601f81565b6102f561059236600461355e565b60066020526000908152604090205481565b6102f560055481565b6104066105bb36600461357b565b610c5d565b6104066105ce3660046136c4565b610d27565b61035f6040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525081565b61040661154b565b61040661062536600461357b565b61161e565b6103ae73a40d5f56745a118d0906a34e69aec8c0db1cb8fa81565b6104066106533660046137bd565b611737565b6103ae7f000000000000000000000000000000000000000000000000000000000000000081565b61035f61068d3660046137ff565b611dd0565b6104066106a036600461357b565b6121b5565b6102f56405ca1ab1e081565b6007546104e590700100000000000000000000000000000000900467ffffffffffffffff1681565b61037c60e481565b6104066106ef366004613874565b61227f565b6002546103ae9073ffffffffffffffffffffffffffffffffffffffff1681565b6103ae7f000000000000000000000000000000000000000000000000000000000000000081565b6102f5635ca1ab1e81565b6104066107543660046138a9565b612312565b6103ae7f000000000000000000000000000000000000000000000000000000000000000081565b6007546104e59067ffffffffffffffff1681565b6104066107a2366004613926565b612bcd565b61037c601b81565b6000546103ae9062010000900473ffffffffffffffffffffffffffffffffffffffff1681565b6040517f70a08231000000000000000000000000000000000000000000000000000000008152306004820152600090819073ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016906370a0823190602401602060405180830381865afa158015610864573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610888919061399e565b6007549091506000906108b39067ffffffffffffffff680100000000000000008204811691166139e6565b67ffffffffffffffff169050806000036108d05760009250505090565b6108da8183613a0e565b9250505090565b600480546108ee90613a49565b80601f016020809104026020016040519081016040528092919081815260200182805461091a90613a49565b80156109675780601f1061093c57610100808354040283529160200191610967565b820191906000526020600020905b81548152906001019060200180831161094a57829003601f168201915b505050505081565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633146109de576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff168367ffffffffffffffff167f9c72852172521097ba7e1482e6b44b351323df0155f97f4ea18fcec28e1f596684604051610a3191815260200190565b60405180910390a3505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314610a95576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62093a8067ffffffffffffffff82161115610adc576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa158015610b47573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b6b9190613a9c565b610bcc5760075467ffffffffffffffff700100000000000000000000000000000000909104811690821610610bcc576040517ff5e37f2f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780547fffffffffffffffff0000000000000000ffffffffffffffffffffffffffffffff1670010000000000000000000000000000000067ffffffffffffffff8416908102919091179091556040519081527fa7eb6cb8a613eb4e8bddc1ac3d61ec6cf10898760f0b187bcca794c6ca6fa40b906020015b60405180910390a150565b600380546108ee90613a49565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314610cb4576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600280547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527ff54144f9611984021529f814a1cb6a41e22c58351510a0d9f7e822618abb9cc090602001610c45565b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163314610d96576040517fb9b3a2c800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054610100900460ff1615808015610db65750600054600160ff909116105b80610dd05750303b158015610dd0575060005460ff166001145b610e61576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790558015610ebf57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b606073ffffffffffffffffffffffffffffffffffffffff851615611124576040517fc00f14ab00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff86811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063c00f14ab90602401600060405180830381865afa158015610f69573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052610faf9190810190613abe565b6040517f318aee3d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff878116600483015291925060009182917f00000000000000000000000000000000000000000000000000000000000000009091169063318aee3d906024016040805180830381865afa158015611044573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110689190613b35565b915091508163ffffffff166000146110e0576009805463ffffffff841674010000000000000000000000000000000000000000027fffffffffffffffff00000000000000000000000000000000000000000000000090911673ffffffffffffffffffffffffffffffffffffffff841617179055611121565b600980547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff89161790555b50505b60095460009061116c90889073ffffffffffffffffffffffffffffffffffffffff81169074010000000000000000000000000000000000000000900463ffffffff1685611dd0565b9050600081805190602001209050600042905060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156111ec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611210919061399e565b90506000808483858f611224600143613b6f565b60408051602081019790975286019490945260608086019390935260c09190911b7fffffffffffffffff000000000000000000000000000000000000000000000000166080850152901b7fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016608883015240609c82015260bc01604080518083037fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe001815290829052805160209091012060058190557f9a908e73000000000000000000000000000000000000000000000000000000008252600160048301526024820181905291507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af115801561136d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113919190613b88565b508c600060026101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508b600260006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555088600390816114239190613beb565b5060046114308982613beb565b508c600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555062069780600760106101000a81548167ffffffffffffffff021916908367ffffffffffffffff1602179055507f060116213bcbf54ca19fd649dc84b59ab2bbd200ab199770e4d923e222a28e7f85838e6040516114d193929190613d05565b60405180910390a1505050505050801561154257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a15b50505050505050565b60015473ffffffffffffffffffffffffffffffffffffffff16331461159c576040517fd1ec4b2300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600154600080547fffffffffffffffffffff0000000000000000000000000000000000000000ffff1673ffffffffffffffffffffffffffffffffffffffff9092166201000081029290921790556040519081527f056dc487bbf0795d0bbb1b4f0af523a855503cff740bfb4d5475f7a90c091e8e9060200160405180910390a1565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff163314611675576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60085473ffffffffffffffffffffffffffffffffffffffff166116c4576040517fc89374d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600880547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527f5fbd7dd171301c4a1611a84aac4ba86d119478560557755f7927595b082634fb90602001610c45565b60085473ffffffffffffffffffffffffffffffffffffffff168015801590611775575073ffffffffffffffffffffffffffffffffffffffff81163314155b156117ac576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b4262093a807f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166330c27dde6040518163ffffffff1660e01b8152600401602060405180830381865afa15801561181c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118409190613b88565b61184a9190613d44565b67ffffffffffffffff16111561188c576040517f3d49ed4c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8160008190036118c8576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e8811115611904576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60075467ffffffffffffffff8082169161192c91849168010000000000000000900416613d65565b1115611964576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6007546005546801000000000000000090910467ffffffffffffffff169060005b83811015611c045760008787838181106119a1576119a1613d78565b90506020028101906119b39190613da7565b6119bc90613de5565b9050836119c881613e6e565b825180516020918201208185015160408087015160608801519151959a50929550600094611a35948794929101938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8916600090815260069093529120549091508114611abe576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff8616600090815260066020526040812055611ae3600188613b6f565b8403611b525742600760109054906101000a900467ffffffffffffffff168460400151611b109190613d44565b67ffffffffffffffff161115611b52576040517fc44a082100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018b90529285018790528481019390935260c01b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808401523390911b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc016040516020818303038152906040528051906020012094505050508080611bfc90613e95565b915050611985565b50611c7a7f000000000000000000000000000000000000000000000000000000000000000084611c326107d5565b611c3c9190613ecd565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016919061309f565b60058190556007805467ffffffffffffffff841668010000000000000000027fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff9091161790556040517f9a908e7300000000000000000000000000000000000000000000000000000000815260009073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001690639a908e7390611d4c908790869060040167ffffffffffffffff929092168252602082015260400190565b6020604051808303816000875af1158015611d6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d8f9190613b88565b60405190915067ffffffffffffffff8216907f648a61dd2438f072f5a1960939abd30f37aea80d2e94c9792ad142d3e0a490a490600090a250505050505050565b6060600085858573a40d5f56745a118d0906a34e69aec8c0db1cb8fa600087604051602401611e0496959493929190613ee4565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167ff811bff7000000000000000000000000000000000000000000000000000000001790528351909150606090600003611f555760f9601f8351611e999190613f47565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b800000000000000000000000000000000000000000000000000000000000081525060e487604051602001611f3f9796959493929190613f62565b6040516020818303038152906040529050612059565b815161ffff1015611f92576040517f248b8f8200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b815160f9611fa1602083613f47565b6040518060400160405280600881526020017f80808401c9c380940000000000000000000000000000000000000000000000008152507f00000000000000000000000000000000000000000000000000000000000000006040518060400160405280600281526020017f80b900000000000000000000000000000000000000000000000000000000000081525085886040516020016120469796959493929190614045565b6040516020818303038152906040529150505b805160208083019190912060408051600080825293810180835292909252601b908201526405ca1ab1e06060820152635ca1ab1e608082015260019060a0016020604051602081039080840390855afa1580156120ba573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116612132576040517fcd16196600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040516000906121789084906405ca1ab1e090635ca1ab1e90601b907fff0000000000000000000000000000000000000000000000000000000000000090602001614128565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190529450505050505b949350505050565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff16331461220c576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040519081527fa5b56b7906fd0a20e3f35120dd8343db1e12e037a6c90111c7e42885e82a1ce690602001610c45565b60005462010000900473ffffffffffffffffffffffffffffffffffffffff1633146122d6576040517f4755657900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60036122e28282613beb565b507f6b8f723a4c7a5335cafae8a598a0aa0301be1387c037dccc085b62add6448b2081604051610c4591906134c7565b60025473ffffffffffffffffffffffffffffffffffffffff163314612363576040517f11e7be1500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83600081900361239f576040517fcb591a5f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6103e88111156123db576040517fb59f753a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123e6602442613d65565b8467ffffffffffffffff161115612429576040517f0a00feb300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166379e2cf976040518163ffffffff1660e01b8152600401600060405180830381600087803b15801561249157600080fd5b505af11580156124a5573d6000803e3d6000fd5b5050505060007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16635ca1e1656040518163ffffffff1660e01b8152600401602060405180830381865afa158015612516573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061253a919061399e565b60075460055491925068010000000000000000900467ffffffffffffffff16908160005b858110156128605760008b8b8381811061257a5761257a613d78565b905060200281019061258c9190613da7565b61259590613de5565b8051805160209091012060408201519192509067ffffffffffffffff161561277a57856125c181613e6e565b9650506000818360200151846040015185606001516040516020016126249493929190938452602084019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166040830152604882015260680190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012067ffffffffffffffff8a166000908152600690935291205490915081146126ad576040517fce3d755e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60208381015160408086015160608088015183519586018c90529285018790528481019390935260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166080840152908c901b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166088830152609c82015260bc01604051602081830303815290604052805190602001209550600660008867ffffffffffffffff1667ffffffffffffffff168152602001908152602001600020600090555061284b565b8151516201d4c010156127b9576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040805160208101879052908101829052606080820189905260c08d901b7fffffffffffffffff0000000000000000000000000000000000000000000000001660808301528a901b7fffffffffffffffffffffffffffffffffffffffff0000000000000000000000001660888201526000609c82015260bc016040516020818303038152906040528051906020012094505b5050808061285890613e95565b91505061255e565b5060075467ffffffffffffffff90811690841611156128ab576040517fc630a00d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60058290558467ffffffffffffffff848116908316146129615760006128d183866139e6565b90506128e767ffffffffffffffff821683613b6f565b91506129207f00000000000000000000000000000000000000000000000000000000000000008267ffffffffffffffff16611c326107d5565b50600780547fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000067ffffffffffffffff8716021790555b612a5f337f0000000000000000000000000000000000000000000000000000000000000000837f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663477fa2706040518163ffffffff1660e01b8152600401602060405180830381865afa1580156129f2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a16919061399e565b612a209190613ecd565b73ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016929190613178565b6040517f9a908e7300000000000000000000000000000000000000000000000000000000815267ffffffffffffffff87166004820152602481018490526000907f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1690639a908e73906044016020604051808303816000875af1158015612aff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612b239190613b88565b9050612b2f87826139e6565b67ffffffffffffffff168967ffffffffffffffff1614612b7b576040517f1a070d9a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b8067ffffffffffffffff167f3e54d0825ed78523037d00a81759237eb436ce774bd546993ee67a1b67b6e76687604051612bb791815260200190565b60405180910390a2505050505050505050505050565b60085473ffffffffffffffffffffffffffffffffffffffff168015801590612c0b575073ffffffffffffffffffffffffffffffffffffffff81163314155b15612c42576040517f24eff8c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa158015612cad573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cd19190613a9c565b15612d08576040517f39258d1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663604691696040518163ffffffff1660e01b8152600401602060405180830381865afa158015612d75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d99919061399e565b905082811115612dd5576040517f2354600f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611388841115612e11576040517fa29a6c7c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b612e5373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000016333084613178565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16633ed691ef6040518163ffffffff1660e01b8152600401602060405180830381865afa158015612ec0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612ee4919061399e565b6007805491925067ffffffffffffffff909116906000612f0383613e6e565b91906101000a81548167ffffffffffffffff021916908367ffffffffffffffff160217905550508585604051612f3a929190614184565b6040519081900390208142612f50600143613b6f565b60408051602081019590955284019290925260c01b7fffffffffffffffff000000000000000000000000000000000000000000000000166060830152406068820152608801604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152918152815160209283012060075467ffffffffffffffff166000908152600690935291205532330361304857600754604080518381523360208201526060818301819052600090820152905167ffffffffffffffff909216917ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc9319181900360800190a2613097565b60075460405167ffffffffffffffff909116907ff94bb37db835f1ab585ee00041849a09b12cd081d77fa15ca070757619cbc9319061308e90849033908b908b90614194565b60405180910390a25b505050505050565b60405173ffffffffffffffffffffffffffffffffffffffff83166024820152604481018290526131739084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909316929092179091526131dc565b505050565b60405173ffffffffffffffffffffffffffffffffffffffff808516602483015283166044820152606481018290526131d69085907f23b872dd00000000000000000000000000000000000000000000000000000000906084016130f1565b50505050565b600061323e826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff166132e89092919063ffffffff16565b805190915015613173578080602001905181019061325c9190613a9c565b613173576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610e58565b60606121ad8484600085856000808673ffffffffffffffffffffffffffffffffffffffff16858760405161331c9190614205565b60006040518083038185875af1925050503d8060008114613359576040519150601f19603f3d011682016040523d82523d6000602084013e61335e565b606091505b509150915061336f8783838761337a565b979650505050505050565b606083156134105782516000036134095773ffffffffffffffffffffffffffffffffffffffff85163b613409576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610e58565b50816121ad565b6121ad83838151156134255781518083602001fd5b806040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5891906134c7565b60005b8381101561347457818101518382015260200161345c565b50506000910152565b60008151808452613495816020860160208601613459565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006134da602083018461347d565b9392505050565b67ffffffffffffffff811681146134f757600080fd5b50565b73ffffffffffffffffffffffffffffffffffffffff811681146134f757600080fd5b60008060006060848603121561353157600080fd5b833561353c816134e1565b9250602084013591506040840135613553816134fa565b809150509250925092565b60006020828403121561357057600080fd5b81356134da816134e1565b60006020828403121561358d57600080fd5b81356134da816134fa565b63ffffffff811681146134f757600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715613620576136206135aa565b604052919050565b600067ffffffffffffffff821115613642576136426135aa565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f83011261367f57600080fd5b813561369261368d82613628565b6135d9565b8181528460208386010111156136a757600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060008060c087890312156136dd57600080fd5b86356136e8816134fa565b955060208701356136f8816134fa565b9450604087013561370881613598565b93506060870135613718816134fa565b9250608087013567ffffffffffffffff8082111561373557600080fd5b6137418a838b0161366e565b935060a089013591508082111561375757600080fd5b5061376489828a0161366e565b9150509295509295509295565b60008083601f84011261378357600080fd5b50813567ffffffffffffffff81111561379b57600080fd5b6020830191508360208260051b85010111156137b657600080fd5b9250929050565b600080602083850312156137d057600080fd5b823567ffffffffffffffff8111156137e757600080fd5b6137f385828601613771565b90969095509350505050565b6000806000806080858703121561381557600080fd5b843561382081613598565b93506020850135613830816134fa565b9250604085013561384081613598565b9150606085013567ffffffffffffffff81111561385c57600080fd5b6138688782880161366e565b91505092959194509250565b60006020828403121561388657600080fd5b813567ffffffffffffffff81111561389d57600080fd5b6121ad8482850161366e565b6000806000806000608086880312156138c157600080fd5b853567ffffffffffffffff8111156138d857600080fd5b6138e488828901613771565b90965094505060208601356138f8816134e1565b92506040860135613908816134e1565b91506060860135613918816134fa565b809150509295509295909350565b60008060006040848603121561393b57600080fd5b833567ffffffffffffffff8082111561395357600080fd5b818601915086601f83011261396757600080fd5b81358181111561397657600080fd5b87602082850101111561398857600080fd5b6020928301989097509590910135949350505050565b6000602082840312156139b057600080fd5b5051919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b67ffffffffffffffff828116828216039080821115613a0757613a076139b7565b5092915050565b600082613a44577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b600181811c90821680613a5d57607f821691505b602082108103613a96577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b600060208284031215613aae57600080fd5b815180151581146134da57600080fd5b600060208284031215613ad057600080fd5b815167ffffffffffffffff811115613ae757600080fd5b8201601f81018413613af857600080fd5b8051613b0661368d82613628565b818152856020838501011115613b1b57600080fd5b613b2c826020830160208601613459565b95945050505050565b60008060408385031215613b4857600080fd5b8251613b5381613598565b6020840151909250613b64816134fa565b809150509250929050565b81810381811115613b8257613b826139b7565b92915050565b600060208284031215613b9a57600080fd5b81516134da816134e1565b601f82111561317357600081815260208120601f850160051c81016020861015613bcc5750805b601f850160051c820191505b8181101561309757828155600101613bd8565b815167ffffffffffffffff811115613c0557613c056135aa565b613c1981613c138454613a49565b84613ba5565b602080601f831160018114613c6c5760008415613c365750858301515b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600386901b1c1916600185901b178555613097565b6000858152602081207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08616915b82811015613cb957888601518255948401946001909101908401613c9a565b5085821015613cf557878501517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff600388901b60f8161c191681555b5050505050600190811b01905550565b606081526000613d18606083018661347d565b905083602083015273ffffffffffffffffffffffffffffffffffffffff83166040830152949350505050565b67ffffffffffffffff818116838216019080821115613a0757613a076139b7565b80820180821115613b8257613b826139b7565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600082357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81833603018112613ddb57600080fd5b9190910192915050565b600060808236031215613df757600080fd5b6040516080810167ffffffffffffffff8282108183111715613e1b57613e1b6135aa565b816040528435915080821115613e3057600080fd5b50613e3d3682860161366e565b825250602083013560208201526040830135613e58816134e1565b6040820152606092830135928101929092525090565b600067ffffffffffffffff808316818103613e8b57613e8b6139b7565b6001019392505050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613ec657613ec66139b7565b5060010190565b8082028115828204841417613b8257613b826139b7565b600063ffffffff808916835273ffffffffffffffffffffffffffffffffffffffff8089166020850152818816604085015280871660608501528086166080850152505060c060a0830152613f3b60c083018461347d565b98975050505050505050565b61ffff818116838216019080821115613a0757613a076139b7565b60007fff00000000000000000000000000000000000000000000000000000000000000808a60f81b1683527fffff0000000000000000000000000000000000000000000000000000000000008960f01b1660018401528751613fcb816003860160208c01613459565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b166003820152865161400e816017840160208b01613459565b808201915050818660f81b16601782015284519150614034826018830160208801613459565b016018019998505050505050505050565b7fff000000000000000000000000000000000000000000000000000000000000008860f81b16815260007fffff000000000000000000000000000000000000000000000000000000000000808960f01b16600184015287516140ae816003860160208c01613459565b80840190507fffffffffffffffffffffffffffffffffffffffff0000000000000000000000008860601b16600382015286516140f1816017840160208b01613459565b808201915050818660f01b16601782015284519150614117826019830160208801613459565b016019019998505050505050505050565b6000865161413a818460208b01613459565b9190910194855250602084019290925260f81b7fff000000000000000000000000000000000000000000000000000000000000009081166040840152166041820152604201919050565b8183823760009101908152919050565b84815273ffffffffffffffffffffffffffffffffffffffff8416602082015260606040820152816060820152818360808301376000818301608090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01601019392505050565b60008251613ddb81846020870161345956fea26469706673582212208984c2308dba308dc344163eec692d3156ed8e3b7becdc49922152f5b72cca8764736f6c63430008140033", } // PolygonzkevmABI is the input ABI used to generate the binding from. @@ -489,37 +489,6 @@ func (_Polygonzkevm *PolygonzkevmCallerSession) INITIALIZETXEFFECTIVEPERCENTAGE( return _Polygonzkevm.Contract.INITIALIZETXEFFECTIVEPERCENTAGE(&_Polygonzkevm.CallOpts) } -// SETUPETROGTX is a free data retrieval call binding the contract method 0xaf7f3e02. -// -// Solidity: function SET_UP_ETROG_TX() view returns(bytes) -func (_Polygonzkevm *PolygonzkevmCaller) SETUPETROGTX(opts *bind.CallOpts) ([]byte, error) { - var out []interface{} - err := _Polygonzkevm.contract.Call(opts, &out, "SET_UP_ETROG_TX") - - if err != nil { - return *new([]byte), err - } - - out0 := *abi.ConvertType(out[0], new([]byte)).(*[]byte) - - return out0, err - -} - -// SETUPETROGTX is a free data retrieval call binding the contract method 0xaf7f3e02. -// -// Solidity: function SET_UP_ETROG_TX() view returns(bytes) -func (_Polygonzkevm *PolygonzkevmSession) SETUPETROGTX() ([]byte, error) { - return _Polygonzkevm.Contract.SETUPETROGTX(&_Polygonzkevm.CallOpts) -} - -// SETUPETROGTX is a free data retrieval call binding the contract method 0xaf7f3e02. -// -// Solidity: function SET_UP_ETROG_TX() view returns(bytes) -func (_Polygonzkevm *PolygonzkevmCallerSession) SETUPETROGTX() ([]byte, error) { - return _Polygonzkevm.Contract.SETUPETROGTX(&_Polygonzkevm.CallOpts) -} - // SIGNATUREINITIALIZETXR is a free data retrieval call binding the contract method 0xb0afe154. // // Solidity: function SIGNATURE_INITIALIZE_TX_R() view returns(bytes32) @@ -613,6 +582,37 @@ func (_Polygonzkevm *PolygonzkevmCallerSession) SIGNATUREINITIALIZETXV() (uint8, return _Polygonzkevm.Contract.SIGNATUREINITIALIZETXV(&_Polygonzkevm.CallOpts) } +// TIMESTAMPRANGE is a free data retrieval call binding the contract method 0x42308fab. +// +// Solidity: function TIMESTAMP_RANGE() view returns(uint256) +func (_Polygonzkevm *PolygonzkevmCaller) TIMESTAMPRANGE(opts *bind.CallOpts) (*big.Int, error) { + var out []interface{} + err := _Polygonzkevm.contract.Call(opts, &out, "TIMESTAMP_RANGE") + + if err != nil { + return *new(*big.Int), err + } + + out0 := *abi.ConvertType(out[0], new(*big.Int)).(**big.Int) + + return out0, err + +} + +// TIMESTAMPRANGE is a free data retrieval call binding the contract method 0x42308fab. +// +// Solidity: function TIMESTAMP_RANGE() view returns(uint256) +func (_Polygonzkevm *PolygonzkevmSession) TIMESTAMPRANGE() (*big.Int, error) { + return _Polygonzkevm.Contract.TIMESTAMPRANGE(&_Polygonzkevm.CallOpts) +} + +// TIMESTAMPRANGE is a free data retrieval call binding the contract method 0x42308fab. +// +// Solidity: function TIMESTAMP_RANGE() view returns(uint256) +func (_Polygonzkevm *PolygonzkevmCallerSession) TIMESTAMPRANGE() (*big.Int, error) { + return _Polygonzkevm.Contract.TIMESTAMPRANGE(&_Polygonzkevm.CallOpts) +} + // Admin is a free data retrieval call binding the contract method 0xf851a440. // // Solidity: function admin() view returns(address) @@ -1265,27 +1265,6 @@ func (_Polygonzkevm *PolygonzkevmTransactorSession) Initialize(_admin common.Add return _Polygonzkevm.Contract.Initialize(&_Polygonzkevm.TransactOpts, _admin, sequencer, networkID, _gasTokenAddress, sequencerURL, _networkName) } -// InitializeUpgrade is a paid mutator transaction binding the contract method 0x5d6717a5. -// -// Solidity: function initializeUpgrade(address _admin, address _trustedSequencer, string _trustedSequencerURL, string _networkName, bytes32 _lastAccInputHash) returns() -func (_Polygonzkevm *PolygonzkevmTransactor) InitializeUpgrade(opts *bind.TransactOpts, _admin common.Address, _trustedSequencer common.Address, _trustedSequencerURL string, _networkName string, _lastAccInputHash [32]byte) (*types.Transaction, error) { - return _Polygonzkevm.contract.Transact(opts, "initializeUpgrade", _admin, _trustedSequencer, _trustedSequencerURL, _networkName, _lastAccInputHash) -} - -// InitializeUpgrade is a paid mutator transaction binding the contract method 0x5d6717a5. -// -// Solidity: function initializeUpgrade(address _admin, address _trustedSequencer, string _trustedSequencerURL, string _networkName, bytes32 _lastAccInputHash) returns() -func (_Polygonzkevm *PolygonzkevmSession) InitializeUpgrade(_admin common.Address, _trustedSequencer common.Address, _trustedSequencerURL string, _networkName string, _lastAccInputHash [32]byte) (*types.Transaction, error) { - return _Polygonzkevm.Contract.InitializeUpgrade(&_Polygonzkevm.TransactOpts, _admin, _trustedSequencer, _trustedSequencerURL, _networkName, _lastAccInputHash) -} - -// InitializeUpgrade is a paid mutator transaction binding the contract method 0x5d6717a5. -// -// Solidity: function initializeUpgrade(address _admin, address _trustedSequencer, string _trustedSequencerURL, string _networkName, bytes32 _lastAccInputHash) returns() -func (_Polygonzkevm *PolygonzkevmTransactorSession) InitializeUpgrade(_admin common.Address, _trustedSequencer common.Address, _trustedSequencerURL string, _networkName string, _lastAccInputHash [32]byte) (*types.Transaction, error) { - return _Polygonzkevm.Contract.InitializeUpgrade(&_Polygonzkevm.TransactOpts, _admin, _trustedSequencer, _trustedSequencerURL, _networkName, _lastAccInputHash) -} - // OnVerifyBatches is a paid mutator transaction binding the contract method 0x32c2d153. // // Solidity: function onVerifyBatches(uint64 lastVerifiedBatch, bytes32 newStateRoot, address aggregator) returns() @@ -1307,25 +1286,25 @@ func (_Polygonzkevm *PolygonzkevmTransactorSession) OnVerifyBatches(lastVerified return _Polygonzkevm.Contract.OnVerifyBatches(&_Polygonzkevm.TransactOpts, lastVerifiedBatch, newStateRoot, aggregator) } -// SequenceBatches is a paid mutator transaction binding the contract method 0xecef3f99. +// SequenceBatches is a paid mutator transaction binding the contract method 0xdef57e54. // -// Solidity: function sequenceBatches((bytes,bytes32,uint64,bytes32)[] batches, address l2Coinbase) returns() -func (_Polygonzkevm *PolygonzkevmTransactor) SequenceBatches(opts *bind.TransactOpts, batches []PolygonRollupBaseEtrogBatchData, l2Coinbase common.Address) (*types.Transaction, error) { - return _Polygonzkevm.contract.Transact(opts, "sequenceBatches", batches, l2Coinbase) +// Solidity: function sequenceBatches((bytes,bytes32,uint64,bytes32)[] batches, uint64 maxSequenceTimestamp, uint64 initSequencedBatch, address l2Coinbase) returns() +func (_Polygonzkevm *PolygonzkevmTransactor) SequenceBatches(opts *bind.TransactOpts, batches []PolygonRollupBaseEtrogBatchData, maxSequenceTimestamp uint64, initSequencedBatch uint64, l2Coinbase common.Address) (*types.Transaction, error) { + return _Polygonzkevm.contract.Transact(opts, "sequenceBatches", batches, maxSequenceTimestamp, initSequencedBatch, l2Coinbase) } -// SequenceBatches is a paid mutator transaction binding the contract method 0xecef3f99. +// SequenceBatches is a paid mutator transaction binding the contract method 0xdef57e54. // -// Solidity: function sequenceBatches((bytes,bytes32,uint64,bytes32)[] batches, address l2Coinbase) returns() -func (_Polygonzkevm *PolygonzkevmSession) SequenceBatches(batches []PolygonRollupBaseEtrogBatchData, l2Coinbase common.Address) (*types.Transaction, error) { - return _Polygonzkevm.Contract.SequenceBatches(&_Polygonzkevm.TransactOpts, batches, l2Coinbase) +// Solidity: function sequenceBatches((bytes,bytes32,uint64,bytes32)[] batches, uint64 maxSequenceTimestamp, uint64 initSequencedBatch, address l2Coinbase) returns() +func (_Polygonzkevm *PolygonzkevmSession) SequenceBatches(batches []PolygonRollupBaseEtrogBatchData, maxSequenceTimestamp uint64, initSequencedBatch uint64, l2Coinbase common.Address) (*types.Transaction, error) { + return _Polygonzkevm.Contract.SequenceBatches(&_Polygonzkevm.TransactOpts, batches, maxSequenceTimestamp, initSequencedBatch, l2Coinbase) } -// SequenceBatches is a paid mutator transaction binding the contract method 0xecef3f99. +// SequenceBatches is a paid mutator transaction binding the contract method 0xdef57e54. // -// Solidity: function sequenceBatches((bytes,bytes32,uint64,bytes32)[] batches, address l2Coinbase) returns() -func (_Polygonzkevm *PolygonzkevmTransactorSession) SequenceBatches(batches []PolygonRollupBaseEtrogBatchData, l2Coinbase common.Address) (*types.Transaction, error) { - return _Polygonzkevm.Contract.SequenceBatches(&_Polygonzkevm.TransactOpts, batches, l2Coinbase) +// Solidity: function sequenceBatches((bytes,bytes32,uint64,bytes32)[] batches, uint64 maxSequenceTimestamp, uint64 initSequencedBatch, address l2Coinbase) returns() +func (_Polygonzkevm *PolygonzkevmTransactorSession) SequenceBatches(batches []PolygonRollupBaseEtrogBatchData, maxSequenceTimestamp uint64, initSequencedBatch uint64, l2Coinbase common.Address) (*types.Transaction, error) { + return _Polygonzkevm.Contract.SequenceBatches(&_Polygonzkevm.TransactOpts, batches, maxSequenceTimestamp, initSequencedBatch, l2Coinbase) } // SequenceForceBatches is a paid mutator transaction binding the contract method 0x9f26f840. @@ -2964,143 +2943,6 @@ func (_Polygonzkevm *PolygonzkevmFilterer) ParseTransferAdminRole(log types.Log) return event, nil } -// PolygonzkevmUpdateEtrogSequenceIterator is returned from FilterUpdateEtrogSequence and is used to iterate over the raw logs and unpacked data for UpdateEtrogSequence events raised by the Polygonzkevm contract. -type PolygonzkevmUpdateEtrogSequenceIterator struct { - Event *PolygonzkevmUpdateEtrogSequence // Event containing the contract specifics and raw log - - contract *bind.BoundContract // Generic contract to use for unpacking event data - event string // Event name to use for unpacking event data - - logs chan types.Log // Log channel receiving the found contract events - sub ethereum.Subscription // Subscription for errors, completion and termination - done bool // Whether the subscription completed delivering logs - fail error // Occurred error to stop iteration -} - -// Next advances the iterator to the subsequent event, returning whether there -// are any more events found. In case of a retrieval or parsing error, false is -// returned and Error() can be queried for the exact failure. -func (it *PolygonzkevmUpdateEtrogSequenceIterator) Next() bool { - // If the iterator failed, stop iterating - if it.fail != nil { - return false - } - // If the iterator completed, deliver directly whatever's available - if it.done { - select { - case log := <-it.logs: - it.Event = new(PolygonzkevmUpdateEtrogSequence) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - default: - return false - } - } - // Iterator still in progress, wait for either a data or an error event - select { - case log := <-it.logs: - it.Event = new(PolygonzkevmUpdateEtrogSequence) - if err := it.contract.UnpackLog(it.Event, it.event, log); err != nil { - it.fail = err - return false - } - it.Event.Raw = log - return true - - case err := <-it.sub.Err(): - it.done = true - it.fail = err - return it.Next() - } -} - -// Error returns any retrieval or parsing error occurred during filtering. -func (it *PolygonzkevmUpdateEtrogSequenceIterator) Error() error { - return it.fail -} - -// Close terminates the iteration process, releasing any pending underlying -// resources. -func (it *PolygonzkevmUpdateEtrogSequenceIterator) Close() error { - it.sub.Unsubscribe() - return nil -} - -// PolygonzkevmUpdateEtrogSequence represents a UpdateEtrogSequence event raised by the Polygonzkevm contract. -type PolygonzkevmUpdateEtrogSequence struct { - NumBatch uint64 - Transactions []byte - LastGlobalExitRoot [32]byte - Sequencer common.Address - Raw types.Log // Blockchain specific contextual infos -} - -// FilterUpdateEtrogSequence is a free log retrieval operation binding the contract event 0xd2c80353fc15ef62c6affc7cd6b7ab5b42c43290c50be3372e55ae552cecd19c. -// -// Solidity: event UpdateEtrogSequence(uint64 numBatch, bytes transactions, bytes32 lastGlobalExitRoot, address sequencer) -func (_Polygonzkevm *PolygonzkevmFilterer) FilterUpdateEtrogSequence(opts *bind.FilterOpts) (*PolygonzkevmUpdateEtrogSequenceIterator, error) { - - logs, sub, err := _Polygonzkevm.contract.FilterLogs(opts, "UpdateEtrogSequence") - if err != nil { - return nil, err - } - return &PolygonzkevmUpdateEtrogSequenceIterator{contract: _Polygonzkevm.contract, event: "UpdateEtrogSequence", logs: logs, sub: sub}, nil -} - -// WatchUpdateEtrogSequence is a free log subscription operation binding the contract event 0xd2c80353fc15ef62c6affc7cd6b7ab5b42c43290c50be3372e55ae552cecd19c. -// -// Solidity: event UpdateEtrogSequence(uint64 numBatch, bytes transactions, bytes32 lastGlobalExitRoot, address sequencer) -func (_Polygonzkevm *PolygonzkevmFilterer) WatchUpdateEtrogSequence(opts *bind.WatchOpts, sink chan<- *PolygonzkevmUpdateEtrogSequence) (event.Subscription, error) { - - logs, sub, err := _Polygonzkevm.contract.WatchLogs(opts, "UpdateEtrogSequence") - if err != nil { - return nil, err - } - return event.NewSubscription(func(quit <-chan struct{}) error { - defer sub.Unsubscribe() - for { - select { - case log := <-logs: - // New log arrived, parse the event and forward to the user - event := new(PolygonzkevmUpdateEtrogSequence) - if err := _Polygonzkevm.contract.UnpackLog(event, "UpdateEtrogSequence", log); err != nil { - return err - } - event.Raw = log - - select { - case sink <- event: - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - case err := <-sub.Err(): - return err - case <-quit: - return nil - } - } - }), nil -} - -// ParseUpdateEtrogSequence is a log parse operation binding the contract event 0xd2c80353fc15ef62c6affc7cd6b7ab5b42c43290c50be3372e55ae552cecd19c. -// -// Solidity: event UpdateEtrogSequence(uint64 numBatch, bytes transactions, bytes32 lastGlobalExitRoot, address sequencer) -func (_Polygonzkevm *PolygonzkevmFilterer) ParseUpdateEtrogSequence(log types.Log) (*PolygonzkevmUpdateEtrogSequence, error) { - event := new(PolygonzkevmUpdateEtrogSequence) - if err := _Polygonzkevm.contract.UnpackLog(event, "UpdateEtrogSequence", log); err != nil { - return nil, err - } - event.Raw = log - return event, nil -} - // PolygonzkevmVerifyBatchesIterator is returned from FilterVerifyBatches and is used to iterate over the raw logs and unpacked data for VerifyBatches events raised by the Polygonzkevm contract. type PolygonzkevmVerifyBatchesIterator struct { Event *PolygonzkevmVerifyBatches // Event containing the contract specifics and raw log diff --git a/etherman/smartcontracts/script.sh b/etherman/smartcontracts/script.sh index 39e67cca8c..870a8d98f7 100755 --- a/etherman/smartcontracts/script.sh +++ b/etherman/smartcontracts/script.sh @@ -11,6 +11,7 @@ gen() { gen oldpolygonzkevmglobalexitroot gen oldpolygonzkevmbridge gen oldpolygonzkevm +gen etrogpolygonzkevm gen polygonzkevm gen polygonzkevmbridge gen pol diff --git a/etherman/types.go b/etherman/types.go index ef2af1037a..683284cbfb 100644 --- a/etherman/types.go +++ b/etherman/types.go @@ -34,6 +34,12 @@ type GlobalExitRoot struct { PreviousBlockHash common.Hash } +// SequencedBatchElderberryData represents an Elderberry sequenced batch data +type SequencedBatchElderberryData struct { + MaxSequenceTimestamp uint64 + InitSequencedBatchNumber uint64 // Last sequenced batch number +} + // SequencedBatch represents virtual batch type SequencedBatch struct { BatchNumber uint64 @@ -46,6 +52,8 @@ type SequencedBatch struct { *oldpolygonzkevm.PolygonZkEVMBatchData // Struct used in Etrog *polygonzkevm.PolygonRollupBaseEtrogBatchData + // Struct used in Elderberry + *SequencedBatchElderberryData } // UpdateEtrogSequence represents the first etrog sequence diff --git a/etherman/types/sequence.go b/etherman/types/sequence.go index 8e4f89e068..0b85760fde 100644 --- a/etherman/types/sequence.go +++ b/etherman/types/sequence.go @@ -11,7 +11,7 @@ import ( type Sequence struct { GlobalExitRoot, StateRoot, LocalExitRoot common.Hash AccInputHash common.Hash - Timestamp int64 + LastL2BLockTimestamp int64 BatchL2Data []byte IsSequenceTooBig bool BatchNumber uint64 diff --git a/sequencesender/interfaces.go b/sequencesender/interfaces.go index 3fd69540c4..98b516a63a 100644 --- a/sequencesender/interfaces.go +++ b/sequencesender/interfaces.go @@ -17,8 +17,8 @@ import ( // etherman contains the methods required to interact with ethereum. type etherman interface { - BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, l2Coinbase common.Address) (to *common.Address, data []byte, err error) - EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, l2Coinbase common.Address) (*types.Transaction, error) + BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address) (to *common.Address, data []byte, err error) + EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address) (*types.Transaction, error) // GetLastBatchTimestamp() (uint64, error) GetLatestBlockHeader(ctx context.Context) (*types.Header, error) GetLatestBatchNumber() (uint64, error) diff --git a/sequencesender/mock_etherman.go b/sequencesender/mock_etherman.go index f4a2943aff..bf526412a3 100644 --- a/sequencesender/mock_etherman.go +++ b/sequencesender/mock_etherman.go @@ -19,9 +19,9 @@ type EthermanMock struct { mock.Mock } -// BuildSequenceBatchesTxData provides a mock function with given fields: sender, sequences, l2Coinbase -func (_m *EthermanMock) BuildSequenceBatchesTxData(sender common.Address, sequences []types.Sequence, l2Coinbase common.Address) (*common.Address, []byte, error) { - ret := _m.Called(sender, sequences, l2Coinbase) +// BuildSequenceBatchesTxData provides a mock function with given fields: sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase +func (_m *EthermanMock) BuildSequenceBatchesTxData(sender common.Address, sequences []types.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address) (*common.Address, []byte, error) { + ret := _m.Called(sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase) if len(ret) == 0 { panic("no return value specified for BuildSequenceBatchesTxData") @@ -30,27 +30,27 @@ func (_m *EthermanMock) BuildSequenceBatchesTxData(sender common.Address, sequen var r0 *common.Address var r1 []byte var r2 error - if rf, ok := ret.Get(0).(func(common.Address, []types.Sequence, common.Address) (*common.Address, []byte, error)); ok { - return rf(sender, sequences, l2Coinbase) + if rf, ok := ret.Get(0).(func(common.Address, []types.Sequence, uint64, uint64, common.Address) (*common.Address, []byte, error)); ok { + return rf(sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase) } - if rf, ok := ret.Get(0).(func(common.Address, []types.Sequence, common.Address) *common.Address); ok { - r0 = rf(sender, sequences, l2Coinbase) + if rf, ok := ret.Get(0).(func(common.Address, []types.Sequence, uint64, uint64, common.Address) *common.Address); ok { + r0 = rf(sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*common.Address) } } - if rf, ok := ret.Get(1).(func(common.Address, []types.Sequence, common.Address) []byte); ok { - r1 = rf(sender, sequences, l2Coinbase) + if rf, ok := ret.Get(1).(func(common.Address, []types.Sequence, uint64, uint64, common.Address) []byte); ok { + r1 = rf(sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase) } else { if ret.Get(1) != nil { r1 = ret.Get(1).([]byte) } } - if rf, ok := ret.Get(2).(func(common.Address, []types.Sequence, common.Address) error); ok { - r2 = rf(sender, sequences, l2Coinbase) + if rf, ok := ret.Get(2).(func(common.Address, []types.Sequence, uint64, uint64, common.Address) error); ok { + r2 = rf(sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase) } else { r2 = ret.Error(2) } @@ -58,9 +58,9 @@ func (_m *EthermanMock) BuildSequenceBatchesTxData(sender common.Address, sequen return r0, r1, r2 } -// EstimateGasSequenceBatches provides a mock function with given fields: sender, sequences, l2Coinbase -func (_m *EthermanMock) EstimateGasSequenceBatches(sender common.Address, sequences []types.Sequence, l2Coinbase common.Address) (*coretypes.Transaction, error) { - ret := _m.Called(sender, sequences, l2Coinbase) +// EstimateGasSequenceBatches provides a mock function with given fields: sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase +func (_m *EthermanMock) EstimateGasSequenceBatches(sender common.Address, sequences []types.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address) (*coretypes.Transaction, error) { + ret := _m.Called(sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase) if len(ret) == 0 { panic("no return value specified for EstimateGasSequenceBatches") @@ -68,19 +68,19 @@ func (_m *EthermanMock) EstimateGasSequenceBatches(sender common.Address, sequen var r0 *coretypes.Transaction var r1 error - if rf, ok := ret.Get(0).(func(common.Address, []types.Sequence, common.Address) (*coretypes.Transaction, error)); ok { - return rf(sender, sequences, l2Coinbase) + if rf, ok := ret.Get(0).(func(common.Address, []types.Sequence, uint64, uint64, common.Address) (*coretypes.Transaction, error)); ok { + return rf(sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase) } - if rf, ok := ret.Get(0).(func(common.Address, []types.Sequence, common.Address) *coretypes.Transaction); ok { - r0 = rf(sender, sequences, l2Coinbase) + if rf, ok := ret.Get(0).(func(common.Address, []types.Sequence, uint64, uint64, common.Address) *coretypes.Transaction); ok { + r0 = rf(sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*coretypes.Transaction) } } - if rf, ok := ret.Get(1).(func(common.Address, []types.Sequence, common.Address) error); ok { - r1 = rf(sender, sequences, l2Coinbase) + if rf, ok := ret.Get(1).(func(common.Address, []types.Sequence, uint64, uint64, common.Address) error); ok { + r1 = rf(sender, sequences, maxSequenceTimestamp, initSequenceBatchNumber, l2Coinbase) } else { r1 = ret.Error(1) } diff --git a/sequencesender/sequencesender.go b/sequencesender/sequencesender.go index 082a522304..30e8c9f0c4 100644 --- a/sequencesender/sequencesender.go +++ b/sequencesender/sequencesender.go @@ -140,18 +140,18 @@ func (s *SequenceSender) tryToSendSequence(ctx context.Context) { // Check if we need to wait until last L1 block timestamp is L1BlockTimestampMargin seconds above the timestamp of the last L2 block in the sequence // Get last batch in the sequence - lastBatchNumInSequence := sequences[sequenceCount-1].BatchNumber + lastSequenceBatchNum := sequences[sequenceCount-1].BatchNumber // Get L2 blocks for the last batch - lastBatchL2Blocks, err := s.state.GetL2BlocksByBatchNumber(ctx, lastBatchNumInSequence, nil) + lastBatchL2Blocks, err := s.state.GetL2BlocksByBatchNumber(ctx, lastSequenceBatchNum, nil) if err != nil { - log.Errorf("failed to get L2 blocks for batch %d, err: %v", lastBatchNumInSequence, err) + log.Errorf("failed to get L2 blocks for batch %d, err: %v", lastSequenceBatchNum, err) return } // Check there are L2 blocks for the last batch if len(lastBatchL2Blocks) == 0 { - log.Errorf("no L2 blocks returned from the state for batch %d", lastBatchNumInSequence) + log.Errorf("no L2 blocks returned from the state for batch %d", lastSequenceBatchNum) return } @@ -202,13 +202,15 @@ func (s *SequenceSender) tryToSendSequence(ctx context.Context) { } // add sequence to be monitored - to, data, err := s.etherman.BuildSequenceBatchesTxData(s.cfg.SenderAddress, sequences, s.cfg.L2Coinbase) + firstSequence := sequences[0] + lastSequence := sequences[len(sequences)-1] + + to, data, err := s.etherman.BuildSequenceBatchesTxData(s.cfg.SenderAddress, sequences, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber-1, s.cfg.L2Coinbase) if err != nil { log.Error("error estimating new sequenceBatches to add to eth tx manager: ", err) return } - firstSequence := sequences[0] - lastSequence := sequences[len(sequences)-1] + monitoredTxID := fmt.Sprintf(monitoredIDFormat, firstSequence.BatchNumber, lastSequence.BatchNumber) err = s.ethTxManager.Add(ctx, ethTxManagerOwner, monitoredTxID, s.cfg.SenderAddress, to, nil, data, s.cfg.GasOffset, nil) if err != nil { @@ -286,11 +288,28 @@ func (s *SequenceSender) getSequencesToSend(ctx context.Context) ([]types.Sequen seq.GlobalExitRoot = forcedBatch.GlobalExitRoot seq.ForcedBatchTimestamp = forcedBatch.ForcedAt.Unix() seq.PrevBlockHash = fbL1Block.ParentHash + // Set sequence timestamps as the forced batch timestamp + seq.LastL2BLockTimestamp = seq.ForcedBatchTimestamp + } else { + // Set sequence timestamps as the latest l2 block timestamp + l2Blocks, err := s.state.GetL2BlocksByBatchNumber(ctx, currentBatchNumToSequence, nil) + if err != nil { + return nil, err + } + if len(l2Blocks) == 0 { + return nil, fmt.Errorf("no L2 blocks returned from the state for batch %d", currentBatchNumToSequence) + } + + // Get timestamp of the last L2 block in the sequence + lastL2Block := l2Blocks[len(l2Blocks)-1] + seq.LastL2BLockTimestamp = lastL2Block.ReceivedAt.Unix() } sequences = append(sequences, seq) // Check if can be send - tx, err = s.etherman.EstimateGasSequenceBatches(s.cfg.SenderAddress, sequences, s.cfg.L2Coinbase) + firstSequence := sequences[0] + lastSequence := sequences[len(sequences)-1] + tx, err = s.etherman.EstimateGasSequenceBatches(s.cfg.SenderAddress, sequences, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber-1, s.cfg.L2Coinbase) if err == nil && tx.Size() > s.cfg.MaxTxSizeForL1 { metrics.SequencesOvesizedDataError() log.Infof("oversized Data on TX oldHash %s (txSize %d > %d)", tx.Hash(), tx.Size(), s.cfg.MaxTxSizeForL1) @@ -300,9 +319,12 @@ func (s *SequenceSender) getSequencesToSend(ctx context.Context) ([]types.Sequen log.Infof("Handling estimage gas send sequence error: %v", err) sequences, err = s.handleEstimateGasSendSequenceErr(ctx, sequences, currentBatchNumToSequence, err) if sequences != nil { - // Handling the error gracefully, re-processing the sequence as a sanity check - _, err = s.etherman.EstimateGasSequenceBatches(s.cfg.SenderAddress, sequences, s.cfg.L2Coinbase) - return sequences, err + if len(sequences) > 0 { + // Handling the error gracefully, re-processing the sequence as a sanity check + lastSequence = sequences[len(sequences)-1] + _, err = s.etherman.EstimateGasSequenceBatches(s.cfg.SenderAddress, sequences, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber-1, s.cfg.L2Coinbase) + return sequences, err + } } return sequences, err } diff --git a/synchronizer/actions/elderberry/elderberry.go b/synchronizer/actions/elderberry/elderberry.go new file mode 100644 index 0000000000..a4c6bf21b1 --- /dev/null +++ b/synchronizer/actions/elderberry/elderberry.go @@ -0,0 +1,10 @@ +package elderberry + +import "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions" + +var ( + // ForkIDElderberry is the forkId for Elderberry + ForkIDElderberry = actions.ForkIdType(8) //nolint:gomnd + // ForksIdOnlyElderberry support only elderberry forkId + ForksIdOnlyElderberry = []actions.ForkIdType{ForkIDElderberry} +) diff --git a/synchronizer/actions/elderberry/mocks/previous_processor.go b/synchronizer/actions/elderberry/mocks/previous_processor.go new file mode 100644 index 0000000000..f0ac9293d6 --- /dev/null +++ b/synchronizer/actions/elderberry/mocks/previous_processor.go @@ -0,0 +1,141 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_elderberry + +import ( + context "context" + + etherman "github.com/0xPolygonHermez/zkevm-node/etherman" + + mock "github.com/stretchr/testify/mock" + + pgx "github.com/jackc/pgx/v4" + + time "time" +) + +// PreviousProcessor is an autogenerated mock type for the PreviousProcessor type +type PreviousProcessor struct { + mock.Mock +} + +type PreviousProcessor_Expecter struct { + mock *mock.Mock +} + +func (_m *PreviousProcessor) EXPECT() *PreviousProcessor_Expecter { + return &PreviousProcessor_Expecter{mock: &_m.Mock} +} + +// Process provides a mock function with given fields: ctx, order, l1Block, dbTx +func (_m *PreviousProcessor) Process(ctx context.Context, order etherman.Order, l1Block *etherman.Block, dbTx pgx.Tx) error { + ret := _m.Called(ctx, order, l1Block, dbTx) + + if len(ret) == 0 { + panic("no return value specified for Process") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, etherman.Order, *etherman.Block, pgx.Tx) error); ok { + r0 = rf(ctx, order, l1Block, dbTx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// PreviousProcessor_Process_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'Process' +type PreviousProcessor_Process_Call struct { + *mock.Call +} + +// Process is a helper method to define mock.On call +// - ctx context.Context +// - order etherman.Order +// - l1Block *etherman.Block +// - dbTx pgx.Tx +func (_e *PreviousProcessor_Expecter) Process(ctx interface{}, order interface{}, l1Block interface{}, dbTx interface{}) *PreviousProcessor_Process_Call { + return &PreviousProcessor_Process_Call{Call: _e.mock.On("Process", ctx, order, l1Block, dbTx)} +} + +func (_c *PreviousProcessor_Process_Call) Run(run func(ctx context.Context, order etherman.Order, l1Block *etherman.Block, dbTx pgx.Tx)) *PreviousProcessor_Process_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(etherman.Order), args[2].(*etherman.Block), args[3].(pgx.Tx)) + }) + return _c +} + +func (_c *PreviousProcessor_Process_Call) Return(_a0 error) *PreviousProcessor_Process_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *PreviousProcessor_Process_Call) RunAndReturn(run func(context.Context, etherman.Order, *etherman.Block, pgx.Tx) error) *PreviousProcessor_Process_Call { + _c.Call.Return(run) + return _c +} + +// ProcessSequenceBatches provides a mock function with given fields: ctx, sequencedBatches, blockNumber, l1BlockTimestamp, dbTx +func (_m *PreviousProcessor) ProcessSequenceBatches(ctx context.Context, sequencedBatches []etherman.SequencedBatch, blockNumber uint64, l1BlockTimestamp time.Time, dbTx pgx.Tx) error { + ret := _m.Called(ctx, sequencedBatches, blockNumber, l1BlockTimestamp, dbTx) + + if len(ret) == 0 { + panic("no return value specified for ProcessSequenceBatches") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, []etherman.SequencedBatch, uint64, time.Time, pgx.Tx) error); ok { + r0 = rf(ctx, sequencedBatches, blockNumber, l1BlockTimestamp, dbTx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// PreviousProcessor_ProcessSequenceBatches_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'ProcessSequenceBatches' +type PreviousProcessor_ProcessSequenceBatches_Call struct { + *mock.Call +} + +// ProcessSequenceBatches is a helper method to define mock.On call +// - ctx context.Context +// - sequencedBatches []etherman.SequencedBatch +// - blockNumber uint64 +// - l1BlockTimestamp time.Time +// - dbTx pgx.Tx +func (_e *PreviousProcessor_Expecter) ProcessSequenceBatches(ctx interface{}, sequencedBatches interface{}, blockNumber interface{}, l1BlockTimestamp interface{}, dbTx interface{}) *PreviousProcessor_ProcessSequenceBatches_Call { + return &PreviousProcessor_ProcessSequenceBatches_Call{Call: _e.mock.On("ProcessSequenceBatches", ctx, sequencedBatches, blockNumber, l1BlockTimestamp, dbTx)} +} + +func (_c *PreviousProcessor_ProcessSequenceBatches_Call) Run(run func(ctx context.Context, sequencedBatches []etherman.SequencedBatch, blockNumber uint64, l1BlockTimestamp time.Time, dbTx pgx.Tx)) *PreviousProcessor_ProcessSequenceBatches_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].([]etherman.SequencedBatch), args[2].(uint64), args[3].(time.Time), args[4].(pgx.Tx)) + }) + return _c +} + +func (_c *PreviousProcessor_ProcessSequenceBatches_Call) Return(_a0 error) *PreviousProcessor_ProcessSequenceBatches_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *PreviousProcessor_ProcessSequenceBatches_Call) RunAndReturn(run func(context.Context, []etherman.SequencedBatch, uint64, time.Time, pgx.Tx) error) *PreviousProcessor_ProcessSequenceBatches_Call { + _c.Call.Return(run) + return _c +} + +// NewPreviousProcessor creates a new instance of PreviousProcessor. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewPreviousProcessor(t interface { + mock.TestingT + Cleanup(func()) +}) *PreviousProcessor { + mock := &PreviousProcessor{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/synchronizer/actions/elderberry/mocks/state_l1_sequence_batches_elderberry.go b/synchronizer/actions/elderberry/mocks/state_l1_sequence_batches_elderberry.go new file mode 100644 index 0000000000..61cd625e75 --- /dev/null +++ b/synchronizer/actions/elderberry/mocks/state_l1_sequence_batches_elderberry.go @@ -0,0 +1,157 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_elderberry + +import ( + context "context" + + mock "github.com/stretchr/testify/mock" + + pgx "github.com/jackc/pgx/v4" + + state "github.com/0xPolygonHermez/zkevm-node/state" +) + +// StateL1SequenceBatchesElderberry is an autogenerated mock type for the StateL1SequenceBatchesElderberry type +type StateL1SequenceBatchesElderberry struct { + mock.Mock +} + +type StateL1SequenceBatchesElderberry_Expecter struct { + mock *mock.Mock +} + +func (_m *StateL1SequenceBatchesElderberry) EXPECT() *StateL1SequenceBatchesElderberry_Expecter { + return &StateL1SequenceBatchesElderberry_Expecter{mock: &_m.Mock} +} + +// GetL2BlocksByBatchNumber provides a mock function with given fields: ctx, batchNumber, dbTx +func (_m *StateL1SequenceBatchesElderberry) GetL2BlocksByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]state.L2Block, error) { + ret := _m.Called(ctx, batchNumber, dbTx) + + if len(ret) == 0 { + panic("no return value specified for GetL2BlocksByBatchNumber") + } + + var r0 []state.L2Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) ([]state.L2Block, error)); ok { + return rf(ctx, batchNumber, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) []state.L2Block); ok { + r0 = rf(ctx, batchNumber, dbTx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]state.L2Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok { + r1 = rf(ctx, batchNumber, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetL2BlocksByBatchNumber' +type StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call struct { + *mock.Call +} + +// GetL2BlocksByBatchNumber is a helper method to define mock.On call +// - ctx context.Context +// - batchNumber uint64 +// - dbTx pgx.Tx +func (_e *StateL1SequenceBatchesElderberry_Expecter) GetL2BlocksByBatchNumber(ctx interface{}, batchNumber interface{}, dbTx interface{}) *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call { + return &StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call{Call: _e.mock.On("GetL2BlocksByBatchNumber", ctx, batchNumber, dbTx)} +} + +func (_c *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call) Run(run func(ctx context.Context, batchNumber uint64, dbTx pgx.Tx)) *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(pgx.Tx)) + }) + return _c +} + +func (_c *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call) Return(_a0 []state.L2Block, _a1 error) *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call) RunAndReturn(run func(context.Context, uint64, pgx.Tx) ([]state.L2Block, error)) *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call { + _c.Call.Return(run) + return _c +} + +// GetLastVirtualBatchNum provides a mock function with given fields: ctx, dbTx +func (_m *StateL1SequenceBatchesElderberry) GetLastVirtualBatchNum(ctx context.Context, dbTx pgx.Tx) (uint64, error) { + ret := _m.Called(ctx, dbTx) + + if len(ret) == 0 { + panic("no return value specified for GetLastVirtualBatchNum") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, pgx.Tx) (uint64, error)); ok { + return rf(ctx, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, pgx.Tx) uint64); ok { + r0 = rf(ctx, dbTx) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(context.Context, pgx.Tx) error); ok { + r1 = rf(ctx, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StateL1SequenceBatchesElderberry_GetLastVirtualBatchNum_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLastVirtualBatchNum' +type StateL1SequenceBatchesElderberry_GetLastVirtualBatchNum_Call struct { + *mock.Call +} + +// GetLastVirtualBatchNum is a helper method to define mock.On call +// - ctx context.Context +// - dbTx pgx.Tx +func (_e *StateL1SequenceBatchesElderberry_Expecter) GetLastVirtualBatchNum(ctx interface{}, dbTx interface{}) *StateL1SequenceBatchesElderberry_GetLastVirtualBatchNum_Call { + return &StateL1SequenceBatchesElderberry_GetLastVirtualBatchNum_Call{Call: _e.mock.On("GetLastVirtualBatchNum", ctx, dbTx)} +} + +func (_c *StateL1SequenceBatchesElderberry_GetLastVirtualBatchNum_Call) Run(run func(ctx context.Context, dbTx pgx.Tx)) *StateL1SequenceBatchesElderberry_GetLastVirtualBatchNum_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(pgx.Tx)) + }) + return _c +} + +func (_c *StateL1SequenceBatchesElderberry_GetLastVirtualBatchNum_Call) Return(_a0 uint64, _a1 error) *StateL1SequenceBatchesElderberry_GetLastVirtualBatchNum_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *StateL1SequenceBatchesElderberry_GetLastVirtualBatchNum_Call) RunAndReturn(run func(context.Context, pgx.Tx) (uint64, error)) *StateL1SequenceBatchesElderberry_GetLastVirtualBatchNum_Call { + _c.Call.Return(run) + return _c +} + +// NewStateL1SequenceBatchesElderberry creates a new instance of StateL1SequenceBatchesElderberry. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewStateL1SequenceBatchesElderberry(t interface { + mock.TestingT + Cleanup(func()) +}) *StateL1SequenceBatchesElderberry { + mock := &StateL1SequenceBatchesElderberry{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/synchronizer/actions/elderberry/processor_l1_sequence_batches.go b/synchronizer/actions/elderberry/processor_l1_sequence_batches.go new file mode 100644 index 0000000000..f159badc48 --- /dev/null +++ b/synchronizer/actions/elderberry/processor_l1_sequence_batches.go @@ -0,0 +1,126 @@ +package elderberry + +import ( + "context" + "errors" + "fmt" + "time" + + "github.com/0xPolygonHermez/zkevm-node/etherman" + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/0xPolygonHermez/zkevm-node/state" + "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions" + "github.com/jackc/pgx/v4" +) + +var ( + // ErrInvalidInitialBatchNumber is returned when the initial batch number is not the expected one + ErrInvalidInitialBatchNumber = errors.New("invalid initial batch number") +) + +// PreviousProcessor is the interface that the previous processor (Etrog) +type PreviousProcessor interface { + Process(ctx context.Context, order etherman.Order, l1Block *etherman.Block, dbTx pgx.Tx) error + ProcessSequenceBatches(ctx context.Context, sequencedBatches []etherman.SequencedBatch, blockNumber uint64, l1BlockTimestamp time.Time, dbTx pgx.Tx) error +} + +// StateL1SequenceBatchesElderberry state interface +type StateL1SequenceBatchesElderberry interface { + GetLastVirtualBatchNum(ctx context.Context, dbTx pgx.Tx) (uint64, error) + GetL2BlocksByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]state.L2Block, error) +} + +// ProcessorL1SequenceBatchesElderberry is the processor for SequenceBatches for Elderberry +type ProcessorL1SequenceBatchesElderberry struct { + actions.ProcessorBase[ProcessorL1SequenceBatchesElderberry] + previousProcessor PreviousProcessor + state StateL1SequenceBatchesElderberry +} + +// NewProcessorL1SequenceBatchesElderberry returns instance of a processor for SequenceBatchesOrder +func NewProcessorL1SequenceBatchesElderberry(previousProcessor PreviousProcessor, state StateL1SequenceBatchesElderberry) *ProcessorL1SequenceBatchesElderberry { + return &ProcessorL1SequenceBatchesElderberry{ + ProcessorBase: actions.ProcessorBase[ProcessorL1SequenceBatchesElderberry]{ + SupportedEvent: []etherman.EventOrder{etherman.SequenceBatchesOrder}, + SupportedForkdIds: &ForksIdOnlyElderberry}, + previousProcessor: previousProcessor, + state: state, + } +} + +// Process process event +func (g *ProcessorL1SequenceBatchesElderberry) Process(ctx context.Context, order etherman.Order, l1Block *etherman.Block, dbTx pgx.Tx) error { + if l1Block == nil || len(l1Block.SequencedBatches) <= order.Pos { + return actions.ErrInvalidParams + } + if len(l1Block.SequencedBatches[order.Pos]) == 0 { + log.Warnf("No sequenced batches for position") + return nil + } + + sbatch := l1Block.SequencedBatches[order.Pos][0] + if isInitialSequenceBatch(sbatch) { + log.Infof("Executing initialSequenceBatch. Processing with previous processor") + return g.previousProcessor.Process(ctx, order, l1Block, dbTx) + } + + if sbatch.SequencedBatchElderberryData == nil { + log.Errorf("No elderberry sequenced batch data for batch %d", sbatch.BatchNumber) + return fmt.Errorf("no elderberry sequenced batch data for batch %d", sbatch.BatchNumber) + } + // We need to check that the sequence match + err := g.sanityCheckExpectedSequence(sbatch.SequencedBatchElderberryData.InitSequencedBatchNumber, dbTx) + if err != nil { + return err + } + // We known that the MaxSequenceTimestamp is the same for all the batches so we can use the first one + err = g.previousProcessor.ProcessSequenceBatches(ctx, l1Block.SequencedBatches[order.Pos], l1Block.BlockNumber, time.Unix(int64(sbatch.SequencedBatchElderberryData.MaxSequenceTimestamp), 0), dbTx) + // The last L2block timestamp must match MaxSequenceTimestamp + if err != nil { + return err + } + // It checks the timestamp of the last L2 block, but it's just log an error instead of refusing the event + _ = g.sanityCheckTstampLastL2Block(sbatch.SequencedBatchElderberryData.MaxSequenceTimestamp, dbTx) + return nil +} + +func isInitialSequenceBatch(sbatch etherman.SequencedBatch) bool { + return sbatch.BatchNumber == 1 +} + +func (g *ProcessorL1SequenceBatchesElderberry) sanityCheckExpectedSequence(initialBatchNumber uint64, dbTx pgx.Tx) error { + // We need to check that the sequence match + lastVirtualBatchNum, err := g.state.GetLastVirtualBatchNum(context.Background(), dbTx) + if err != nil { + log.Errorf("Error getting last virtual batch number: %s", err) + return err + } + if lastVirtualBatchNum != initialBatchNumber { + log.Errorf("The last virtual batch number is not the expected one. Expected: %d (last on DB), got: %d (L1 event)", lastVirtualBatchNum+1, initialBatchNumber) + return fmt.Errorf("the last virtual batch number is not the expected one. Expected: %d (last on DB), got: %d (L1 event) err:%w", lastVirtualBatchNum+1, initialBatchNumber, ErrInvalidInitialBatchNumber) + } + return nil +} + +func (g *ProcessorL1SequenceBatchesElderberry) sanityCheckTstampLastL2Block(timeLimit uint64, dbTx pgx.Tx) error { + lastVirtualBatchNum, err := g.state.GetLastVirtualBatchNum(context.Background(), dbTx) + if err != nil { + log.Errorf("Error getting last virtual batch number: %s", err) + return err + } + l2blocks, err := g.state.GetL2BlocksByBatchNumber(context.Background(), lastVirtualBatchNum, dbTx) + if err != nil { + log.Errorf("Error getting last virtual batch number: %s", err) + return err + } + if len(l2blocks) == 0 { + //TODO: find the previous batch until we find a L2 block to check the timestamp + return nil + } + lastL2Block := l2blocks[len(l2blocks)-1] + if uint64(lastL2Block.ReceivedAt.Unix()) <= timeLimit { + log.Errorf("The last L2 block timestamp can't be greater than timeLimit. Expected: %d (L1 event), got: %d (last L2Block)", timeLimit, lastL2Block.ReceivedAt.Unix()) + return fmt.Errorf("wrong timestamp of last L2 block timestamp with L1 event timestamp") + } + return nil +} diff --git a/synchronizer/actions/elderberry/processor_l1_sequence_batches_test.go b/synchronizer/actions/elderberry/processor_l1_sequence_batches_test.go new file mode 100644 index 0000000000..e05dcafa68 --- /dev/null +++ b/synchronizer/actions/elderberry/processor_l1_sequence_batches_test.go @@ -0,0 +1,15 @@ +package elderberry_test + +import ( + "testing" + + "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/elderberry" + mock_elderberry "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/elderberry/mocks" +) + +func TestProcessorL1InfoTreeUpdate_Process(t *testing.T) { + mockState := mock_elderberry.NewStateL1SequenceBatchesElderberry(t) + mockPreviousProcessor := mock_elderberry.NewPreviousProcessor(t) + + _ = elderberry.NewProcessorL1SequenceBatchesElderberry(mockPreviousProcessor, mockState) +} diff --git a/synchronizer/actions/etrog/processor_l1_sequence_batches.go b/synchronizer/actions/etrog/processor_l1_sequence_batches.go index 638c505cee..582004d5f1 100644 --- a/synchronizer/actions/etrog/processor_l1_sequence_batches.go +++ b/synchronizer/actions/etrog/processor_l1_sequence_batches.go @@ -70,11 +70,12 @@ func (g *ProcessorL1SequenceBatchesEtrog) Process(ctx context.Context, order eth if l1Block == nil || len(l1Block.SequencedBatches) <= order.Pos { return actions.ErrInvalidParams } - err := g.processSequenceBatches(ctx, l1Block.SequencedBatches[order.Pos], l1Block.BlockNumber, l1Block.ReceivedAt, dbTx) + err := g.ProcessSequenceBatches(ctx, l1Block.SequencedBatches[order.Pos], l1Block.BlockNumber, l1Block.ReceivedAt, dbTx) return err } -func (p *ProcessorL1SequenceBatchesEtrog) processSequenceBatches(ctx context.Context, sequencedBatches []etherman.SequencedBatch, blockNumber uint64, l1BlockTimestamp time.Time, dbTx pgx.Tx) error { +// ProcessSequenceBatches process sequence of batches +func (p *ProcessorL1SequenceBatchesEtrog) ProcessSequenceBatches(ctx context.Context, sequencedBatches []etherman.SequencedBatch, blockNumber uint64, l1BlockTimestamp time.Time, dbTx pgx.Tx) error { if len(sequencedBatches) == 0 { log.Warn("Empty sequencedBatches array detected, ignoring...") return nil diff --git a/synchronizer/common/syncinterfaces/mocks/state_full_interface.go b/synchronizer/common/syncinterfaces/mocks/state_full_interface.go index e00553efd6..8c34ad92ea 100644 --- a/synchronizer/common/syncinterfaces/mocks/state_full_interface.go +++ b/synchronizer/common/syncinterfaces/mocks/state_full_interface.go @@ -1216,6 +1216,66 @@ func (_c *StateFullInterface_GetL1InfoTreeDataFromBatchL2Data_Call) RunAndReturn return _c } +// GetL2BlocksByBatchNumber provides a mock function with given fields: ctx, batchNumber, dbTx +func (_m *StateFullInterface) GetL2BlocksByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]state.L2Block, error) { + ret := _m.Called(ctx, batchNumber, dbTx) + + if len(ret) == 0 { + panic("no return value specified for GetL2BlocksByBatchNumber") + } + + var r0 []state.L2Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) ([]state.L2Block, error)); ok { + return rf(ctx, batchNumber, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) []state.L2Block); ok { + r0 = rf(ctx, batchNumber, dbTx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]state.L2Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok { + r1 = rf(ctx, batchNumber, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StateFullInterface_GetL2BlocksByBatchNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetL2BlocksByBatchNumber' +type StateFullInterface_GetL2BlocksByBatchNumber_Call struct { + *mock.Call +} + +// GetL2BlocksByBatchNumber is a helper method to define mock.On call +// - ctx context.Context +// - batchNumber uint64 +// - dbTx pgx.Tx +func (_e *StateFullInterface_Expecter) GetL2BlocksByBatchNumber(ctx interface{}, batchNumber interface{}, dbTx interface{}) *StateFullInterface_GetL2BlocksByBatchNumber_Call { + return &StateFullInterface_GetL2BlocksByBatchNumber_Call{Call: _e.mock.On("GetL2BlocksByBatchNumber", ctx, batchNumber, dbTx)} +} + +func (_c *StateFullInterface_GetL2BlocksByBatchNumber_Call) Run(run func(ctx context.Context, batchNumber uint64, dbTx pgx.Tx)) *StateFullInterface_GetL2BlocksByBatchNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(pgx.Tx)) + }) + return _c +} + +func (_c *StateFullInterface_GetL2BlocksByBatchNumber_Call) Return(_a0 []state.L2Block, _a1 error) *StateFullInterface_GetL2BlocksByBatchNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *StateFullInterface_GetL2BlocksByBatchNumber_Call) RunAndReturn(run func(context.Context, uint64, pgx.Tx) ([]state.L2Block, error)) *StateFullInterface_GetL2BlocksByBatchNumber_Call { + _c.Call.Return(run) + return _c +} + // GetLastBatchNumber provides a mock function with given fields: ctx, dbTx func (_m *StateFullInterface) GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) { ret := _m.Called(ctx, dbTx) diff --git a/synchronizer/common/syncinterfaces/state.go b/synchronizer/common/syncinterfaces/state.go index ef39017869..a35ac56039 100644 --- a/synchronizer/common/syncinterfaces/state.go +++ b/synchronizer/common/syncinterfaces/state.go @@ -69,4 +69,5 @@ type StateFullInterface interface { GetL1InfoTreeDataFromBatchL2Data(ctx context.Context, batchL2Data []byte, dbTx pgx.Tx) (map[uint32]state.L1DataV2, common.Hash, common.Hash, error) GetExitRootByGlobalExitRoot(ctx context.Context, ger common.Hash, dbTx pgx.Tx) (*state.GlobalExitRoot, error) GetForkIDInMemory(forkId uint64) *state.ForkIDInterval + GetL2BlocksByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]state.L2Block, error) } diff --git a/synchronizer/default_l1processors.go b/synchronizer/default_l1processors.go index 5b6bd7fb6f..29429caac8 100644 --- a/synchronizer/default_l1processors.go +++ b/synchronizer/default_l1processors.go @@ -1,6 +1,7 @@ package synchronizer import ( + "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/elderberry" "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/etrog" "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/incaberry" "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions/processor_manager" @@ -15,8 +16,10 @@ func defaultsL1EventProcessors(sync *ClientSynchronizer) *processor_manager.L1Ev p.Register(incaberry.NewProcessL1SequenceForcedBatches(sync.state, sync)) p.Register(incaberry.NewProcessorForkId(sync.state, sync)) p.Register(etrog.NewProcessorL1InfoTreeUpdate(sync.state)) - p.Register(etrog.NewProcessorL1SequenceBatches(sync.state, sync, common.DefaultTimeProvider{}, sync.halter)) + sequenceBatchesProcessor := etrog.NewProcessorL1SequenceBatches(sync.state, sync, common.DefaultTimeProvider{}, sync.halter) + p.Register(sequenceBatchesProcessor) p.Register(incaberry.NewProcessorL1VerifyBatch(sync.state)) p.Register(etrog.NewProcessorL1UpdateEtrogSequence(sync.state, sync, common.DefaultTimeProvider{})) + p.Register(elderberry.NewProcessorL1SequenceBatchesElderberry(sequenceBatchesProcessor, sync.state)) return p.Build() } diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 69206ffa76..26b8df4d6e 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -20,7 +20,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/synchronizer/l1event_orders" "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared" "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_sync_etrog" - "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_sync_incaberry" "github.com/0xPolygonHermez/zkevm-node/synchronizer/metrics" "github.com/ethereum/go-ethereum/common" "github.com/jackc/pgx/v4" @@ -112,13 +111,10 @@ func NewSynchronizer( } L1SyncChecker := l2_sync_etrog.NewCheckSyncStatusToProcessBatch(res.zkEVMClient, res.state) - syncTrustedStateIncaberry := l2_sync_incaberry.NewSyncTrustedStateExecutor(res.zkEVMClient, res.state, res) syncTrustedStateEtrog := l2_sync_etrog.NewSyncTrustedBatchExecutorForEtrog(res.zkEVMClient, res.state, res.state, res, syncCommon.DefaultTimeProvider{}, L1SyncChecker) - res.syncTrustedStateExecutor = l2_shared.NewSyncTrustedStateExecutorSelector( - syncTrustedStateIncaberry, syncTrustedStateEtrog, st) - + res.syncTrustedStateExecutor = syncTrustedStateEtrog res.l1EventProcessors = defaultsL1EventProcessors(res) switch cfg.L1SynchronizationMode { case ParallelMode: diff --git a/synchronizer/synchronizer_test.go b/synchronizer/synchronizer_test.go index cc2f99e455..226a4a4537 100644 --- a/synchronizer/synchronizer_test.go +++ b/synchronizer/synchronizer_test.go @@ -126,11 +126,6 @@ func TestForcedBatchEtrog(t *testing.T) { // state preparation ctxMatchBy := mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil }) - forkIdInterval := state.ForkIDInterval{ - FromBatchNumber: 0, - ToBatchNumber: ^uint64(0), - } - m.State.EXPECT().GetForkIDInMemory(uint64(7)).Return(&forkIdInterval) m.State. On("BeginStateTransaction", ctxMatchBy). @@ -765,11 +760,6 @@ func expectedCallsForsyncTrustedState(t *testing.T, m *mocks, sync *ClientSynchr batchInPermissionLess *types.Batch, batchInTrustedNode *types.Batch, previousBatchInPermissionless *types.Batch, needToRetrieveBatchFromDatabase bool, etrogMode bool) { m.State.EXPECT().GetForkIDByBatchNumber(mock.Anything).Return(uint64(7)).Times(1) - forkIdInterval := state.ForkIDInterval{ - FromBatchNumber: 0, - ToBatchNumber: ^uint64(0), - } - m.State.EXPECT().GetForkIDInMemory(uint64(7)).Return(&forkIdInterval) batchNumber := uint64(batchInTrustedNode.Number) m.ZKEVMClient. On("BatchNumber", mock.Anything). diff --git a/test/Makefile b/test/Makefile index adba545b78..b8883b04dc 100644 --- a/test/Makefile +++ b/test/Makefile @@ -199,7 +199,7 @@ test-e2e-group-7: stop ## Runs group 7 e2e tests checking race conditions $(RUNZKPROVER) docker ps -a docker logs $(DOCKERCOMPOSEZKPROVER) - trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -failfast -race -v -p 1 -timeout 600s ../ci/e2e-group7/... + trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -failfast -race -v -p 1 -timeout 720s ../ci/e2e-group7/... .PHONY: test-e2e-group-8 test-e2e-group-8: stop ## Runs group 8 e2e tests checking race conditions @@ -701,10 +701,14 @@ generate-mocks-synchronizer: ## Generates mocks for synchronizer , using mockery rm -Rf ../synchronizer/l2_sync/l2_shared/mocks export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/l2_sync/l2_shared --output ../synchronizer/l2_sync/l2_shared/mocks --outpkg mock_l2_shared ${COMMON_MOCKERY_PARAMS} - rm -Rf ../synchronizer/common/syncinterfaces/mocks export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/common/syncinterfaces --output ../synchronizer/common/syncinterfaces/mocks --outpkg mock_syncinterfaces ${COMMON_MOCKERY_PARAMS} + rm -Rf ../synchronizer/actions/elderberry/mocks + export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --all --case snake --dir ../synchronizer/actions/elderberry --output ../synchronizer/actions/elderberry/mocks --outpkg mock_elderberry ${COMMON_MOCKERY_PARAMS} + + + export "GOROOT=$$(go env GOROOT)" && $$(go env GOPATH)/bin/mockery --name=Tx --srcpkg=github.com/jackc/pgx/v4 --output=../synchronizer/mocks --structname=DbTxMock --filename=mock_dbtx.go .PHONY: generate-mocks-etherman diff --git a/test/config/test.genesis.config.json b/test/config/test.genesis.config.json index 042bd754a9..9744f7b920 100644 --- a/test/config/test.genesis.config.json +++ b/test/config/test.genesis.config.json @@ -6,95 +6,95 @@ "polTokenAddress": "0x5FbDB2315678afecb367f032d93F642f64180aa3", "polygonZkEVMGlobalExitRootAddress": "0x8A791620dd6260079BF849Dc5567aDC3F2FdC318" }, - "genesisBlockNumber": 138, - "root": "0xa64456534f3bbe93f991c0139342a0ef52df95c6999eaa5ec8a69741da407f9a", - "genesis": [ - { - "contractName": "PolygonZkEVMDeployer", - "balance": "0", - "nonce": "4", - "address": "0x51dbd54FCCb6b3A07738fd3E156D588e71f79973", - "bytecode": "0x6080604052600436106100705760003560e01c8063715018a61161004e578063715018a6146100e65780638da5cb5b146100fb578063e11ae6cb14610126578063f2fde38b1461013957600080fd5b80632b79805a146100755780634a94d4871461008a5780636d07dbf81461009d575b600080fd5b610088610083366004610927565b610159565b005b6100886100983660046109c7565b6101cb565b3480156100a957600080fd5b506100bd6100b8366004610a1e565b61020d565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b50610088610220565b34801561010757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100bd565b610088610134366004610a40565b610234565b34801561014557600080fd5b50610088610154366004610a90565b61029b565b610161610357565b600061016e8585856103d8565b905061017a8183610537565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101d3610357565b6101de83838361057b565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b90600090a1505050565b600061021983836105a9565b9392505050565b610228610357565b61023260006105b6565b565b61023c610357565b60006102498484846103d8565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b6102a3610357565b73ffffffffffffffffffffffffffffffffffffffff811661034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610354816105b6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610342565b600083471015610444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610342565b81516000036104af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610342565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610342565b6060610219838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c6564000081525061062b565b60606105a1848484604051806060016040528060298152602001610b3d6029913961062b565b949350505050565b6000610219838330610744565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610342565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106e69190610acf565b60006040518083038185875af1925050503d8060008114610723576040519150601f19603f3d011682016040523d82523d6000602084013e610728565b606091505b50915091506107398783838761076e565b979650505050505050565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156108045782516000036107fd5773ffffffffffffffffffffffffffffffffffffffff85163b6107fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610342565b50816105a1565b6105a183838151156108195781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103429190610aeb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261088d57600080fd5b813567ffffffffffffffff808211156108a8576108a861084d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108ee576108ee61084d565b8160405283815286602085880101111561090757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561093d57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561096357600080fd5b61096f8883890161087c565b9350606087013591508082111561098557600080fd5b506109928782880161087c565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff811681146109c257600080fd5b919050565b6000806000606084860312156109dc57600080fd5b6109e58461099e565b9250602084013567ffffffffffffffff811115610a0157600080fd5b610a0d8682870161087c565b925050604084013590509250925092565b60008060408385031215610a3157600080fd5b50508035926020909101359150565b600080600060608486031215610a5557600080fd5b8335925060208401359150604084013567ffffffffffffffff811115610a7a57600080fd5b610a868682870161087c565b9150509250925092565b600060208284031215610aa257600080fd5b6102198261099e565b60005b83811015610ac6578181015183820152602001610aae565b50506000910152565b60008251610ae1818460208701610aab565b9190910192915050565b6020815260008251806020840152610b0a816040850160208701610aab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220964619cee0e0baf94c6f8763f013be157da5d54c89e5cff4a8caf4266e13f13a64736f6c63430008140033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" - } - }, - { - "contractName": "ProxyAdmin", - "balance": "0", - "nonce": "1", - "address": "0xe34Fe58DDa5b8c6D547E4857E987633aa86a5e90", - "bytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b366004610608565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb36600461062c565b610269565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610694565b6102f7565b34801561014a57600080fd5b506100de61015936600461062c565b61038c565b34801561016a57600080fd5b506100de610179366004610608565b6103e8565b34801561018a57600080fd5b506100a0610199366004610608565b6104a4565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610788565b949350505050565b61025d6104f0565b6102676000610571565b565b6102716104f0565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156102db57600080fd5b505af11580156102ef573d6000803e3d6000fd5b505050505050565b6102ff6104f0565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061035590869086906004016107a5565b6000604051808303818588803b15801561036e57600080fd5b505af1158015610382573d6000803e3d6000fd5b5050505050505050565b6103946104f0565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102c1565b6103f06104f0565b73ffffffffffffffffffffffffffffffffffffffff8116610498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6104a181610571565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048f565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146104a157600080fd5b60006020828403121561061a57600080fd5b8135610625816105e6565b9392505050565b6000806040838503121561063f57600080fd5b823561064a816105e6565b9150602083013561065a816105e6565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156106a957600080fd5b83356106b4816105e6565b925060208401356106c4816105e6565b9150604084013567ffffffffffffffff808211156106e157600080fd5b818601915086601f8301126106f557600080fd5b81358181111561070757610707610665565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074d5761074d610665565b8160405282815289602084870101111561076657600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079a57600080fd5b8151610625816105e6565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156107ef578581018301518582016060015282016107d3565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea2646970667358221220c9867ffac53151bdb1305d8f5e3e883cd83e5270c7ec09cdc24e837b2e65239064736f6c63430008140033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f" - } - }, - { - "contractName": "PolygonZkEVMBridge implementation", - "balance": "0", - "nonce": "1", - "address": "0x12864938EADb26501034339667CabFB3d7045CD2", - "bytecode": "0x608060405260043610620001ff5760003560e01c806383f244031162000117578063ccaa2d1111620000a1578063ee25560b116200006c578063ee25560b1462000639578063f5efcd79146200066a578063f811bff7146200068f578063fb57083414620006b457600080fd5b8063ccaa2d1114620005ba578063cd58657914620005df578063d02103ca14620005f6578063dbc16976146200062157600080fd5b8063bab161bf11620000e2578063bab161bf1462000526578063be5831c7146200054a578063c00f14ab1462000570578063cc461632146200059557600080fd5b806383f2440314620004955780638ed7e3f214620004ba578063aaa13cc214620004dc578063b8b284d0146200050157600080fd5b80633c351e1011620001995780635ca1e16511620001645780635ca1e16514620004065780637843298b146200041e57806379e2cf97146200044357806381b1c174146200045b57600080fd5b80633c351e1014620003615780633cbc795b14620003835780633e19704314620003bf5780634b2f336d14620003e457600080fd5b8063240ff37811620001da578063240ff378146200028d57806327aef4e814620002a45780632dfdf0b514620002cb578063318aee3d14620002f257600080fd5b806315064c9614620002045780632072f6c5146200023557806322e95f2c146200024f575b600080fd5b3480156200021157600080fd5b50606854620002209060ff1681565b60405190151581526020015b60405180910390f35b3480156200024257600080fd5b506200024d620006d9565b005b3480156200025c57600080fd5b50620002746200026e366004620031fd565b62000711565b6040516001600160a01b0390911681526020016200022c565b6200024d6200029e36600462003294565b6200077c565b348015620002b157600080fd5b50620002bc6200080a565b6040516200022c91906200336c565b348015620002d857600080fd5b50620002e360535481565b6040519081526020016200022c565b348015620002ff57600080fd5b506200033c6200031136600462003388565b606b6020526000908152604090205463ffffffff81169064010000000090046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b039091166020830152016200022c565b3480156200036e57600080fd5b50606d5462000274906001600160a01b031681565b3480156200039057600080fd5b50606d54620003a990600160a01b900463ffffffff1681565b60405163ffffffff90911681526020016200022c565b348015620003cc57600080fd5b50620002e3620003de366004620033b8565b620008a0565b348015620003f157600080fd5b50606f5462000274906001600160a01b031681565b3480156200041357600080fd5b50620002e36200094a565b3480156200042b57600080fd5b50620002746200043d36600462003442565b62000a30565b3480156200045057600080fd5b506200024d62000a61565b3480156200046857600080fd5b50620002746200047a36600462003492565b606a602052600090815260409020546001600160a01b031681565b348015620004a257600080fd5b50620002e3620004b4366004620034bf565b62000a85565b348015620004c757600080fd5b50606c5462000274906001600160a01b031681565b348015620004e957600080fd5b5062000274620004fb366004620035de565b62000b69565b3480156200050e57600080fd5b506200024d6200052036600462003687565b62000cb7565b3480156200053357600080fd5b50606854620003a990610100900463ffffffff1681565b3480156200055757600080fd5b50606854620003a990600160c81b900463ffffffff1681565b3480156200057d57600080fd5b50620002bc6200058f36600462003388565b62000d9d565b348015620005a257600080fd5b5062000220620005b436600462003714565b62000dea565b348015620005c757600080fd5b506200024d620005d93660046200374c565b62000e7b565b6200024d620005f036600462003848565b6200140e565b3480156200060357600080fd5b5060685462000274906501000000000090046001600160a01b031681565b3480156200062e57600080fd5b506200024d620018c2565b3480156200064657600080fd5b50620002e36200065836600462003492565b60696020526000908152604090205481565b3480156200067757600080fd5b506200024d620006893660046200374c565b620018f8565b3480156200069c57600080fd5b506200024d620006ae366004620038ea565b62001be2565b348015620006c157600080fd5b5062000220620006d3366004620039a2565b62001f1b565b606c546001600160a01b031633146200070557604051631736745960e31b815260040160405180910390fd5b6200070f62001f35565b565b6040805160e084901b6001600160e01b031916602080830191909152606084901b6bffffffffffffffffffffffff1916602483015282516018818403018152603890920183528151918101919091206000908152606a90915220546001600160a01b03165b92915050565b60685460ff1615620007a157604051630bc011ff60e21b815260040160405180910390fd5b3415801590620007bb5750606f546001600160a01b031615155b15620007f3576040517f6f625c4000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6200080385853486868662001f92565b5050505050565b606e80546200081990620039ef565b80601f01602080910402602001604051908101604052809291908181526020018280546200084790620039ef565b8015620008985780601f106200086c5761010080835404028352916020019162000898565b820191906000526020600020905b8154815290600101906020018083116200087a57829003601f168201915b505050505081565b6040517fff0000000000000000000000000000000000000000000000000000000000000060f889901b1660208201526001600160e01b031960e088811b821660218401526bffffffffffffffffffffffff19606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b605354600090819081805b602081101562000a27578083901c600116600103620009b8576033816020811062000984576200098462003a2b565b01546040805160208101929092528101859052606001604051602081830303815290604052805190602001209350620009e5565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b6040805160208101849052908101839052606001604051602081830303815290604052805190602001209150808062000a1e9062003a57565b91505062000955565b50919392505050565b600062000a59848462000a438562002066565b62000a4e866200215c565b620004fb8762002247565b949350505050565b605354606854600160c81b900463ffffffff1610156200070f576200070f62002321565b600083815b602081101562000b6057600163ffffffff8516821c8116900362000afc5784816020811062000abd5762000abd62003a2b565b60200201358260405160200162000ade929190918252602082015260400190565b60405160208183030381529060405280519060200120915062000b4b565b8185826020811062000b125762000b1262003a2b565b602002013560405160200162000b32929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b8062000b578162003a57565b91505062000a8a565b50949350505050565b6040516001600160e01b031960e087901b1660208201526bffffffffffffffffffffffff19606086901b1660248201526000908190603801604051602081830303815290604052805190602001209050600060ff60f81b30836040518060200162000bd490620031c1565b601f1982820381018352601f90910116604081905262000bfd908b908b908b9060200162003a73565b60408051601f198184030181529082905262000c1d929160200162003ab0565b6040516020818303038152906040528051906020012060405160200162000c9394939291907fff0000000000000000000000000000000000000000000000000000000000000094909416845260609290921b6bffffffffffffffffffffffff191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012098975050505050505050565b60685460ff161562000cdc57604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b031662000d1f576040517fdde3cda700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f54604051632770a7eb60e21b8152336004820152602481018690526001600160a01b0390911690639dc29fac90604401600060405180830381600087803b15801562000d6c57600080fd5b505af115801562000d81573d6000803e3d6000fd5b5050505062000d9586868686868662001f92565b505050505050565b606062000daa8262002066565b62000db5836200215c565b62000dc08462002247565b60405160200162000dd49392919062003a73565b6040516020818303038152906040529050919050565b6068546000908190610100900463ffffffff1615801562000e11575063ffffffff83166001145b1562000e25575063ffffffff831662000e51565b62000e3c64010000000063ffffffff851662003ae3565b62000e4e9063ffffffff861662003afd565b90505b600881901c600090815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff161562000ea057604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff868116610100909204161462000ed1576040516302caf51760e11b815260040160405180910390fd5b62000f0b8c8c8c8c8c62000f0560008e8e8e8e8e8e8e60405162000ef792919062003b13565b6040518091039020620008a0565b620023d9565b6001600160a01b0386166200106a57606f546001600160a01b031662000ffc5760006001600160a01b03851684825b6040519080825280601f01601f19166020018201604052801562000f65576020820181803683370190505b5060405162000f75919062003b23565b60006040518083038185875af1925050503d806000811462000fb4576040519150601f19603f3d011682016040523d82523d6000602084013e62000fb9565b606091505b505090508062000ff5576040517f6747a28800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b50620013a4565b606f546040516340c10f1960e01b81526001600160a01b03868116600483015260248201869052909116906340c10f1990604401600060405180830381600087803b1580156200104b57600080fd5b505af115801562001060573d6000803e3d6000fd5b50505050620013a4565b606d546001600160a01b038781169116148015620010995750606d5463ffffffff888116600160a01b90920416145b15620010b35760006001600160a01b038516848262000f3a565b60685463ffffffff610100909104811690881603620010e857620010e26001600160a01b038716858562002583565b620013a4565b6040516001600160e01b031960e089901b1660208201526bffffffffffffffffffffffff19606088901b16602482015260009060380160408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b0316806200133c5760008080620011678688018862003b41565b9250925092506000858484846040516200118190620031c1565b6200118f9392919062003a73565b8190604051809103906000f5905080158015620011b0573d6000803e3d6000fd5b506040516340c10f1960e01b81526001600160a01b038c81166004830152602482018c9052919250908216906340c10f1990604401600060405180830381600087803b1580156200120057600080fd5b505af115801562001215573d6000803e3d6000fd5b5050505080606a600088815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808e63ffffffff1681526020018d6001600160a01b0316815250606b6000836001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398d8d838b8b6040516200132a95949392919062003be0565b60405180910390a150505050620013a1565b6040516340c10f1960e01b81526001600160a01b038781166004830152602482018790528216906340c10f1990604401600060405180830381600087803b1580156200138757600080fd5b505af11580156200139c573d6000803e3d6000fd5b505050505b50505b604080518b815263ffffffff891660208201526001600160a01b0388811682840152861660608201526080810185905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a1505050505050505050505050565b60685460ff16156200143357604051630bc011ff60e21b815260040160405180910390fd5b6200143d62002606565b60685463ffffffff6101009091048116908816036200146f576040516302caf51760e11b815260040160405180910390fd5b6000806060876001600160a01b0388166200157957883414620014be576040517fb89240f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff16945090620014ed90620039ef565b80601f01602080910402602001604051908101604052809291908181526020018280546200151b90620039ef565b80156200156c5780601f1062001540576101008083540402835291602001916200156c565b820191906000526020600020905b8154815290600101906020018083116200154e57829003601f168201915b505050505091506200182d565b3415620015b2576040517f798ee6f100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b606f546001600160a01b03908116908916036200163157604051632770a7eb60e21b8152336004820152602481018a90526001600160a01b03891690639dc29fac90604401600060405180830381600087803b1580156200161257600080fd5b505af115801562001627573d6000803e3d6000fd5b505050506200182d565b6001600160a01b038089166000908152606b602090815260409182902082518084019093525463ffffffff8116835264010000000090049092169181018290529015620016ee57604051632770a7eb60e21b8152336004820152602481018b90526001600160a01b038a1690639dc29fac90604401600060405180830381600087803b158015620016c157600080fd5b505af1158015620016d6573d6000803e3d6000fd5b5050505080602001519450806000015193506200181e565b8515620017035762001703898b898962002661565b6040516370a0823160e01b81523060048201526000906001600160a01b038b16906370a0823190602401602060405180830381865afa1580156200174b573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062001771919062003c1b565b90506200178a6001600160a01b038b1633308e62002a27565b6040516370a0823160e01b81523060048201526000906001600160a01b038c16906370a0823190602401602060405180830381865afa158015620017d2573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620017f8919062003c1b565b905062001806828262003c35565b6068548c9850610100900463ffffffff169650935050505b620018298962000d9d565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e86886053546040516200186f98979695949392919062003c4b565b60405180910390a16200189a62001894600085878f8f878980519060200120620008a0565b62002a7a565b8615620018ab57620018ab62002321565b50505050620018b960018055565b50505050505050565b606c546001600160a01b03163314620018ee57604051631736745960e31b815260040160405180910390fd5b6200070f62002b92565b60685460ff16156200191d57604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff86811661010090920416146200194e576040516302caf51760e11b815260040160405180910390fd5b620019748c8c8c8c8c62000f0560018e8e8e8e8e8e8e60405162000ef792919062003b13565b606f546000906001600160a01b031662001a3357846001600160a01b031684888a8686604051602401620019ac949392919062003cb7565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b17905251620019e3919062003b23565b60006040518083038185875af1925050503d806000811462001a22576040519150601f19603f3d011682016040523d82523d6000602084013e62001a27565b606091505b50508091505062001b3f565b606f546040516340c10f1960e01b81526001600160a01b03878116600483015260248201879052909116906340c10f1990604401600060405180830381600087803b15801562001a8257600080fd5b505af115801562001a97573d6000803e3d6000fd5b50505050846001600160a01b03168789858560405160240162001abe949392919062003cb7565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525162001af5919062003b23565b6000604051808303816000865af19150503d806000811462001b34576040519150601f19603f3d011682016040523d82523d6000602084013e62001b39565b606091505b50909150505b8062001b77576040517f37e391c300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080518c815263ffffffff8a1660208201526001600160a01b0389811682840152871660608201526080810186905290517f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d9181900360a00190a150505050505050505050505050565b600054610100900460ff161580801562001c035750600054600160ff909116105b8062001c1f5750303b15801562001c1f575060005460ff166001145b62001c975760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a656400000000000000000000000000000000000060648201526084015b60405180910390fd5b6000805460ff19166001179055801562001cbb576000805461ff0019166101001790555b606880547fffffffffffffff000000000000000000000000000000000000000000000000ff1661010063ffffffff8a16027fffffffffffffff0000000000000000000000000000000000000000ffffffffff1617650100000000006001600160a01b038781169190910291909117909155606c805473ffffffffffffffffffffffffffffffffffffffff1916858316179055861662001d995763ffffffff85161562001d93576040517f1a874c1200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b62001ec2565b606d805463ffffffff8716600160a01b027fffffffffffffffff0000000000000000000000000000000000000000000000009091166001600160a01b03891617179055606e62001dea838262003d3c565b506000801b601260405162001dff90620031c1565b6060808252600d908201527f5772617070656420457468657200000000000000000000000000000000000000608082015260a0602082018190526004908201527f574554480000000000000000000000000000000000000000000000000000000060c082015260ff909116604082015260e0018190604051809103906000f590508015801562001e93573d6000803e3d6000fd5b50606f805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b03929092169190911790555b62001ecc62002c04565b8015620018b9576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b60008162001f2b86868662000a85565b1495945050505050565b60685460ff161562001f5a57604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b60685463ffffffff61010090910481169087160362001fc4576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff163389898988886053546040516200201a9998979695949392919062003e09565b60405180910390a162002055620018946001606860019054906101000a900463ffffffff16338a8a8a898960405162000ef792919062003b13565b821562000d955762000d9562002321565b60408051600481526024810182526020810180516001600160e01b03167f06fdde0300000000000000000000000000000000000000000000000000000000179052905160609160009182916001600160a01b03861691620020c8919062003b23565b600060405180830381855afa9150503d806000811462002105576040519150601f19603f3d011682016040523d82523d6000602084013e6200210a565b606091505b50915091508162002151576040518060400160405280600781526020017f4e4f5f4e414d450000000000000000000000000000000000000000000000000081525062000a59565b62000a598162002c7b565b60408051600481526024810182526020810180516001600160e01b03167f95d89b4100000000000000000000000000000000000000000000000000000000179052905160609160009182916001600160a01b03861691620021be919062003b23565b600060405180830381855afa9150503d8060008114620021fb576040519150601f19603f3d011682016040523d82523d6000602084013e62002200565b606091505b50915091508162002151576040518060400160405280600981526020017f4e4f5f53594d424f4c000000000000000000000000000000000000000000000081525062000a59565b60408051600481526024810182526020810180516001600160e01b03167f313ce567000000000000000000000000000000000000000000000000000000001790529051600091829182916001600160a01b03861691620022a8919062003b23565b600060405180830381855afa9150503d8060008114620022e5576040519150601f19603f3d011682016040523d82523d6000602084013e620022ea565b606091505b5091509150818015620022fe575080516020145b6200230b57601262000a59565b8080602001905181019062000a59919062003e77565b6053546068805463ffffffff909216600160c81b027fffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffffff90921691909117908190556001600160a01b0365010000000000909104166333d6247d620023846200094a565b6040518263ffffffff1660e01b8152600401620023a391815260200190565b600060405180830381600087803b158015620023be57600080fd5b505af1158015620023d3573d6000803e3d6000fd5b50505050565b606854604080516020808201879052818301869052825180830384018152606083019384905280519101207f257b36320000000000000000000000000000000000000000000000000000000090925260648101919091526000916501000000000090046001600160a01b03169063257b3632906084016020604051808303816000875af11580156200246f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019062002495919062003c1b565b905080600003620024d1576040517e2f6fad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080680100000000000000008716156200251b57869150620024f7848a848962001f1b565b62002515576040516338105f3b60e21b815260040160405180910390fd5b6200256c565b602087901c6200252d81600162003e97565b91508792506200254c62002543868c8662000a85565b8a838962001f1b565b6200256a576040516338105f3b60e21b815260040160405180910390fd5b505b62002578828262002e6b565b505050505050505050565b6040516001600160a01b038316602482015260448101829052620026019084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915262002f35565b505050565b6002600154036200265a5760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015260640162001c8e565b6002600155565b600062002672600482848662003ebe565b6200267d9162003eea565b90507f2afa5331000000000000000000000000000000000000000000000000000000006001600160e01b031982160162002869576000808080808080620026c8896004818d62003ebe565b810190620026d7919062003f1b565b9650965096509650965096509650336001600160a01b0316876001600160a01b031614620027185760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b0386163014620027425760405163750643af60e01b815260040160405180910390fd5b8a85146200277c576040517f03fffc4b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b03167fd505accf000000000000000000000000000000000000000000000000000000001790529151918e169162002815919062003b23565b6000604051808303816000865af19150503d806000811462002854576040519150601f19603f3d011682016040523d82523d6000602084013e62002859565b606091505b5050505050505050505062000803565b6001600160e01b031981166323f2ebc360e21b14620028b4576040517fe282c0ba00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080808080808080620028cc8a6004818e62003ebe565b810190620028db919062003f76565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146200291e5760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b0387163014620029485760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f1691620029d1919062003b23565b6000604051808303816000865af19150503d806000811462002a10576040519150601f19603f3d011682016040523d82523d6000602084013e62002a15565b606091505b50505050505050505050505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052620023d39085907f23b872dd0000000000000000000000000000000000000000000000000000000090608401620025c9565b80600162002a8b60206002620040ff565b62002a97919062003c35565b6053541062002ad2576040517fef5ccf6600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600060536000815462002ae59062003a57565b9182905550905060005b602081101562002b81578082901c60011660010362002b2757826033826020811062002b1f5762002b1f62003a2b565b015550505050565b6033816020811062002b3d5762002b3d62003a2b565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808062002b789062003a57565b91505062002aef565b50620026016200410d565b60018055565b60685460ff1662002bcf576040517f5386698100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600054610100900460ff1662002c715760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162001c8e565b6200070f62003021565b6060604082511062002c9d578180602001905181019062000776919062004123565b815160200362002e2d5760005b60208110801562002cf5575082818151811062002ccb5762002ccb62003a2b565b01602001517fff000000000000000000000000000000000000000000000000000000000000001615155b1562002d10578062002d078162003a57565b91505062002caa565b8060000362002d5457505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e4700000000000000000000000000006020820152919050565b60008167ffffffffffffffff81111562002d725762002d7262003503565b6040519080825280601f01601f19166020018201604052801562002d9d576020820181803683370190505b50905060005b8281101562002e255784818151811062002dc15762002dc162003a2b565b602001015160f81c60f81b82828151811062002de15762002de162003a2b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508062002e1c8162003a57565b91505062002da3565b509392505050565b505060408051808201909152601281527f4e4f545f56414c49445f454e434f44494e470000000000000000000000000000602082015290565b919050565b606854600090610100900463ffffffff1615801562002e90575063ffffffff82166001145b1562002ea4575063ffffffff821662002ed0565b62002ebb64010000000063ffffffff841662003ae3565b62002ecd9063ffffffff851662003afd565b90505b600881901c60008181526069602052604081208054600160ff861690811b91821892839055929091908183169003620018b9576040517f646cf55800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600062002f8c826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b03166200308e9092919063ffffffff16565b80519091501562002601578080602001905181019062002fad9190620041a3565b620026015760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f74207375636365656400000000000000000000000000000000000000000000606482015260840162001c8e565b600054610100900460ff1662002b8c5760405162461bcd60e51b815260206004820152602b60248201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960448201526a6e697469616c697a696e6760a81b606482015260840162001c8e565b606062000a59848460008585600080866001600160a01b03168587604051620030b8919062003b23565b60006040518083038185875af1925050503d8060008114620030f7576040519150601f19603f3d011682016040523d82523d6000602084013e620030fc565b606091505b50915091506200310f878383876200311a565b979650505050505050565b606083156200318e57825160000362003186576001600160a01b0385163b620031865760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640162001c8e565b508162000a59565b62000a598383815115620031a55781518083602001fd5b8060405162461bcd60e51b815260040162001c8e91906200336c565b6117a780620041c483390190565b803563ffffffff8116811462002e6657600080fd5b6001600160a01b0381168114620031fa57600080fd5b50565b600080604083850312156200321157600080fd5b6200321c83620031cf565b915060208301356200322e81620031e4565b809150509250929050565b8015158114620031fa57600080fd5b60008083601f8401126200325b57600080fd5b50813567ffffffffffffffff8111156200327457600080fd5b6020830191508360208285010111156200328d57600080fd5b9250929050565b600080600080600060808688031215620032ad57600080fd5b620032b886620031cf565b94506020860135620032ca81620031e4565b93506040860135620032dc8162003239565b9250606086013567ffffffffffffffff811115620032f957600080fd5b620033078882890162003248565b969995985093965092949392505050565b60005b83811015620033355781810151838201526020016200331b565b50506000910152565b600081518084526200335881602086016020860162003318565b601f01601f19169290920160200192915050565b6020815260006200338160208301846200333e565b9392505050565b6000602082840312156200339b57600080fd5b81356200338181620031e4565b60ff81168114620031fa57600080fd5b600080600080600080600060e0888a031215620033d457600080fd5b8735620033e181620033a8565b9650620033f160208901620031cf565b955060408801356200340381620031e4565b94506200341360608901620031cf565b935060808801356200342581620031e4565b9699959850939692959460a0840135945060c09093013592915050565b6000806000606084860312156200345857600080fd5b6200346384620031cf565b925060208401356200347581620031e4565b915060408401356200348781620031e4565b809150509250925092565b600060208284031215620034a557600080fd5b5035919050565b8061040081018310156200077657600080fd5b60008060006104408486031215620034d657600080fd5b83359250620034e98560208601620034ac565b9150620034fa6104208501620031cf565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171562003545576200354562003503565b604052919050565b600067ffffffffffffffff8211156200356a576200356a62003503565b50601f01601f191660200190565b60006200358f62003589846200354d565b62003519565b9050828152838383011115620035a457600080fd5b828260208301376000602084830101529392505050565b600082601f830112620035cd57600080fd5b620033818383356020850162003578565b600080600080600060a08688031215620035f757600080fd5b6200360286620031cf565b945060208601356200361481620031e4565b9350604086013567ffffffffffffffff808211156200363257600080fd5b6200364089838a01620035bb565b945060608801359150808211156200365757600080fd5b506200366688828901620035bb565b92505060808601356200367981620033a8565b809150509295509295909350565b60008060008060008060a08789031215620036a157600080fd5b620036ac87620031cf565b95506020870135620036be81620031e4565b9450604087013593506060870135620036d78162003239565b9250608087013567ffffffffffffffff811115620036f457600080fd5b6200370289828a0162003248565b979a9699509497509295939492505050565b600080604083850312156200372857600080fd5b6200373383620031cf565b91506200374360208401620031cf565b90509250929050565b6000806000806000806000806000806000806109208d8f0312156200377057600080fd5b6200377c8e8e620034ac565b9b506200378e8e6104008f01620034ac565b9a506108008d013599506108208d013598506108408d01359750620037b76108608e01620031cf565b9650620037c96108808e0135620031e4565b6108808d01359550620037e06108a08e01620031cf565b9450620037f26108c08e0135620031e4565b6108c08d013593506108e08d0135925067ffffffffffffffff6109008e013511156200381d57600080fd5b620038308e6109008f01358f0162003248565b81935080925050509295989b509295989b509295989b565b600080600080600080600060c0888a0312156200386457600080fd5b6200386f88620031cf565b965060208801356200388181620031e4565b95506040880135945060608801356200389a81620031e4565b93506080880135620038ac8162003239565b925060a088013567ffffffffffffffff811115620038c957600080fd5b620038d78a828b0162003248565b989b979a50959850939692959293505050565b60008060008060008060c087890312156200390457600080fd5b6200390f87620031cf565b955060208701356200392181620031e4565b94506200393160408801620031cf565b935060608701356200394381620031e4565b925060808701356200395581620031e4565b915060a087013567ffffffffffffffff8111156200397257600080fd5b8701601f810189136200398457600080fd5b620039958982356020840162003578565b9150509295509295509295565b6000806000806104608587031215620039ba57600080fd5b84359350620039cd8660208701620034ac565b9250620039de6104208601620031cf565b939692955092936104400135925050565b600181811c9082168062003a0457607f821691505b60208210810362003a2557634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006001820162003a6c5762003a6c62003a41565b5060010190565b60608152600062003a8860608301866200333e565b828103602084015262003a9c81866200333e565b91505060ff83166040830152949350505050565b6000835162003ac481846020880162003318565b83519083019062003ada81836020880162003318565b01949350505050565b808202811582820484141762000776576200077662003a41565b8082018082111562000776576200077662003a41565b8183823760009101908152919050565b6000825162003b3781846020870162003318565b9190910192915050565b60008060006060848603121562003b5757600080fd5b833567ffffffffffffffff8082111562003b7057600080fd5b62003b7e87838801620035bb565b9450602086013591508082111562003b9557600080fd5b5062003ba486828701620035bb565b92505060408401356200348781620033a8565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b63ffffffff8616815260006001600160a01b038087166020840152808616604084015250608060608301526200310f60808301848662003bb7565b60006020828403121562003c2e57600080fd5b5051919050565b8181038181111562000776576200077662003a41565b600061010060ff8b16835263ffffffff808b1660208501526001600160a01b03808b166040860152818a1660608601528089166080860152508660a08501528160c085015262003c9e828501876200333e565b925080851660e085015250509998505050505050505050565b6001600160a01b038516815263ffffffff8416602082015260606040820152600062003ce860608301848662003bb7565b9695505050505050565b601f8211156200260157600081815260208120601f850160051c8101602086101562003d1b5750805b601f850160051c820191505b8181101562000d955782815560010162003d27565b815167ffffffffffffffff81111562003d595762003d5962003503565b62003d718162003d6a8454620039ef565b8462003cf2565b602080601f83116001811462003da9576000841562003d905750858301515b600019600386901b1c1916600185901b17855562000d95565b600085815260208120601f198616915b8281101562003dda5788860151825594840194600190910190840162003db9565b508582101562003df95787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600061010060ff8c16835263ffffffff808c1660208501526001600160a01b03808c166040860152818b166060860152808a166080860152508760a08501528160c085015262003e5d828501878962003bb7565b925080851660e085015250509a9950505050505050505050565b60006020828403121562003e8a57600080fd5b81516200338181620033a8565b63ffffffff81811683821601908082111562003eb75762003eb762003a41565b5092915050565b6000808585111562003ecf57600080fd5b8386111562003edd57600080fd5b5050820193919092039150565b6001600160e01b0319813581811691600485101562003f135780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a03121562003f3757600080fd5b873562003f4481620031e4565b9650602088013562003f5681620031e4565b9550604088013594506060880135935060808801356200342581620033a8565b600080600080600080600080610100898b03121562003f9457600080fd5b883562003fa181620031e4565b9750602089013562003fb381620031e4565b96506040890135955060608901359450608089013562003fd38162003239565b935060a089013562003fe581620033a8565b979a969950949793969295929450505060c08201359160e0013590565b600181815b808511156200404357816000190482111562004027576200402762003a41565b808516156200403557918102915b93841c939080029062004007565b509250929050565b6000826200405c5750600162000776565b816200406b5750600062000776565b81600181146200408457600281146200408f57620040af565b600191505062000776565b60ff841115620040a357620040a362003a41565b50506001821b62000776565b5060208310610133831016604e8410600b8410161715620040d4575081810a62000776565b620040e0838362004002565b8060001904821115620040f757620040f762003a41565b029392505050565b60006200338183836200404b565b634e487b7160e01b600052600160045260246000fd5b6000602082840312156200413657600080fd5b815167ffffffffffffffff8111156200414e57600080fd5b8201601f810184136200416057600080fd5b80516200417162003589826200354d565b8181528560208385010111156200418757600080fd5b6200419a82602083016020860162003318565b95945050505050565b600060208284031215620041b657600080fd5b815162003381816200323956fe6101006040523480156200001257600080fd5b50604051620017a7380380620017a783398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516112eb620004bc60003960006102370152600081816102fa015281816105630152610623015260006104f701526000818161035f01526104c101526112eb6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf14610381578063dd62ed3e14610394578063ffa1ad74146103cd57600080fd5b8063a457c2d714610334578063a9059cbb14610347578063cd0d00961461035a57600080fd5b806395d89b41116100bd57806395d89b41146102da5780639dc29fac146102e2578063a3c573eb146102f557600080fd5b806370a08231146102915780637ecebe00146102ba57600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b6101846103ed565b60405161019191906110a1565b60405180910390f35b6101ad6101a836600461110b565b61047f565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad610204366004611135565b610499565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c16104bd565b6101ad61027736600461110b565b610519565b61028f61028a36600461110b565b610558565b005b6101c161029f366004611171565b6001600160a01b031660009081526020819052604090205490565b6101c16102c8366004611171565b60056020526000908152604090205481565b610184610609565b61028f6102f036600461110b565b610618565b61031c7f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b039091168152602001610191565b6101ad61034236600461110b565b6106c0565b6101ad61035536600461110b565b61076a565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f61038f366004611193565b610778565b6101c16103a2366004611206565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b610184604051806040016040528060018152602001603160f81b81525081565b6060600380546103fc90611239565b80601f016020809104026020016040519081016040528092919081815260200182805461042890611239565b80156104755780601f1061044a57610100808354040283529160200191610475565b820191906000526020600020905b81548152906001019060200180831161045857829003601f168201915b5050505050905090565b60003361048d8185856109fd565b60019150505b92915050565b6000336104a7858285610b56565b6104b2858585610be8565b506001949350505050565b60007f000000000000000000000000000000000000000000000000000000000000000046146104f4576104ef46610dd5565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b3360008181526001602090815260408083206001600160a01b038716845290915281205490919061048d9082908690610553908790611289565b6109fd565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146105fb5760405162461bcd60e51b815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b6106058282610e81565b5050565b6060600480546103fc90611239565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146106b65760405162461bcd60e51b815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084016105f2565b6106058282610f40565b3360008181526001602090815260408083206001600160a01b03871684529091528120549091908381101561075d5760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f00000000000000000000000000000000000000000000000000000060648201526084016105f2565b6104b282868684036109fd565b60003361048d818585610be8565b834211156107ed5760405162461bcd60e51b8152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d69740000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6001600160a01b038716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a91908661083a8361129c565b909155506040805160208101969096526001600160a01b0394851690860152929091166060840152608083015260a082015260c0810186905260e00160405160208183030381529060405280519060200120905060006108986104bd565b6040517f1901000000000000000000000000000000000000000000000000000000000000602082015260228101919091526042810183905260620160408051601f198184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa15801561093e573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b038116158015906109745750896001600160a01b0316816001600160a01b0316145b6109e65760405162461bcd60e51b815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e61747572650000000000000000000000000000000000000000000000000060648201526084016105f2565b6109f18a8a8a6109fd565b50505050505050505050565b6001600160a01b038316610a785760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6001600160a01b038216610af45760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f737300000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6001600160a01b0383811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b6001600160a01b038381166000908152600160209081526040808320938616835292905220546000198114610be25781811015610bd55760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016105f2565b610be284848484036109fd565b50505050565b6001600160a01b038316610c645760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f647265737300000000000000000000000000000000000000000000000000000060648201526084016105f2565b6001600160a01b038216610ce05760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f657373000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6001600160a01b03831660009081526020819052604090205481811015610d6f5760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e6365000000000000000000000000000000000000000000000000000060648201526084016105f2565b6001600160a01b03848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610be2565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f610e006103ed565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6001600160a01b038216610ed75760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064016105f2565b8060026000828254610ee99190611289565b90915550506001600160a01b038216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b6001600160a01b038216610fbc5760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f730000000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6001600160a01b0382166000908152602081905260409020548181101561104b5760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f636500000000000000000000000000000000000000000000000000000000000060648201526084016105f2565b6001600160a01b0383166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610b49565b600060208083528351808285015260005b818110156110ce578581018301518582016040015282016110b2565b506000604082860101526040601f19601f8301168501019250505092915050565b80356001600160a01b038116811461110657600080fd5b919050565b6000806040838503121561111e57600080fd5b611127836110ef565b946020939093013593505050565b60008060006060848603121561114a57600080fd5b611153846110ef565b9250611161602085016110ef565b9150604084013590509250925092565b60006020828403121561118357600080fd5b61118c826110ef565b9392505050565b600080600080600080600060e0888a0312156111ae57600080fd5b6111b7886110ef565b96506111c5602089016110ef565b95506040880135945060608801359350608088013560ff811681146111e957600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561121957600080fd5b611222836110ef565b9150611230602084016110ef565b90509250929050565b600181811c9082168061124d57607f821691505b60208210810361126d57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b8082018082111561049357610493611273565b6000600182016112ae576112ae611273565b506001019056fea2646970667358221220aee05225eb578ca4601af39623d6cec4d7df11fc43f9c71ce59466ac2db4e37864736f6c63430008140033a26469706673582212202371b7d4c0384f70a2b904847ca70da52a1432c9a54bc07a292aeb4703fc816864736f6c63430008140033" - }, - { - "contractName": "PolygonZkEVMBridge proxy", - "balance": "340282366920938463463374607431768211455", - "nonce": "1", - "address": "0xCca6ECD73932e49633B9307e1aa0fC174525F424", - "bytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461086f565b610135565b61006b6100a336600461088a565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461086f565b610231565b34801561011257600080fd5b506100bd61025e565b61012361028c565b61013361012e610363565b61036d565b565b61013d610391565b73ffffffffffffffffffffffffffffffffffffffff16330361017757610174816040518060200160405280600081525060006103d1565b50565b61017461011b565b610187610391565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103d1915050565b505050565b6101e661011b565b60006101fd610391565b73ffffffffffffffffffffffffffffffffffffffff16330361022657610221610363565b905090565b61022e61011b565b90565b610239610391565b73ffffffffffffffffffffffffffffffffffffffff16330361017757610174816103fc565b6000610268610391565b73ffffffffffffffffffffffffffffffffffffffff16330361022657610221610391565b610294610391565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b600061022161045d565b3660008037600080366000845af43d6000803e80801561038c573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103da83610485565b6000825111806103e75750805b156101e6576103f683836104d2565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610425610391565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a1610174816104fe565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103b5565b61048e8161060a565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606104f7838360405180606001604052806027815260200161099f602791396106d5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81166105a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161035a565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b6106ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161035a565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105c4565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516106ff9190610931565b600060405180830381855af49150503d806000811461073a576040519150601f19603f3d011682016040523d82523d6000602084013e61073f565b606091505b50915091506107508683838761075a565b9695505050505050565b606083156107f05782516000036107e95773ffffffffffffffffffffffffffffffffffffffff85163b6107e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161035a565b50816107fa565b6107fa8383610802565b949350505050565b8151156108125781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035a919061094d565b803573ffffffffffffffffffffffffffffffffffffffff8116811461086a57600080fd5b919050565b60006020828403121561088157600080fd5b6104f782610846565b60008060006040848603121561089f57600080fd5b6108a884610846565b9250602084013567ffffffffffffffff808211156108c557600080fd5b818601915086601f8301126108d957600080fd5b8135818111156108e857600080fd5b8760208285010111156108fa57600080fd5b6020830194508093505050509250925092565b60005b83811015610928578181015183820152602001610910565b50506000910152565b6000825161094381846020870161090d565b9190910192915050565b602081526000825180602084015261096c81604085016020870161090d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220701a0c26bdd76686e63fc3c65e4f28a20ba3ecc8a60246733c0627e679c9804e64736f6c63430008140033", - "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x000000000000000000000000e34fe58dda5b8c6d547e4857e987633aa86a5e90", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x00000000000000000000000012864938eadb26501034339667cabfb3d7045cd2" - } - }, - { - "contractName": "PolygonZkEVMGlobalExitRootL2 implementation", - "balance": "0", - "nonce": "1", - "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", - "bytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806301fd904414610051578063257b36321461006d57806333d6247d1461008d578063a3c573eb146100a2575b600080fd5b61005a60015481565b6040519081526020015b60405180910390f35b61005a61007b366004610162565b60006020819052908152604090205481565b6100a061009b366004610162565b6100ee565b005b6100c97f000000000000000000000000cca6ecd73932e49633b9307e1aa0fc174525f42481565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610064565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000cca6ecd73932e49633b9307e1aa0fc174525f424161461015d576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b60006020828403121561017457600080fd5b503591905056fea2646970667358221220ea2171e2c85c8bff947affc409ef6fc6a8fe82fb8c174ddeda988651e595d66564736f6c63430008140033" - }, - { - "contractName": "PolygonZkEVMGlobalExitRootL2 proxy", - "balance": "0", - "nonce": "1", - "address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa", - "bytecode": "0x60806040523661001357610011610017565b005b6100115b61001f6101b7565b6001600160a01b0316336001600160a01b0316141561016f5760606001600160e01b031960003516631b2ce7f360e11b8114156100655761005e6101ea565b9150610167565b6001600160e01b0319811663278f794360e11b14156100865761005e610241565b6001600160e01b031981166308f2839760e41b14156100a75761005e610287565b6001600160e01b031981166303e1469160e61b14156100c85761005e6102b8565b6001600160e01b03198116635c60da1b60e01b14156100e95761005e6102f8565b60405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b815160208301f35b61017761030c565b565b606061019e83836040518060600160405280602781526020016108576027913961031c565b9392505050565b90565b6001600160a01b03163b151590565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b60606101f4610394565b600061020336600481846106a2565b81019061021091906106e8565b905061022d8160405180602001604052806000815250600061039f565b505060408051602081019091526000815290565b606060008061025336600481846106a2565b8101906102609190610719565b915091506102708282600161039f565b604051806020016040528060008152509250505090565b6060610291610394565b60006102a036600481846106a2565b8101906102ad91906106e8565b905061022d816103cb565b60606102c2610394565b60006102cc6101b7565b604080516001600160a01b03831660208201529192500160405160208183030381529060405291505090565b6060610302610394565b60006102cc610422565b610177610317610422565b610431565b6060600080856001600160a01b0316856040516103399190610807565b600060405180830381855af49150503d8060008114610374576040519150601f19603f3d011682016040523d82523d6000602084013e610379565b606091505b509150915061038a86838387610455565b9695505050505050565b341561017757600080fd5b6103a8836104d3565b6000825111806103b55750805b156103c6576103c48383610179565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103f46101b7565b604080516001600160a01b03928316815291841660208301520160405180910390a161041f81610513565b50565b600061042c6105bc565b905090565b3660008037600080366000845af43d6000803e808015610450573d6000f35b3d6000fd5b606083156104c15782516104ba576001600160a01b0385163b6104ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161015e565b50816104cb565b6104cb83836105e4565b949350505050565b6104dc8161060e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105785760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840161015e565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6101db565b8151156105f45781518083602001fd5b8060405162461bcd60e51b815260040161015e9190610823565b6001600160a01b0381163b61067b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161015e565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61059b565b600080858511156106b257600080fd5b838611156106bf57600080fd5b5050820193919092039150565b80356001600160a01b03811681146106e357600080fd5b919050565b6000602082840312156106fa57600080fd5b61019e826106cc565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561072c57600080fd5b610735836106cc565b9150602083013567ffffffffffffffff8082111561075257600080fd5b818501915085601f83011261076657600080fd5b81358181111561077857610778610703565b604051601f8201601f19908116603f011681019083821181831017156107a0576107a0610703565b816040528281528860208487010111156107b957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60005b838110156107f65781810151838201526020016107de565b838111156103c45750506000910152565b600082516108198184602087016107db565b9190910192915050565b60208152600082518060208401526108428160408501602087016107db565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122012bb4f564f73959a03513dc74fc3c6e40e8386e6f02c16b78d6db00ce0aa16af64736f6c63430008090033", - "storage": { - "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x000000000000000000000000e34fe58dda5b8c6d547e4857e987633aa86a5e90", - "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c9" - } - }, - { - "contractName": "PolygonZkEVMTimelock", - "balance": "0", - "nonce": "1", - "address": "0x0165878A594ca255338adfa4d48449f69242Eb8F", - "bytecode": "0x6080604052600436106101c65760003560e01c806364d62353116100f7578063b1c5f42711610095578063d547741f11610064578063d547741f14610661578063e38335e514610681578063f23a6e6114610694578063f27a0c92146106d957600080fd5b8063b1c5f427146105af578063bc197c81146105cf578063c4d252f514610614578063d45c44351461063457600080fd5b80638f61f4f5116100d15780638f61f4f5146104e157806391d1485414610515578063a217fddf14610566578063b08e51c01461057b57600080fd5b806364d62353146104815780638065657f146104a15780638f2a0bb0146104c157600080fd5b8063248a9ca31161016457806331d507501161013e57806331d50750146103c857806336568abe146103e85780633a6aae7214610408578063584b153e1461046157600080fd5b8063248a9ca3146103475780632ab0f529146103775780632f2ff15d146103a857600080fd5b80630d3cf6fc116101a05780630d3cf6fc1461026b578063134008d31461029f57806313bc9f20146102b2578063150b7a02146102d257600080fd5b806301d5062a146101d257806301ffc9a7146101f457806307bd02651461022957600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506101f26101ed366004611c52565b6106ee565b005b34801561020057600080fd5b5061021461020f366004611cc7565b610783565b60405190151581526020015b60405180910390f35b34801561023557600080fd5b5061025d7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610220565b34801561027757600080fd5b5061025d7f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101f26102ad366004611d09565b6107df565b3480156102be57600080fd5b506102146102cd366004611d75565b6108d7565b3480156102de57600080fd5b506103166102ed366004611e9a565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610220565b34801561035357600080fd5b5061025d610362366004611d75565b60009081526020819052604090206001015490565b34801561038357600080fd5b50610214610392366004611d75565b6000908152600160208190526040909120541490565b3480156103b457600080fd5b506101f26103c3366004611f02565b6108fd565b3480156103d457600080fd5b506102146103e3366004611d75565b610927565b3480156103f457600080fd5b506101f2610403366004611f02565b610940565b34801561041457600080fd5b5061043c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610220565b34801561046d57600080fd5b5061021461047c366004611d75565b6109f8565b34801561048d57600080fd5b506101f261049c366004611d75565b610a0e565b3480156104ad57600080fd5b5061025d6104bc366004611d09565b610ade565b3480156104cd57600080fd5b506101f26104dc366004611f73565b610b1d565b3480156104ed57600080fd5b5061025d7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b34801561052157600080fd5b50610214610530366004611f02565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561057257600080fd5b5061025d600081565b34801561058757600080fd5b5061025d7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b3480156105bb57600080fd5b5061025d6105ca366004612025565b610d4f565b3480156105db57600080fd5b506103166105ea36600461214e565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b34801561062057600080fd5b506101f261062f366004611d75565b610d94565b34801561064057600080fd5b5061025d61064f366004611d75565b60009081526001602052604090205490565b34801561066d57600080fd5b506101f261067c366004611f02565b610e8f565b6101f261068f366004612025565b610eb4565b3480156106a057600080fd5b506103166106af3660046121f8565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106e557600080fd5b5061025d611161565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc161071881611244565b6000610728898989898989610ade565b90506107348184611251565b6000817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a604051610770969594939291906122a6565b60405180910390a3505050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107d957506107d98261139e565b92915050565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661085c5761085c8133611435565b600061086c888888888888610ade565b905061087881856114ed565b6108848888888861162a565b6000817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a6040516108bc94939291906122f1565b60405180910390a36108cd8161172e565b5050505050505050565b6000818152600160205260408120546001811180156108f65750428111155b9392505050565b60008281526020819052604090206001015461091881611244565b61092283836117d7565b505050565b60008181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109f482826118c7565b5050565b6000818152600160208190526040822054610939565b333014610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109e1565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b6000868686868686604051602001610afb969594939291906122a6565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b4781611244565b888714610bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b888514610c65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b6000610c778b8b8b8b8b8b8b8b610d4f565b9050610c838184611251565b60005b8a811015610d415780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610cc357610cc3612331565b9050602002016020810190610cd89190612360565b8d8d86818110610cea57610cea612331565b905060200201358c8c87818110610d0357610d03612331565b9050602002810190610d15919061237b565b8c8b604051610d29969594939291906122a6565b60405180910390a3610d3a8161240f565b9050610c86565b505050505050505050505050565b60008888888888888888604051602001610d709897969594939291906124f7565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610dbe81611244565b610dc7826109f8565b610e53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109e1565b6000828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b600082815260208190526040902060010154610eaa81611244565b61092283836118c7565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610f3157610f318133611435565b878614610fc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b87841461104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b60006110618a8a8a8a8a8a8a8a610d4f565b905061106d81856114ed565b60005b8981101561114b5760008b8b8381811061108c5761108c612331565b90506020020160208101906110a19190612360565b905060008a8a848181106110b7576110b7612331565b9050602002013590503660008a8a868181106110d5576110d5612331565b90506020028101906110e7919061237b565b915091506110f78484848461162a565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588686868660405161112e94939291906122f1565b60405180910390a350505050806111449061240f565b9050611070565b506111558161172e565b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580159061123257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123291906125be565b1561123d5750600090565b5060025490565b61124e8133611435565b50565b61125a82610927565b156112e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109e1565b6112ef611161565b81101561137e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109e1565b61138881426125e0565b6000928352600160205260409092209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107d957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107d9565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f4576114738161197e565b61147e83602061199d565b60405160200161148f929190612617565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109e191600401612698565b6114f6826108d7565b611582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b80158061159e5750600081815260016020819052604090912054145b6109f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109e1565b60008473ffffffffffffffffffffffffffffffffffffffff168484846040516116549291906126e9565b60006040518083038185875af1925050503d8060008114611691576040519150601f19603f3d011682016040523d82523d6000602084013e611696565b606091505b5050905080611727576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109e1565b5050505050565b611737816108d7565b6117c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b600090815260016020819052604090912055565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556118693390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107d973ffffffffffffffffffffffffffffffffffffffff831660145b606060006119ac8360026126f9565b6119b79060026125e0565b67ffffffffffffffff8111156119cf576119cf611d8e565b6040519080825280601f01601f1916602001820160405280156119f9576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611a3057611a30612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a9357611a93612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611acf8460026126f9565b611ada9060016125e0565b90505b6001811115611b77577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611b1b57611b1b612331565b1a60f81b828281518110611b3157611b31612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611b7081612710565b9050611add565b5083156108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109e1565b803573ffffffffffffffffffffffffffffffffffffffff81168114611c0457600080fd5b919050565b60008083601f840112611c1b57600080fd5b50813567ffffffffffffffff811115611c3357600080fd5b602083019150836020828501011115611c4b57600080fd5b9250929050565b600080600080600080600060c0888a031215611c6d57600080fd5b611c7688611be0565b965060208801359550604088013567ffffffffffffffff811115611c9957600080fd5b611ca58a828b01611c09565b989b979a50986060810135976080820135975060a09091013595509350505050565b600060208284031215611cd957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108f657600080fd5b60008060008060008060a08789031215611d2257600080fd5b611d2b87611be0565b955060208701359450604087013567ffffffffffffffff811115611d4e57600080fd5b611d5a89828a01611c09565b979a9699509760608101359660809091013595509350505050565b600060208284031215611d8757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e0457611e04611d8e565b604052919050565b600082601f830112611e1d57600080fd5b813567ffffffffffffffff811115611e3757611e37611d8e565b611e6860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611dbd565b818152846020838601011115611e7d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611eb057600080fd5b611eb985611be0565b9350611ec760208601611be0565b925060408501359150606085013567ffffffffffffffff811115611eea57600080fd5b611ef687828801611e0c565b91505092959194509250565b60008060408385031215611f1557600080fd5b82359150611f2560208401611be0565b90509250929050565b60008083601f840112611f4057600080fd5b50813567ffffffffffffffff811115611f5857600080fd5b6020830191508360208260051b8501011115611c4b57600080fd5b600080600080600080600080600060c08a8c031215611f9157600080fd5b893567ffffffffffffffff80821115611fa957600080fd5b611fb58d838e01611f2e565b909b50995060208c0135915080821115611fce57600080fd5b611fda8d838e01611f2e565b909950975060408c0135915080821115611ff357600080fd5b506120008c828d01611f2e565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b60008060008060008060008060a0898b03121561204157600080fd5b883567ffffffffffffffff8082111561205957600080fd5b6120658c838d01611f2e565b909a50985060208b013591508082111561207e57600080fd5b61208a8c838d01611f2e565b909850965060408b01359150808211156120a357600080fd5b506120b08b828c01611f2e565b999c989b509699959896976060870135966080013595509350505050565b600082601f8301126120df57600080fd5b8135602067ffffffffffffffff8211156120fb576120fb611d8e565b8160051b61210a828201611dbd565b928352848101820192828101908785111561212457600080fd5b83870192505b848310156121435782358252918301919083019061212a565b979650505050505050565b600080600080600060a0868803121561216657600080fd5b61216f86611be0565b945061217d60208701611be0565b9350604086013567ffffffffffffffff8082111561219a57600080fd5b6121a689838a016120ce565b945060608801359150808211156121bc57600080fd5b6121c889838a016120ce565b935060808801359150808211156121de57600080fd5b506121eb88828901611e0c565b9150509295509295909350565b600080600080600060a0868803121561221057600080fd5b61221986611be0565b945061222760208701611be0565b93506040860135925060608601359150608086013567ffffffffffffffff81111561225157600080fd5b6121eb88828901611e0c565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a0604082015260006122dc60a08301868861225d565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260606040820152600061232760608301848661225d565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561237257600080fd5b6108f682611be0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126123b057600080fd5b83018035915067ffffffffffffffff8211156123cb57600080fd5b602001915036819003821315611c4b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612440576124406123e0565b5060010190565b81835260006020808501808196508560051b810191508460005b878110156124ea57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126124a057600080fd5b8701858101903567ffffffffffffffff8111156124bc57600080fd5b8036038213156124cb57600080fd5b6124d686828461225d565b9a87019a9550505090840190600101612461565b5091979650505050505050565b60a0808252810188905260008960c08301825b8b8110156125455773ffffffffffffffffffffffffffffffffffffffff61253084611be0565b1682526020928301929091019060010161250a565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff89111561257e57600080fd5b8860051b9150818a602083013701828103602090810160408501526125a69082018789612447565b60608401959095525050608001529695505050505050565b6000602082840312156125d057600080fd5b815180151581146108f657600080fd5b808201808211156107d9576107d96123e0565b60005b8381101561260e5781810151838201526020016125f6565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161264f8160178501602088016125f3565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835161268c8160288401602088016125f3565b01602801949350505050565b60208152600082518060208401526126b78160408501602087016125f3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b8183823760009101908152919050565b80820281158282048414176107d9576107d96123e0565b60008161271f5761271f6123e0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea264697066735822122048ac459f9165e9eaa91bead23625fe941931ad2332a61820c2a6d1dcd92c218164736f6c63430008140033", - "storage": { - "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000e10", - "0xaedcc9e7897c0d335bdc5d92fe3a8b4f23727fe558cd1c19f332b28716a30559": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xf5e61edb9c9cc6bfbae4463e9a2b1dd6ac3b44ddef38f18016e56ba0363910d9": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", - "0x60b9d94c75b7b3f721925089391e4644cd890cb5e6466f9596dfbd2c54e0b280": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", - "0x4b63b79f1e338a49559dcd3193ac9eecc50d0f275d24e97cc8c319e5a31a8bd0": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", - "0x800d5dfe4bba53eedee06cd4546a27da8de00f12db83f56062976d4493fda899": "0x0000000000000000000000000000000000000000000000000000000000000001", - "0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5" - } - }, - { - "accountName": "keyless Deployer", - "balance": "0", - "nonce": "1", - "address": "0x28BB4e66addE1f042B77E04cf7D3784C1dcDBbA3" - }, - { - "accountName": "deployer", - "balance": "100000000000000000000000", - "nonce": "8", - "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" - } - ] -} \ No newline at end of file + "genesisBlockNumber": 67, + "root": "0xcc9ec17819f4ac7f282949ca8c379c4d3ee1b8b7908c51b9b405b6319af67b32", + "genesis": [ + { + "contractName": "PolygonZkEVMDeployer", + "balance": "0", + "nonce": "4", + "address": "0x51dbd54FCCb6b3A07738fd3E156D588e71f79973", + "bytecode": "0x6080604052600436106100705760003560e01c8063715018a61161004e578063715018a6146100e65780638da5cb5b146100fb578063e11ae6cb14610126578063f2fde38b1461013957600080fd5b80632b79805a146100755780634a94d4871461008a5780636d07dbf81461009d575b600080fd5b610088610083366004610927565b610159565b005b6100886100983660046109c7565b6101cb565b3480156100a957600080fd5b506100bd6100b8366004610a1e565b61020d565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b50610088610220565b34801561010757600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100bd565b610088610134366004610a40565b610234565b34801561014557600080fd5b50610088610154366004610a90565b61029b565b610161610357565b600061016e8585856103d8565b905061017a8183610537565b5060405173ffffffffffffffffffffffffffffffffffffffff821681527fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a15050505050565b6101d3610357565b6101de83838361057b565b506040517f25adb19089b6a549831a273acdf7908cff8b7ee5f551f8d1d37996cf01c5df5b90600090a1505050565b600061021983836105a9565b9392505050565b610228610357565b61023260006105b6565b565b61023c610357565b60006102498484846103d8565b60405173ffffffffffffffffffffffffffffffffffffffff821681529091507fba82f25fed02cd2a23d9f5d11c2ef588d22af5437cbf23bfe61d87257c480e4c9060200160405180910390a150505050565b6102a3610357565b73ffffffffffffffffffffffffffffffffffffffff811661034b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b610354816105b6565b50565b60005473ffffffffffffffffffffffffffffffffffffffff163314610232576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610342565b600083471015610444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f437265617465323a20696e73756666696369656e742062616c616e63650000006044820152606401610342565b81516000036104af576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f437265617465323a2062797465636f6465206c656e677468206973207a65726f6044820152606401610342565b8282516020840186f5905073ffffffffffffffffffffffffffffffffffffffff8116610219576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f437265617465323a204661696c6564206f6e206465706c6f79000000000000006044820152606401610342565b6060610219838360006040518060400160405280601e81526020017f416464726573733a206c6f772d6c6576656c2063616c6c206661696c6564000081525061062b565b60606105a1848484604051806060016040528060298152602001610b3d6029913961062b565b949350505050565b6000610219838330610744565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6060824710156106bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610342565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516106e69190610acf565b60006040518083038185875af1925050503d8060008114610723576040519150601f19603f3d011682016040523d82523d6000602084013e610728565b606091505b50915091506107398783838761076e565b979650505050505050565b6000604051836040820152846020820152828152600b8101905060ff815360559020949350505050565b606083156108045782516000036107fd5773ffffffffffffffffffffffffffffffffffffffff85163b6107fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610342565b50816105a1565b6105a183838151156108195781518083602001fd5b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016103429190610aeb565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600082601f83011261088d57600080fd5b813567ffffffffffffffff808211156108a8576108a861084d565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156108ee576108ee61084d565b8160405283815286602085880101111561090757600080fd5b836020870160208301376000602085830101528094505050505092915050565b6000806000806080858703121561093d57600080fd5b8435935060208501359250604085013567ffffffffffffffff8082111561096357600080fd5b61096f8883890161087c565b9350606087013591508082111561098557600080fd5b506109928782880161087c565b91505092959194509250565b803573ffffffffffffffffffffffffffffffffffffffff811681146109c257600080fd5b919050565b6000806000606084860312156109dc57600080fd5b6109e58461099e565b9250602084013567ffffffffffffffff811115610a0157600080fd5b610a0d8682870161087c565b925050604084013590509250925092565b60008060408385031215610a3157600080fd5b50508035926020909101359150565b600080600060608486031215610a5557600080fd5b8335925060208401359150604084013567ffffffffffffffff811115610a7a57600080fd5b610a868682870161087c565b9150509250925092565b600060208284031215610aa257600080fd5b6102198261099e565b60005b83811015610ac6578181015183820152602001610aae565b50506000910152565b60008251610ae1818460208701610aab565b9190910192915050565b6020815260008251806020840152610b0a816040850160208701610aab565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a2646970667358221220964619cee0e0baf94c6f8763f013be157da5d54c89e5cff4a8caf4266e13f13a64736f6c63430008140033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x000000000000000000000000f39fd6e51aad88f6f4ce6ab8827279cfffb92266" + } + }, + { + "contractName": "ProxyAdmin", + "balance": "0", + "nonce": "1", + "address": "0xe34Fe58DDa5b8c6D547E4857E987633aa86a5e90", + "bytecode": "0x60806040526004361061007b5760003560e01c80639623609d1161004e5780639623609d1461012b57806399a88ec41461013e578063f2fde38b1461015e578063f3b7dead1461017e57600080fd5b8063204e1c7a14610080578063715018a6146100c95780637eff275e146100e05780638da5cb5b14610100575b600080fd5b34801561008c57600080fd5b506100a061009b366004610608565b61019e565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100d557600080fd5b506100de610255565b005b3480156100ec57600080fd5b506100de6100fb36600461062c565b610269565b34801561010c57600080fd5b5060005473ffffffffffffffffffffffffffffffffffffffff166100a0565b6100de610139366004610694565b6102f7565b34801561014a57600080fd5b506100de61015936600461062c565b61038c565b34801561016a57600080fd5b506100de610179366004610608565b6103e8565b34801561018a57600080fd5b506100a0610199366004610608565b6104a4565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907f5c60da1b00000000000000000000000000000000000000000000000000000000815260040190565b600060405180830381855afa9150503d8060008114610225576040519150601f19603f3d011682016040523d82523d6000602084013e61022a565b606091505b50915091508161023957600080fd5b8080602001905181019061024d9190610788565b949350505050565b61025d6104f0565b6102676000610571565b565b6102716104f0565b6040517f8f28397000000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690638f283970906024015b600060405180830381600087803b1580156102db57600080fd5b505af11580156102ef573d6000803e3d6000fd5b505050505050565b6102ff6104f0565b6040517f4f1ef28600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff841690634f1ef28690349061035590869086906004016107a5565b6000604051808303818588803b15801561036e57600080fd5b505af1158015610382573d6000803e3d6000fd5b5050505050505050565b6103946104f0565b6040517f3659cfe600000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff8281166004830152831690633659cfe6906024016102c1565b6103f06104f0565b73ffffffffffffffffffffffffffffffffffffffff8116610498576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084015b60405180910390fd5b6104a181610571565b50565b60008060008373ffffffffffffffffffffffffffffffffffffffff166040516101ea907ff851a44000000000000000000000000000000000000000000000000000000000815260040190565b60005473ffffffffffffffffffffffffffffffffffffffff163314610267576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161048f565b6000805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b73ffffffffffffffffffffffffffffffffffffffff811681146104a157600080fd5b60006020828403121561061a57600080fd5b8135610625816105e6565b9392505050565b6000806040838503121561063f57600080fd5b823561064a816105e6565b9150602083013561065a816105e6565b809150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000806000606084860312156106a957600080fd5b83356106b4816105e6565b925060208401356106c4816105e6565b9150604084013567ffffffffffffffff808211156106e157600080fd5b818601915086601f8301126106f557600080fd5b81358181111561070757610707610665565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561074d5761074d610665565b8160405282815289602084870101111561076657600080fd5b8260208601602083013760006020848301015280955050505050509250925092565b60006020828403121561079a57600080fd5b8151610625816105e6565b73ffffffffffffffffffffffffffffffffffffffff8316815260006020604081840152835180604085015260005b818110156107ef578581018301518582016060015282016107d3565b5060006060828601015260607fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f83011685010192505050939250505056fea2646970667358221220c9867ffac53151bdb1305d8f5e3e883cd83e5270c7ec09cdc24e837b2e65239064736f6c63430008140033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000000": "0x0000000000000000000000000165878a594ca255338adfa4d48449f69242eb8f" + } + }, + { + "contractName": "PolygonZkEVMBridge implementation", + "balance": "0", + "nonce": "1", + "address": "0x493732fB136a380920C390a85fc27d79C7b70756", + "bytecode": "0x6080604052600436106101a35760003560e01c806383f24403116100e2578063ccaa2d1111610085578063ccaa2d1114610511578063cd58657914610531578063d02103ca14610544578063dbc169761461056b578063ee25560b14610580578063f5efcd79146105ad578063f811bff7146105cd578063fb570834146105ed57600080fd5b806383f244031461040b5780638ed7e3f21461042b578063aaa13cc21461044b578063b8b284d01461046b578063bab161bf1461048b578063be5831c7146104ad578063c00f14ab146104d1578063cc461632146104f157600080fd5b80633cbc795b1161014a5780633cbc795b146102fd5780633e197043146103365780634b2f336d146103565780635ca1e165146103765780637843298b1461038b57806379e2cf97146103ab57806381b1c174146103c057806383c43a55146103f657600080fd5b806315064c96146101a85780632072f6c5146101d757806322e95f2c146101ee578063240ff3781461021b57806327aef4e81461022e5780632dfdf0b514610250578063318aee3d146102745780633c351e10146102dd575b600080fd5b3480156101b457600080fd5b506068546101c29060ff1681565b60405190151581526020015b60405180910390f35b3480156101e357600080fd5b506101ec61060d565b005b3480156101fa57600080fd5b5061020e610209366004612b65565b610642565b6040516101ce9190612b9c565b6101ec610229366004612c06565b610693565b34801561023a57600080fd5b50610243610703565b6040516101ce9190612ccf565b34801561025c57600080fd5b5061026660535481565b6040519081526020016101ce565b34801561028057600080fd5b506102b961028f366004612ce9565b606b6020526000908152604090205463ffffffff811690600160201b90046001600160a01b031682565b6040805163ffffffff90931683526001600160a01b039091166020830152016101ce565b3480156102e957600080fd5b50606d5461020e906001600160a01b031681565b34801561030957600080fd5b50606d5461032190600160a01b900463ffffffff1681565b60405163ffffffff90911681526020016101ce565b34801561034257600080fd5b50610266610351366004612d15565b610791565b34801561036257600080fd5b50606f5461020e906001600160a01b031681565b34801561038257600080fd5b5061026661081e565b34801561039757600080fd5b5061020e6103a6366004612d94565b6108fb565b3480156103b757600080fd5b506101ec610925565b3480156103cc57600080fd5b5061020e6103db366004612ddd565b606a602052600090815260409020546001600160a01b031681565b34801561040257600080fd5b50610243610946565b34801561041757600080fd5b50610266610426366004612e08565b610965565b34801561043757600080fd5b50606c5461020e906001600160a01b031681565b34801561045757600080fd5b5061020e610466366004612f12565b610a3b565b34801561047757600080fd5b506101ec610486366004612fad565b610b3d565b34801561049757600080fd5b5060685461032190610100900463ffffffff1681565b3480156104b957600080fd5b5060685461032190600160c81b900463ffffffff1681565b3480156104dd57600080fd5b506102436104ec366004612ce9565b610c04565b3480156104fd57600080fd5b506101c261050c36600461302f565b610c49565b34801561051d57600080fd5b506101ec61052c366004613062565b610cd2565b6101ec61053f36600461314d565b6111c7565b34801561055057600080fd5b5060685461020e90600160281b90046001600160a01b031681565b34801561057757600080fd5b506101ec611621565b34801561058c57600080fd5b5061026661059b366004612ddd565b60696020526000908152604090205481565b3480156105b957600080fd5b506101ec6105c8366004613062565b611654565b3480156105d957600080fd5b506101ec6105e83660046131e2565b6118ef565b3480156105f957600080fd5b506101c261060836600461328a565b611b62565b606c546001600160a01b0316331461063857604051631736745960e31b815260040160405180910390fd5b610640611b7a565b565b6000606a6000848460405160200161065b9291906132d2565b60408051601f19818403018152918152815160209283012083529082019290925201600020546001600160a01b031690505b92915050565b60685460ff16156106b757604051630bc011ff60e21b815260040160405180910390fd5b34158015906106d05750606f546001600160a01b031615155b156106ee576040516301bd897160e61b815260040160405180910390fd5b6106fc858534868686611bd6565b5050505050565b606e8054610710906132fc565b80601f016020809104026020016040519081016040528092919081815260200182805461073c906132fc565b80156107895780601f1061075e57610100808354040283529160200191610789565b820191906000526020600020905b81548152906001019060200180831161076c57829003601f168201915b505050505081565b6040516001600160f81b031960f889901b1660208201526001600160e01b031960e088811b821660218401526001600160601b0319606089811b821660258601529188901b909216603984015285901b16603d8201526051810183905260718101829052600090609101604051602081830303815290604052805190602001209050979650505050505050565b605354600090819081805b60208110156108f2578083901c600116600103610886576033816020811061085357610853613336565b015460408051602081019290925281018590526060016040516020818303038152906040528051906020012093506108b3565b60408051602081018690529081018390526060016040516020818303038152906040528051906020012093505b604080516020810184905290810183905260600160405160208183030381529060405280519060200120915080806108ea90613362565b915050610829565b50919392505050565b600061091d848461090b85611ca0565b61091486611d5f565b61046687611e17565b949350505050565b605354606854600160c81b900463ffffffff16101561064057610640611ecf565b60405180611ba00160405280611b668152602001613a7a611b66913981565b600083815b6020811015610a3257600163ffffffff8516821c811690036109d55784816020811061099857610998613336565b6020020135826040516020016109b8929190918252602082015260400190565b604051602081830303815290604052805190602001209150610a20565b818582602081106109e8576109e8613336565b6020020135604051602001610a07929190918252602082015260400190565b6040516020818303038152906040528051906020012091505b80610a2a81613362565b91505061096a565b50949350505050565b6000808686604051602001610a519291906132d2565b604051602081830303815290604052805190602001209050600060ff60f81b308360405180611ba00160405280611b668152602001613a7a611b669139898989604051602001610aa39392919061337b565b60408051601f1981840301815290829052610ac192916020016133b4565b60405160208183030381529060405280519060200120604051602001610b1994939291906001600160f81b031994909416845260609290921b6001600160601b03191660018401526015830152603582015260550190565b60408051808303601f19018152919052805160209091012098975050505050505050565b60685460ff1615610b6157604051630bc011ff60e21b815260040160405180910390fd5b606f546001600160a01b0316610b8a5760405163dde3cda760e01b815260040160405180910390fd5b606f54604051632770a7eb60e21b81526001600160a01b0390911690639dc29fac90610bbc90339088906004016133e3565b600060405180830381600087803b158015610bd657600080fd5b505af1158015610bea573d6000803e3d6000fd5b50505050610bfc868686868686611bd6565b505050505050565b6060610c0f82611ca0565b610c1883611d5f565b610c2184611e17565b604051602001610c339392919061337b565b6040516020818303038152906040529050919050565b6068546000908190610100900463ffffffff16158015610c6f575063ffffffff83166001145b15610c81575063ffffffff8316610ca8565b610c95600160201b63ffffffff85166133fc565b610ca59063ffffffff8616613413565b90505b600881901c600090815260696020526040902054600160ff9092169190911b908116149392505050565b60685460ff1615610cf657604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff8681166101009092041614610d26576040516302caf51760e11b815260040160405180910390fd5b610d5a8c8c8c8c8c610d5560008e8e8e8e8e8e8e604051610d48929190613426565b6040518091039020610791565b611f68565b6001600160a01b038616610e9257606f546001600160a01b0316610e295760006001600160a01b03851684825b6040519080825280601f01601f191660200182016040528015610db1576020820181803683370190505b50604051610dbf9190613436565b60006040518083038185875af1925050503d8060008114610dfc576040519150601f19603f3d011682016040523d82523d6000602084013e610e01565b606091505b5050905080610e2357604051630ce8f45160e31b815260040160405180910390fd5b5061117a565b606f546040516340c10f1960e01b81526001600160a01b03909116906340c10f1990610e5b90879087906004016133e3565b600060405180830381600087803b158015610e7557600080fd5b505af1158015610e89573d6000803e3d6000fd5b5050505061117a565b606d546001600160a01b038781169116148015610ec05750606d5463ffffffff888116600160a01b90920416145b15610ed85760006001600160a01b0385168482610d87565b60685463ffffffff610100909104811690881603610f0957610f046001600160a01b03871685856120c7565b61117a565b60008787604051602001610f1e9291906132d2565b60408051601f1981840301815291815281516020928301206000818152606a9093529120549091506001600160a01b031680611116576000610f968386868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061212292505050565b6040516340c10f1960e01b81529091506001600160a01b038216906340c10f1990610fc7908a908a906004016133e3565b600060405180830381600087803b158015610fe157600080fd5b505af1158015610ff5573d6000803e3d6000fd5b5050505080606a600085815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555060405180604001604052808b63ffffffff1681526020018a6001600160a01b0316815250606b6000836001600160a01b03166001600160a01b0316815260200190815260200160002060008201518160000160006101000a81548163ffffffff021916908363ffffffff16021790555060208201518160000160046101000a8154816001600160a01b0302191690836001600160a01b031602179055509050507f490e59a1701b938786ac72570a1efeac994a3dbe96e2e883e19e902ace6e6a398a8a83888860405161110895949392919061347b565b60405180910390a150611177565b6040516340c10f1960e01b81526001600160a01b038216906340c10f199061114490899089906004016133e3565b600060405180830381600087803b15801561115e57600080fd5b505af1158015611172573d6000803e3d6000fd5b505050505b50505b7f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d8a888887876040516111b19594939291906134b4565b60405180910390a1505050505050505050505050565b60685460ff16156111eb57604051630bc011ff60e21b815260040160405180910390fd5b6111f361219e565b60685463ffffffff610100909104811690881603611224576040516302caf51760e11b815260040160405180910390fd5b6000806060876001600160a01b03881661130a578834146112585760405163b89240f560e01b815260040160405180910390fd5b606d54606e80546001600160a01b0383169650600160a01b90920463ffffffff16945090611285906132fc565b80601f01602080910402602001604051908101604052809291908181526020018280546112b1906132fc565b80156112fe5780601f106112d3576101008083540402835291602001916112fe565b820191906000526020600020905b8154815290600101906020018083116112e157829003601f168201915b50505050509150611596565b34156113295760405163798ee6f160e01b815260040160405180910390fd5b606f546001600160a01b03908116908916036113a457604051632770a7eb60e21b81526001600160a01b03891690639dc29fac9061136d9033908d906004016133e3565b600060405180830381600087803b15801561138757600080fd5b505af115801561139b573d6000803e3d6000fd5b50505050611596565b6001600160a01b038089166000908152606b602090815260409182902082518084019093525463ffffffff81168352600160201b9004909216918101829052901561145c57604051632770a7eb60e21b81526001600160a01b038a1690639dc29fac906114179033908e906004016133e3565b600060405180830381600087803b15801561143157600080fd5b505af1158015611445573d6000803e3d6000fd5b505050508060200151945080600001519350611589565b851561146e5761146e898b89896121f7565b6040516370a0823160e01b81526000906001600160a01b038b16906370a082319061149d903090600401612b9c565b602060405180830381865afa1580156114ba573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114de91906134e6565b90506114f56001600160a01b038b1633308e61253d565b6040516370a0823160e01b81526000906001600160a01b038c16906370a0823190611524903090600401612b9c565b602060405180830381865afa158015611541573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061156591906134e6565b905061157182826134ff565b6068548c9850610100900463ffffffff169650935050505b61159289610c04565b9250505b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b600084868e8e86886053546040516115d6989796959493929190613512565b60405180910390a16115fd6115f8600085878f8f878980519060200120610791565b612575565b861561160b5761160b611ecf565b5050505061161860018055565b50505050505050565b606c546001600160a01b0316331461164c57604051631736745960e31b815260040160405180910390fd5b610640612660565b60685460ff161561167857604051630bc011ff60e21b815260040160405180910390fd5b60685463ffffffff86811661010090920416146116a8576040516302caf51760e11b815260040160405180910390fd5b6116ca8c8c8c8c8c610d5560018e8e8e8e8e8e8e604051610d48929190613426565b606f546000906001600160a01b031661178157846001600160a01b031684888a86866040516024016116ff949392919061357d565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b179052516117349190613436565b60006040518083038185875af1925050503d8060008114611771576040519150601f19603f3d011682016040523d82523d6000602084013e611776565b606091505b505080915050611883565b606f546040516340c10f1960e01b81526001600160a01b03909116906340c10f19906117b390889088906004016133e3565b600060405180830381600087803b1580156117cd57600080fd5b505af11580156117e1573d6000803e3d6000fd5b50505050846001600160a01b031687898585604051602401611806949392919061357d565b60408051601f198184030181529181526020820180516001600160e01b0316630c035af960e11b1790525161183b9190613436565b6000604051808303816000865af19150503d8060008114611878576040519150601f19603f3d011682016040523d82523d6000602084013e61187d565b606091505b50909150505b806118a1576040516337e391c360e01b815260040160405180910390fd5b7f1df3f2a973a00d6635911755c260704e95e8a5876997546798770f76396fda4d8b898988886040516118d89594939291906134b4565b60405180910390a150505050505050505050505050565b600054610100900460ff161580801561190f5750600054600160ff909116105b806119295750303b158015611929575060005460ff166001145b6119915760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b60648201526084015b60405180910390fd5b6000805460ff1916600117905580156119b4576000805461ff0019166101001790555b60688054610100600160c81b03191661010063ffffffff8a160265010000000000600160c81b03191617600160281b6001600160a01b038781169190910291909117909155606c80546001600160a01b0319168583161790558616611a3d5763ffffffff851615611a3857604051630d43a60960e11b815260040160405180910390fd5b611b0c565b606d805463ffffffff8716600160a01b026001600160c01b03199091166001600160a01b03891617179055606e611a7483826135fe565b50611aeb6000801b6012604051602001611ad791906060808252600d908201526c2bb930b83832b21022ba3432b960991b608082015260a060208201819052600490820152630ae8aa8960e31b60c082015260ff91909116604082015260e00190565b604051602081830303815290604052612122565b606f80546001600160a01b0319166001600160a01b03929092169190911790555b611b146126b8565b8015611618576000805461ff0019169055604051600181527f7f26b83ff96e1f2b6a682f133852f6798a09c465da95921460cefb38474024989060200160405180910390a150505050505050565b600081611b70868686610965565b1495945050505050565b60685460ff1615611b9e57604051630bc011ff60e21b815260040160405180910390fd5b6068805460ff191660011790556040517f2261efe5aef6fedc1fd1550b25facc9181745623049c7901287030b9ad1a549790600090a1565b60685463ffffffff610100909104811690871603611c07576040516302caf51760e11b815260040160405180910390fd5b7f501781209a1f8899323b96b4ef08b168df93e0a90c673d1e4cce39366cb62f9b6001606860019054906101000a900463ffffffff16338989898888605354604051611c5b999897969594939291906136bd565b60405180910390a1611c926115f86001606860019054906101000a900463ffffffff16338a8a8a8989604051610d48929190613426565b8215610bfc57610bfc611ecf565b60408051600481526024810182526020810180516001600160e01b03166306fdde0360e01b179052905160609160009182916001600160a01b03861691611ce79190613436565b600060405180830381855afa9150503d8060008114611d22576040519150601f19603f3d011682016040523d82523d6000602084013e611d27565b606091505b509150915081611d5657604051806040016040528060078152602001664e4f5f4e414d4560c81b81525061091d565b61091d816126e7565b60408051600481526024810182526020810180516001600160e01b03166395d89b4160e01b179052905160609160009182916001600160a01b03861691611da69190613436565b600060405180830381855afa9150503d8060008114611de1576040519150601f19603f3d011682016040523d82523d6000602084013e611de6565b606091505b509150915081611d5657604051806040016040528060098152602001681393d7d4d6535093d360ba1b81525061091d565b60408051600481526024810182526020810180516001600160e01b031663313ce56760e01b1790529051600091829182916001600160a01b03861691611e5d9190613436565b600060405180830381855afa9150503d8060008114611e98576040519150601f19603f3d011682016040523d82523d6000602084013e611e9d565b606091505b5091509150818015611eb0575080516020145b611ebb57601261091d565b8080602001905181019061091d919061372a565b6053546068805463ffffffff909216600160c81b0263ffffffff60c81b1990921691909117908190556001600160a01b03600160281b909104166333d6247d611f1661081e565b6040518263ffffffff1660e01b8152600401611f3491815260200190565b600060405180830381600087803b158015611f4e57600080fd5b505af1158015611f62573d6000803e3d6000fd5b50505050565b606854604080516020808201879052818301869052825180830384018152606083019384905280519101206312bd9b1960e11b9092526064810191909152600091600160281b90046001600160a01b03169063257b3632906084016020604051808303816000875af1158015611fe2573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200691906134e6565b90508060000361202857604051622f6fad60e01b815260040160405180910390fd5b600080600160401b87161561206857869150612046848a8489611b62565b612063576040516338105f3b60e21b815260040160405180910390fd5b6120b2565b602087901c612078816001613747565b915087925061209361208b868c86610965565b8a8389611b62565b6120b0576040516338105f3b60e21b815260040160405180910390fd5b505b6120bc8282612875565b505050505050505050565b61211d8363a9059cbb60e01b84846040516024016120e69291906133e3565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b03199093169290921790915261291d565b505050565b60008060405180611ba00160405280611b668152602001613a7a611b669139836040516020016121539291906133b4565b6040516020818303038152906040529050838151602083016000f591506001600160a01b038216612197576040516305f7d84960e51b815260040160405180910390fd5b5092915050565b6002600154036121f05760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401611988565b6002600155565b60006122066004828486613764565b61220f9161378e565b9050632afa533160e01b6001600160e01b03198216016123a357600080808080808061223e896004818d613764565b81019061224b91906137be565b9650965096509650965096509650336001600160a01b0316876001600160a01b03161461228b5760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03861630146122b45760405163750643af60e01b815260040160405180910390fd5b8a85146122d4576040516303fffc4b60e01b815260040160405180910390fd5b604080516001600160a01b0389811660248301528881166044830152606482018890526084820187905260ff861660a483015260c4820185905260e48083018590528351808403909101815261010490920183526020820180516001600160e01b031663d505accf60e01b1790529151918e16916123529190613436565b6000604051808303816000865af19150503d806000811461238f576040519150601f19603f3d011682016040523d82523d6000602084013e612394565b606091505b505050505050505050506106fc565b6001600160e01b031981166323f2ebc360e21b146123d457604051637141605d60e11b815260040160405180910390fd5b6000808080808080806123ea8a6004818e613764565b8101906123f79190613812565b97509750975097509750975097509750336001600160a01b0316886001600160a01b0316146124395760405163912ecce760e01b815260040160405180910390fd5b6001600160a01b03871630146124625760405163750643af60e01b815260040160405180910390fd5b604080516001600160a01b038a811660248301528981166044830152606482018990526084820188905286151560a483015260ff861660c483015260e482018590526101048083018590528351808403909101815261012490920183526020820180516001600160e01b03166323f2ebc360e21b1790529151918f16916124e99190613436565b6000604051808303816000865af19150503d8060008114612526576040519150601f19603f3d011682016040523d82523d6000602084013e61252b565b606091505b50505050505050505050505050505050565b6040516001600160a01b0380851660248301528316604482015260648101829052611f629085906323b872dd60e01b906084016120e6565b80600161258460206002613979565b61258e91906134ff565b605354106125af576040516377ae67b360e11b815260040160405180910390fd5b60006053600081546125c090613362565b9182905550905060005b6020811015612651578082901c6001166001036125fd5782603382602081106125f5576125f5613336565b015550505050565b6033816020811061261057612610613336565b01546040805160208101929092528101849052606001604051602081830303815290604052805190602001209250808061264990613362565b9150506125ca565b5061211d613985565b60018055565b60685460ff1661268357604051635386698160e01b815260040160405180910390fd5b6068805460ff191690556040517f1e5e34eea33501aecf2ebec9fe0e884a40804275ea7fe10b2ba084c8374308b390600090a1565b600054610100900460ff166126df5760405162461bcd60e51b81526004016119889061399b565b6106406129ef565b60606040825110612706578180602001905181019061068d91906139e6565b81516020036128425760005b602081108015612741575082818151811061272f5761272f613336565b01602001516001600160f81b03191615155b15612758578061275081613362565b915050612712565b806000036127905750506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b6020820152919050565b6000816001600160401b038111156127aa576127aa612e47565b6040519080825280601f01601f1916602001820160405280156127d4576020820181803683370190505b50905060005b8281101561283a578481815181106127f4576127f4613336565b602001015160f81c60f81b82828151811061281157612811613336565b60200101906001600160f81b031916908160001a9053508061283281613362565b9150506127da565b509392505050565b50506040805180820190915260128152714e4f545f56414c49445f454e434f44494e4760701b602082015290565b919050565b606854600090610100900463ffffffff16158015612899575063ffffffff82166001145b156128ab575063ffffffff82166128d2565b6128bf600160201b63ffffffff84166133fc565b6128cf9063ffffffff8516613413565b90505b600881901c60008181526069602052604081208054600160ff861690811b9182189283905592909190818316900361161857604051630c8d9eab60e31b815260040160405180910390fd5b6000612972826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612a169092919063ffffffff16565b80519091501561211d57808060200190518101906129909190613a5c565b61211d5760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401611988565b600054610100900460ff1661265a5760405162461bcd60e51b81526004016119889061399b565b606061091d848460008585600080866001600160a01b03168587604051612a3d9190613436565b60006040518083038185875af1925050503d8060008114612a7a576040519150601f19603f3d011682016040523d82523d6000602084013e612a7f565b606091505b5091509150612a9087838387612a9b565b979650505050505050565b60608315612b0a578251600003612b03576001600160a01b0385163b612b035760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401611988565b508161091d565b61091d8383815115612b1f5781518083602001fd5b8060405162461bcd60e51b81526004016119889190612ccf565b803563ffffffff8116811461287057600080fd5b6001600160a01b0381168114612b6257600080fd5b50565b60008060408385031215612b7857600080fd5b612b8183612b39565b91506020830135612b9181612b4d565b809150509250929050565b6001600160a01b0391909116815260200190565b8015158114612b6257600080fd5b60008083601f840112612bd057600080fd5b5081356001600160401b03811115612be757600080fd5b602083019150836020828501011115612bff57600080fd5b9250929050565b600080600080600060808688031215612c1e57600080fd5b612c2786612b39565b94506020860135612c3781612b4d565b93506040860135612c4781612bb0565b925060608601356001600160401b03811115612c6257600080fd5b612c6e88828901612bbe565b969995985093965092949392505050565b60005b83811015612c9a578181015183820152602001612c82565b50506000910152565b60008151808452612cbb816020860160208601612c7f565b601f01601f19169290920160200192915050565b602081526000612ce26020830184612ca3565b9392505050565b600060208284031215612cfb57600080fd5b8135612ce281612b4d565b60ff81168114612b6257600080fd5b600080600080600080600060e0888a031215612d3057600080fd5b8735612d3b81612d06565b9650612d4960208901612b39565b95506040880135612d5981612b4d565b9450612d6760608901612b39565b93506080880135612d7781612b4d565b9699959850939692959460a0840135945060c09093013592915050565b600080600060608486031215612da957600080fd5b612db284612b39565b92506020840135612dc281612b4d565b91506040840135612dd281612b4d565b809150509250925092565b600060208284031215612def57600080fd5b5035919050565b80610400810183101561068d57600080fd5b60008060006104408486031215612e1e57600080fd5b83359250612e2f8560208601612df6565b9150612e3e6104208501612b39565b90509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715612e8557612e85612e47565b604052919050565b60006001600160401b03821115612ea657612ea6612e47565b50601f01601f191660200190565b6000612ec7612ec284612e8d565b612e5d565b9050828152838383011115612edb57600080fd5b828260208301376000602084830101529392505050565b600082601f830112612f0357600080fd5b612ce283833560208501612eb4565b600080600080600060a08688031215612f2a57600080fd5b612f3386612b39565b94506020860135612f4381612b4d565b935060408601356001600160401b0380821115612f5f57600080fd5b612f6b89838a01612ef2565b94506060880135915080821115612f8157600080fd5b50612f8e88828901612ef2565b9250506080860135612f9f81612d06565b809150509295509295909350565b60008060008060008060a08789031215612fc657600080fd5b612fcf87612b39565b95506020870135612fdf81612b4d565b9450604087013593506060870135612ff681612bb0565b925060808701356001600160401b0381111561301157600080fd5b61301d89828a01612bbe565b979a9699509497509295939492505050565b6000806040838503121561304257600080fd5b61304b83612b39565b915061305960208401612b39565b90509250929050565b6000806000806000806000806000806000806109208d8f03121561308557600080fd5b61308f8e8e612df6565b9b5061309f8e6104008f01612df6565b9a506108008d013599506108208d013598506108408d013597506130c66108608e01612b39565b96506130d66108808e0135612b4d565b6108808d013595506130eb6108a08e01612b39565b94506130fb6108c08e0135612b4d565b6108c08d013593506108e08d013592506001600160401b036109008e0135111561312457600080fd5b6131358e6109008f01358f01612bbe565b81935080925050509295989b509295989b509295989b565b600080600080600080600060c0888a03121561316857600080fd5b61317188612b39565b9650602088013561318181612b4d565b955060408801359450606088013561319881612b4d565b935060808801356131a881612bb0565b925060a08801356001600160401b038111156131c357600080fd5b6131cf8a828b01612bbe565b989b979a50959850939692959293505050565b60008060008060008060c087890312156131fb57600080fd5b61320487612b39565b9550602087013561321481612b4d565b945061322260408801612b39565b9350606087013561323281612b4d565b9250608087013561324281612b4d565b915060a08701356001600160401b0381111561325d57600080fd5b8701601f8101891361326e57600080fd5b61327d89823560208401612eb4565b9150509295509295509295565b60008060008061046085870312156132a157600080fd5b843593506132b28660208701612df6565b92506132c16104208601612b39565b939692955092936104400135925050565b60e09290921b6001600160e01b031916825260601b6001600160601b031916600482015260180190565b600181811c9082168061331057607f821691505b60208210810361333057634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600182016133745761337461334c565b5060010190565b60608152600061338e6060830186612ca3565b82810360208401526133a08186612ca3565b91505060ff83166040830152949350505050565b600083516133c6818460208801612c7f565b8351908301906133da818360208801612c7f565b01949350505050565b6001600160a01b03929092168252602082015260400190565b808202811582820484141761068d5761068d61334c565b8082018082111561068d5761068d61334c565b8183823760009101908152919050565b60008251613448818460208701612c7f565b9190910192915050565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b63ffffffff861681526001600160a01b03858116602083015284166040820152608060608201819052600090612a909083018486613452565b94855263ffffffff9390931660208501526001600160a01b039182166040850152166060830152608082015260a00190565b6000602082840312156134f857600080fd5b5051919050565b8181038181111561068d5761068d61334c565b60ff8916815263ffffffff88811660208301526001600160a01b03888116604084015287821660608401528616608083015260a0820185905261010060c0830181905260009161356484830187612ca3565b925080851660e085015250509998505050505050505050565b6001600160a01b038516815263ffffffff841660208201526060604082018190526000906135ae9083018486613452565b9695505050505050565b601f82111561211d57600081815260208120601f850160051c810160208610156135df5750805b601f850160051c820191505b81811015610bfc578281556001016135eb565b81516001600160401b0381111561361757613617612e47565b61362b8161362584546132fc565b846135b8565b602080601f83116001811461366057600084156136485750858301515b600019600386901b1c1916600185901b178555610bfc565b600085815260208120601f198616915b8281101561368f57888601518255948401946001909101908401613670565b50858210156136ad5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60ff8a16815263ffffffff89811660208301526001600160a01b03898116604084015288821660608401528716608083015260a0820186905261010060c083018190526000916137108483018789613452565b925080851660e085015250509a9950505050505050505050565b60006020828403121561373c57600080fd5b8151612ce281612d06565b63ffffffff8181168382160190808211156121975761219761334c565b6000808585111561377457600080fd5b8386111561378157600080fd5b5050820193919092039150565b6001600160e01b031981358181169160048510156137b65780818660040360031b1b83161692505b505092915050565b600080600080600080600060e0888a0312156137d957600080fd5b87356137e481612b4d565b965060208801356137f481612b4d565b955060408801359450606088013593506080880135612d7781612d06565b600080600080600080600080610100898b03121561382f57600080fd5b883561383a81612b4d565b9750602089013561384a81612b4d565b96506040890135955060608901359450608089013561386881612bb0565b935060a089013561387881612d06565b979a969950949793969295929450505060c08201359160e0013590565b600181815b808511156138d05781600019048211156138b6576138b661334c565b808516156138c357918102915b93841c939080029061389a565b509250929050565b6000826138e75750600161068d565b816138f45750600061068d565b816001811461390a576002811461391457613930565b600191505061068d565b60ff8411156139255761392561334c565b50506001821b61068d565b5060208310610133831016604e8410600b8410161715613953575081810a61068d565b61395d8383613895565b80600019048211156139715761397161334c565b029392505050565b6000612ce283836138d8565b634e487b7160e01b600052600160045260246000fd5b6020808252602b908201527f496e697469616c697a61626c653a20636f6e7472616374206973206e6f74206960408201526a6e697469616c697a696e6760a81b606082015260800190565b6000602082840312156139f857600080fd5b81516001600160401b03811115613a0e57600080fd5b8201601f81018413613a1f57600080fd5b8051613a2d612ec282612e8d565b818152856020838501011115613a4257600080fd5b613a53826020830160208601612c7f565b95945050505050565b600060208284031215613a6e57600080fd5b8151612ce281612bb056fe6101006040523480156200001257600080fd5b5060405162001b6638038062001b6683398101604081905262000035916200028d565b82826003620000458382620003a1565b506004620000548282620003a1565b50503360c0525060ff811660e052466080819052620000739062000080565b60a052506200046d915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f620000ad6200012e565b805160209182012060408051808201825260018152603160f81b90840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b6060600380546200013f9062000312565b80601f01602080910402602001604051908101604052809291908181526020018280546200016d9062000312565b8015620001be5780601f106200019257610100808354040283529160200191620001be565b820191906000526020600020905b815481529060010190602001808311620001a057829003601f168201915b5050505050905090565b634e487b7160e01b600052604160045260246000fd5b600082601f830112620001f057600080fd5b81516001600160401b03808211156200020d576200020d620001c8565b604051601f8301601f19908116603f01168101908282118183101715620002385762000238620001c8565b816040528381526020925086838588010111156200025557600080fd5b600091505b838210156200027957858201830151818301840152908201906200025a565b600093810190920192909252949350505050565b600080600060608486031215620002a357600080fd5b83516001600160401b0380821115620002bb57600080fd5b620002c987838801620001de565b94506020860151915080821115620002e057600080fd5b50620002ef86828701620001de565b925050604084015160ff811681146200030757600080fd5b809150509250925092565b600181811c908216806200032757607f821691505b6020821081036200034857634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200039c57600081815260208120601f850160051c81016020861015620003775750805b601f850160051c820191505b81811015620003985782815560010162000383565b5050505b505050565b81516001600160401b03811115620003bd57620003bd620001c8565b620003d581620003ce845462000312565b846200034e565b602080601f8311600181146200040d5760008415620003f45750858301515b600019600386901b1c1916600185901b17855562000398565b600085815260208120601f198616915b828110156200043e578886015182559484019460019091019084016200041d565b50858210156200045d5787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b60805160a05160c05160e0516116aa620004bc6000396000610237015260008181610307015281816105c001526106a70152600061053a015260008181610379015261050401526116aa6000f3fe608060405234801561001057600080fd5b50600436106101775760003560e01c806370a08231116100d8578063a457c2d71161008c578063d505accf11610066578063d505accf1461039b578063dd62ed3e146103ae578063ffa1ad74146103f457600080fd5b8063a457c2d71461034e578063a9059cbb14610361578063cd0d00961461037457600080fd5b806395d89b41116100bd57806395d89b41146102e75780639dc29fac146102ef578063a3c573eb1461030257600080fd5b806370a08231146102915780637ecebe00146102c757600080fd5b806330adf81f1161012f5780633644e515116101145780633644e51514610261578063395093511461026957806340c10f191461027c57600080fd5b806330adf81f14610209578063313ce5671461023057600080fd5b806318160ddd1161016057806318160ddd146101bd57806320606b70146101cf57806323b872dd146101f657600080fd5b806306fdde031461017c578063095ea7b31461019a575b600080fd5b610184610430565b60405161019191906113e4565b60405180910390f35b6101ad6101a8366004611479565b6104c2565b6040519015158152602001610191565b6002545b604051908152602001610191565b6101c17f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f81565b6101ad6102043660046114a3565b6104dc565b6101c17f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c981565b60405160ff7f0000000000000000000000000000000000000000000000000000000000000000168152602001610191565b6101c1610500565b6101ad610277366004611479565b61055c565b61028f61028a366004611479565b6105a8565b005b6101c161029f3660046114df565b73ffffffffffffffffffffffffffffffffffffffff1660009081526020819052604090205490565b6101c16102d53660046114df565b60056020526000908152604090205481565b610184610680565b61028f6102fd366004611479565b61068f565b6103297f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610191565b6101ad61035c366004611479565b61075e565b6101ad61036f366004611479565b61082f565b6101c17f000000000000000000000000000000000000000000000000000000000000000081565b61028f6103a9366004611501565b61083d565b6101c16103bc366004611574565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260016020908152604080832093909416825291909152205490565b6101846040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081565b60606003805461043f906115a7565b80601f016020809104026020016040519081016040528092919081815260200182805461046b906115a7565b80156104b85780601f1061048d576101008083540402835291602001916104b8565b820191906000526020600020905b81548152906001019060200180831161049b57829003601f168201915b5050505050905090565b6000336104d0818585610b73565b60019150505b92915050565b6000336104ea858285610d27565b6104f5858585610dfe565b506001949350505050565b60007f00000000000000000000000000000000000000000000000000000000000000004614610537576105324661106d565b905090565b507f000000000000000000000000000000000000000000000000000000000000000090565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091906104d090829086906105a3908790611629565b610b73565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610672576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d4272696467650000000000000000000000000000000060648201526084015b60405180910390fd5b61067c8282611135565b5050565b60606004805461043f906115a7565b3373ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001614610754576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546f6b656e577261707065643a3a6f6e6c794272696467653a204e6f7420506f60448201527f6c79676f6e5a6b45564d427269646765000000000000000000000000000000006064820152608401610669565b61067c8282611228565b33600081815260016020908152604080832073ffffffffffffffffffffffffffffffffffffffff8716845290915281205490919083811015610822576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610669565b6104f58286868403610b73565b6000336104d0818585610dfe565b834211156108cc576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546f6b656e577261707065643a3a7065726d69743a204578706972656420706560448201527f726d6974000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8716600090815260056020526040812080547f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9918a918a918a9190866109268361163c565b9091555060408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810186905260e0016040516020818303038152906040528051906020012090506000610991610500565b6040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281019190915260428101839052606201604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181528282528051602091820120600080855291840180845281905260ff89169284019290925260608301879052608083018690529092509060019060a0016020604051602081039080840390855afa158015610a55573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff811615801590610ad057508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16145b610b5c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602760248201527f546f6b656e577261707065643a3a7065726d69743a20496e76616c696420736960448201527f676e6174757265000000000000000000000000000000000000000000000000006064820152608401610669565b610b678a8a8a610b73565b50505050505050505050565b73ffffffffffffffffffffffffffffffffffffffff8316610c15576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610cb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526001602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8381166000908152600160209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610df85781811015610deb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610669565b610df88484848403610b73565b50505050565b73ffffffffffffffffffffffffffffffffffffffff8316610ea1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff8216610f44576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff831660009081526020819052604090205481811015610ffa576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff848116600081815260208181526040808320878703905593871680835291849020805487019055925185815290927fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3610df8565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611098610430565b8051602091820120604080518082018252600181527f310000000000000000000000000000000000000000000000000000000000000090840152805192830193909352918101919091527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152608081018390523060a082015260c001604051602081830303815290604052805190602001209050919050565b73ffffffffffffffffffffffffffffffffffffffff82166111b2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610669565b80600260008282546111c49190611629565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600081815260208181526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b73ffffffffffffffffffffffffffffffffffffffff82166112cb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff821660009081526020819052604090205481811015611381576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610669565b73ffffffffffffffffffffffffffffffffffffffff83166000818152602081815260408083208686039055600280548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9101610d1a565b600060208083528351808285015260005b81811015611411578581018301518582016040015282016113f5565b5060006040828601015260407fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f8301168501019250505092915050565b803573ffffffffffffffffffffffffffffffffffffffff8116811461147457600080fd5b919050565b6000806040838503121561148c57600080fd5b61149583611450565b946020939093013593505050565b6000806000606084860312156114b857600080fd5b6114c184611450565b92506114cf60208501611450565b9150604084013590509250925092565b6000602082840312156114f157600080fd5b6114fa82611450565b9392505050565b600080600080600080600060e0888a03121561151c57600080fd5b61152588611450565b965061153360208901611450565b95506040880135945060608801359350608088013560ff8116811461155757600080fd5b9699959850939692959460a0840135945060c09093013592915050565b6000806040838503121561158757600080fd5b61159083611450565b915061159e60208401611450565b90509250929050565b600181811c908216806115bb57607f821691505b6020821081036115f4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b808201808211156104d6576104d66115fa565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361166d5761166d6115fa565b506001019056fea26469706673582212208d88fee561cff7120d381c345cfc534cef8229a272dc5809d4bbb685ad67141164736f6c63430008110033a2646970667358221220914f18d5b241f0d10b2ebc814aadeee338ad60bad704683e414dad415cb2e14d64736f6c63430008140033" + }, + { + "contractName": "PolygonZkEVMBridge proxy", + "balance": "340282366920938463463374607431768211455", + "nonce": "1", + "address": "0xB7098a13a48EcE087d3DA15b2D28eCE0f89819B8", + "bytecode": "0x60806040526004361061005e5760003560e01c80635c60da1b116100435780635c60da1b146100a85780638f283970146100e6578063f851a440146101065761006d565b80633659cfe6146100755780634f1ef286146100955761006d565b3661006d5761006b61011b565b005b61006b61011b565b34801561008157600080fd5b5061006b61009036600461086f565b610135565b61006b6100a336600461088a565b61017f565b3480156100b457600080fd5b506100bd6101f3565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390f35b3480156100f257600080fd5b5061006b61010136600461086f565b610231565b34801561011257600080fd5b506100bd61025e565b61012361028c565b61013361012e610363565b61036d565b565b61013d610391565b73ffffffffffffffffffffffffffffffffffffffff16330361017757610174816040518060200160405280600081525060006103d1565b50565b61017461011b565b610187610391565b73ffffffffffffffffffffffffffffffffffffffff1633036101eb576101e68383838080601f016020809104026020016040519081016040528093929190818152602001838380828437600092019190915250600192506103d1915050565b505050565b6101e661011b565b60006101fd610391565b73ffffffffffffffffffffffffffffffffffffffff16330361022657610221610363565b905090565b61022e61011b565b90565b610239610391565b73ffffffffffffffffffffffffffffffffffffffff16330361017757610174816103fc565b6000610268610391565b73ffffffffffffffffffffffffffffffffffffffff16330361022657610221610391565b610294610391565b73ffffffffffffffffffffffffffffffffffffffff163303610133576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f7879207461726760648201527f6574000000000000000000000000000000000000000000000000000000000000608482015260a4015b60405180910390fd5b600061022161045d565b3660008037600080366000845af43d6000803e80801561038c573d6000f35b3d6000fd5b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b5473ffffffffffffffffffffffffffffffffffffffff16919050565b6103da83610485565b6000825111806103e75750805b156101e6576103f683836104d2565b50505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f610425610391565b6040805173ffffffffffffffffffffffffffffffffffffffff928316815291841660208301520160405180910390a1610174816104fe565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6103b5565b61048e8161060a565b60405173ffffffffffffffffffffffffffffffffffffffff8216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b60606104f7838360405180606001604052806027815260200161099f602791396106d5565b9392505050565b73ffffffffffffffffffffffffffffffffffffffff81166105a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161035a565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff9290921691909117905550565b73ffffffffffffffffffffffffffffffffffffffff81163b6106ae576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201527f6f74206120636f6e747261637400000000000000000000000000000000000000606482015260840161035a565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6105c4565b60606000808573ffffffffffffffffffffffffffffffffffffffff16856040516106ff9190610931565b600060405180830381855af49150503d806000811461073a576040519150601f19603f3d011682016040523d82523d6000602084013e61073f565b606091505b50915091506107508683838761075a565b9695505050505050565b606083156107f05782516000036107e95773ffffffffffffffffffffffffffffffffffffffff85163b6107e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161035a565b50816107fa565b6107fa8383610802565b949350505050565b8151156108125781518083602001fd5b806040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161035a919061094d565b803573ffffffffffffffffffffffffffffffffffffffff8116811461086a57600080fd5b919050565b60006020828403121561088157600080fd5b6104f782610846565b60008060006040848603121561089f57600080fd5b6108a884610846565b9250602084013567ffffffffffffffff808211156108c557600080fd5b818601915086601f8301126108d957600080fd5b8135818111156108e857600080fd5b8760208285010111156108fa57600080fd5b6020830194508093505050509250925092565b60005b83811015610928578181015183820152602001610910565b50506000910152565b6000825161094381846020870161090d565b9190910192915050565b602081526000825180602084015261096c81604085016020870161090d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a2646970667358221220701a0c26bdd76686e63fc3c65e4f28a20ba3ecc8a60246733c0627e679c9804e64736f6c63430008140033", + "storage": { + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x000000000000000000000000e34fe58dda5b8c6d547e4857e987633aa86a5e90", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000493732fb136a380920c390a85fc27d79c7b70756" + } + }, + { + "contractName": "PolygonZkEVMGlobalExitRootL2 implementation", + "balance": "0", + "nonce": "1", + "address": "0xDc64a140Aa3E981100a9becA4E685f962f0cF6C9", + "bytecode": "0x608060405234801561001057600080fd5b506004361061004c5760003560e01c806301fd904414610051578063257b36321461006d57806333d6247d1461008d578063a3c573eb146100a2575b600080fd5b61005a60015481565b6040519081526020015b60405180910390f35b61005a61007b366004610162565b60006020819052908152604090205481565b6100a061009b366004610162565b6100ee565b005b6100c97f000000000000000000000000b7098a13a48ece087d3da15b2d28ece0f89819b881565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610064565b3373ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000b7098a13a48ece087d3da15b2d28ece0f89819b8161461015d576040517fb49365dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600155565b60006020828403121561017457600080fd5b503591905056fea2646970667358221220ea2171e2c85c8bff947affc409ef6fc6a8fe82fb8c174ddeda988651e595d66564736f6c63430008140033" + }, + { + "contractName": "PolygonZkEVMGlobalExitRootL2 proxy", + "balance": "0", + "nonce": "1", + "address": "0xa40d5f56745a118d0906a34e69aec8c0db1cb8fa", + "bytecode": "0x60806040523661001357610011610017565b005b6100115b61001f6101b7565b6001600160a01b0316336001600160a01b0316141561016f5760606001600160e01b031960003516631b2ce7f360e11b8114156100655761005e6101ea565b9150610167565b6001600160e01b0319811663278f794360e11b14156100865761005e610241565b6001600160e01b031981166308f2839760e41b14156100a75761005e610287565b6001600160e01b031981166303e1469160e61b14156100c85761005e6102b8565b6001600160e01b03198116635c60da1b60e01b14156100e95761005e6102f8565b60405162461bcd60e51b815260206004820152604260248201527f5472616e73706172656e745570677261646561626c6550726f78793a2061646d60448201527f696e2063616e6e6f742066616c6c6261636b20746f2070726f78792074617267606482015261195d60f21b608482015260a4015b60405180910390fd5b815160208301f35b61017761030c565b565b606061019e83836040518060600160405280602781526020016108576027913961031c565b9392505050565b90565b6001600160a01b03163b151590565b60007fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b546001600160a01b0316919050565b60606101f4610394565b600061020336600481846106a2565b81019061021091906106e8565b905061022d8160405180602001604052806000815250600061039f565b505060408051602081019091526000815290565b606060008061025336600481846106a2565b8101906102609190610719565b915091506102708282600161039f565b604051806020016040528060008152509250505090565b6060610291610394565b60006102a036600481846106a2565b8101906102ad91906106e8565b905061022d816103cb565b60606102c2610394565b60006102cc6101b7565b604080516001600160a01b03831660208201529192500160405160208183030381529060405291505090565b6060610302610394565b60006102cc610422565b610177610317610422565b610431565b6060600080856001600160a01b0316856040516103399190610807565b600060405180830381855af49150503d8060008114610374576040519150601f19603f3d011682016040523d82523d6000602084013e610379565b606091505b509150915061038a86838387610455565b9695505050505050565b341561017757600080fd5b6103a8836104d3565b6000825111806103b55750805b156103c6576103c48383610179565b505b505050565b7f7e644d79422f17c01e4894b5f4f588d331ebfa28653d42ae832dc59e38c9798f6103f46101b7565b604080516001600160a01b03928316815291841660208301520160405180910390a161041f81610513565b50565b600061042c6105bc565b905090565b3660008037600080366000845af43d6000803e808015610450573d6000f35b3d6000fd5b606083156104c15782516104ba576001600160a01b0385163b6104ba5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604482015260640161015e565b50816104cb565b6104cb83836105e4565b949350505050565b6104dc8161060e565b6040516001600160a01b038216907fbc7cd75a20ee27fd9adebab32041f755214dbc6bffa90cc0225b39da2e5c2d3b90600090a250565b6001600160a01b0381166105785760405162461bcd60e51b815260206004820152602660248201527f455243313936373a206e65772061646d696e20697320746865207a65726f206160448201526564647265737360d01b606482015260840161015e565b807fb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d61035b80546001600160a01b0319166001600160a01b039290921691909117905550565b60007f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc6101db565b8151156105f45781518083602001fd5b8060405162461bcd60e51b815260040161015e9190610823565b6001600160a01b0381163b61067b5760405162461bcd60e51b815260206004820152602d60248201527f455243313936373a206e657720696d706c656d656e746174696f6e206973206e60448201526c1bdd08184818dbdb9d1c9858dd609a1b606482015260840161015e565b807f360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc61059b565b600080858511156106b257600080fd5b838611156106bf57600080fd5b5050820193919092039150565b80356001600160a01b03811681146106e357600080fd5b919050565b6000602082840312156106fa57600080fd5b61019e826106cc565b634e487b7160e01b600052604160045260246000fd5b6000806040838503121561072c57600080fd5b610735836106cc565b9150602083013567ffffffffffffffff8082111561075257600080fd5b818501915085601f83011261076657600080fd5b81358181111561077857610778610703565b604051601f8201601f19908116603f011681019083821181831017156107a0576107a0610703565b816040528281528860208487010111156107b957600080fd5b8260208601602083013760006020848301015280955050505050509250929050565b60005b838110156107f65781810151838201526020016107de565b838111156103c45750506000910152565b600082516108198184602087016107db565b9190910192915050565b60208152600082518060208401526108428160408501602087016107db565b601f01601f1916919091016040019291505056fe416464726573733a206c6f772d6c6576656c2064656c65676174652063616c6c206661696c6564a264697066735822122012bb4f564f73959a03513dc74fc3c6e40e8386e6f02c16b78d6db00ce0aa16af64736f6c63430008090033", + "storage": { + "0xb53127684a568b3173ae13b9f8a6016e243e63b6e8ee1178d6a717850b5d6103": "0x000000000000000000000000e34fe58dda5b8c6d547e4857e987633aa86a5e90", + "0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc": "0x000000000000000000000000dc64a140aa3e981100a9beca4e685f962f0cf6c9" + } + }, + { + "contractName": "PolygonZkEVMTimelock", + "balance": "0", + "nonce": "1", + "address": "0x0165878A594ca255338adfa4d48449f69242Eb8F", + "bytecode": "0x6080604052600436106101c65760003560e01c806364d62353116100f7578063b1c5f42711610095578063d547741f11610064578063d547741f14610661578063e38335e514610681578063f23a6e6114610694578063f27a0c92146106d957600080fd5b8063b1c5f427146105af578063bc197c81146105cf578063c4d252f514610614578063d45c44351461063457600080fd5b80638f61f4f5116100d15780638f61f4f5146104e157806391d1485414610515578063a217fddf14610566578063b08e51c01461057b57600080fd5b806364d62353146104815780638065657f146104a15780638f2a0bb0146104c157600080fd5b8063248a9ca31161016457806331d507501161013e57806331d50750146103c857806336568abe146103e85780633a6aae7214610408578063584b153e1461046157600080fd5b8063248a9ca3146103475780632ab0f529146103775780632f2ff15d146103a857600080fd5b80630d3cf6fc116101a05780630d3cf6fc1461026b578063134008d31461029f57806313bc9f20146102b2578063150b7a02146102d257600080fd5b806301d5062a146101d257806301ffc9a7146101f457806307bd02651461022957600080fd5b366101cd57005b600080fd5b3480156101de57600080fd5b506101f26101ed366004611c52565b6106ee565b005b34801561020057600080fd5b5061021461020f366004611cc7565b610783565b60405190151581526020015b60405180910390f35b34801561023557600080fd5b5061025d7fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e6381565b604051908152602001610220565b34801561027757600080fd5b5061025d7f5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca581565b6101f26102ad366004611d09565b6107df565b3480156102be57600080fd5b506102146102cd366004611d75565b6108d7565b3480156102de57600080fd5b506103166102ed366004611e9a565b7f150b7a0200000000000000000000000000000000000000000000000000000000949350505050565b6040517fffffffff000000000000000000000000000000000000000000000000000000009091168152602001610220565b34801561035357600080fd5b5061025d610362366004611d75565b60009081526020819052604090206001015490565b34801561038357600080fd5b50610214610392366004611d75565b6000908152600160208190526040909120541490565b3480156103b457600080fd5b506101f26103c3366004611f02565b6108fd565b3480156103d457600080fd5b506102146103e3366004611d75565b610927565b3480156103f457600080fd5b506101f2610403366004611f02565b610940565b34801561041457600080fd5b5061043c7f000000000000000000000000000000000000000000000000000000000000000081565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610220565b34801561046d57600080fd5b5061021461047c366004611d75565b6109f8565b34801561048d57600080fd5b506101f261049c366004611d75565b610a0e565b3480156104ad57600080fd5b5061025d6104bc366004611d09565b610ade565b3480156104cd57600080fd5b506101f26104dc366004611f73565b610b1d565b3480156104ed57600080fd5b5061025d7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc181565b34801561052157600080fd5b50610214610530366004611f02565b60009182526020828152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b34801561057257600080fd5b5061025d600081565b34801561058757600080fd5b5061025d7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f78381565b3480156105bb57600080fd5b5061025d6105ca366004612025565b610d4f565b3480156105db57600080fd5b506103166105ea36600461214e565b7fbc197c810000000000000000000000000000000000000000000000000000000095945050505050565b34801561062057600080fd5b506101f261062f366004611d75565b610d94565b34801561064057600080fd5b5061025d61064f366004611d75565b60009081526001602052604090205490565b34801561066d57600080fd5b506101f261067c366004611f02565b610e8f565b6101f261068f366004612025565b610eb4565b3480156106a057600080fd5b506103166106af3660046121f8565b7ff23a6e610000000000000000000000000000000000000000000000000000000095945050505050565b3480156106e557600080fd5b5061025d611161565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc161071881611244565b6000610728898989898989610ade565b90506107348184611251565b6000817f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8b8b8b8b8b8a604051610770969594939291906122a6565b60405180910390a3505050505050505050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f4e2312e00000000000000000000000000000000000000000000000000000000014806107d957506107d98261139e565b92915050565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff1661085c5761085c8133611435565b600061086c888888888888610ade565b905061087881856114ed565b6108848888888861162a565b6000817fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588a8a8a8a6040516108bc94939291906122f1565b60405180910390a36108cd8161172e565b5050505050505050565b6000818152600160205260408120546001811180156108f65750428111155b9392505050565b60008281526020819052604090206001015461091881611244565b61092283836117d7565b505050565b60008181526001602052604081205481905b1192915050565b73ffffffffffffffffffffffffffffffffffffffff811633146109ea576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c66000000000000000000000000000000000060648201526084015b60405180910390fd5b6109f482826118c7565b5050565b6000818152600160208190526040822054610939565b333014610a9d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f54696d656c6f636b436f6e74726f6c6c65723a2063616c6c6572206d7573742060448201527f62652074696d656c6f636b00000000000000000000000000000000000000000060648201526084016109e1565b60025460408051918252602082018390527f11c24f4ead16507c69ac467fbd5e4eed5fb5c699626d2cc6d66421df253886d5910160405180910390a1600255565b6000868686868686604051602001610afb969594939291906122a6565b6040516020818303038152906040528051906020012090509695505050505050565b7fb09aa5aeb3702cfd50b6b62bc4532604938f21248a27a1d5ca736082b6819cc1610b4781611244565b888714610bd6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b888514610c65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b6000610c778b8b8b8b8b8b8b8b610d4f565b9050610c838184611251565b60005b8a811015610d415780827f4cf4410cc57040e44862ef0f45f3dd5a5e02db8eb8add648d4b0e236f1d07dca8e8e85818110610cc357610cc3612331565b9050602002016020810190610cd89190612360565b8d8d86818110610cea57610cea612331565b905060200201358c8c87818110610d0357610d03612331565b9050602002810190610d15919061237b565b8c8b604051610d29969594939291906122a6565b60405180910390a3610d3a8161240f565b9050610c86565b505050505050505050505050565b60008888888888888888604051602001610d709897969594939291906124f7565b60405160208183030381529060405280519060200120905098975050505050505050565b7ffd643c72710c63c0180259aba6b2d05451e3591a24e58b62239378085726f783610dbe81611244565b610dc7826109f8565b610e53576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20636160448201527f6e6e6f742062652063616e63656c6c656400000000000000000000000000000060648201526084016109e1565b6000828152600160205260408082208290555183917fbaa1eb22f2a492ba1a5fea61b8df4d27c6c8b5f3971e63bb58fa14ff72eedb7091a25050565b600082815260208190526040902060010154610eaa81611244565b61092283836118c7565b600080527fdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d70696020527f5ba6852781629bcdcd4bdaa6de76d786f1c64b16acdac474e55bebc0ea157951547fd8aa0f3194971a2a116679f7c2090f6939c8d4e01a2a8d7e41d55e5351469e639060ff16610f3157610f318133611435565b878614610fc0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b87841461104f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f54696d656c6f636b436f6e74726f6c6c65723a206c656e677468206d69736d6160448201527f746368000000000000000000000000000000000000000000000000000000000060648201526084016109e1565b60006110618a8a8a8a8a8a8a8a610d4f565b905061106d81856114ed565b60005b8981101561114b5760008b8b8381811061108c5761108c612331565b90506020020160208101906110a19190612360565b905060008a8a848181106110b7576110b7612331565b9050602002013590503660008a8a868181106110d5576110d5612331565b90506020028101906110e7919061237b565b915091506110f78484848461162a565b84867fc2617efa69bab66782fa219543714338489c4e9e178271560a91b82c3f612b588686868660405161112e94939291906122f1565b60405180910390a350505050806111449061240f565b9050611070565b506111558161172e565b50505050505050505050565b60007f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff161580159061123257507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166315064c966040518163ffffffff1660e01b8152600401602060405180830381865afa15801561120e573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061123291906125be565b1561123d5750600090565b5060025490565b61124e8133611435565b50565b61125a82610927565b156112e7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20616c60448201527f7265616479207363686564756c6564000000000000000000000000000000000060648201526084016109e1565b6112ef611161565b81101561137e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a20696e73756666696369656e7460448201527f2064656c6179000000000000000000000000000000000000000000000000000060648201526084016109e1565b61138881426125e0565b6000928352600160205260409092209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b0000000000000000000000000000000000000000000000000000000014806107d957507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146107d9565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f4576114738161197e565b61147e83602061199d565b60405160200161148f929190612617565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a00000000000000000000000000000000000000000000000000000000082526109e191600401612698565b6114f6826108d7565b611582576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b80158061159e5750600081815260016020819052604090912054145b6109f4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f54696d656c6f636b436f6e74726f6c6c65723a206d697373696e67206465706560448201527f6e64656e6379000000000000000000000000000000000000000000000000000060648201526084016109e1565b60008473ffffffffffffffffffffffffffffffffffffffff168484846040516116549291906126e9565b60006040518083038185875af1925050503d8060008114611691576040519150601f19603f3d011682016040523d82523d6000602084013e611696565b606091505b5050905080611727576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603360248201527f54696d656c6f636b436f6e74726f6c6c65723a20756e6465726c79696e67207460448201527f72616e73616374696f6e2072657665727465640000000000000000000000000060648201526084016109e1565b5050505050565b611737816108d7565b6117c3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f54696d656c6f636b436f6e74726f6c6c65723a206f7065726174696f6e20697360448201527f206e6f742072656164790000000000000000000000000000000000000000000060648201526084016109e1565b600090815260016020819052604090912055565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790556118693390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156109f45760008281526020818152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60606107d973ffffffffffffffffffffffffffffffffffffffff831660145b606060006119ac8360026126f9565b6119b79060026125e0565b67ffffffffffffffff8111156119cf576119cf611d8e565b6040519080825280601f01601f1916602001820160405280156119f9576020820181803683370190505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110611a3057611a30612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110611a9357611a93612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506000611acf8460026126f9565b611ada9060016125e0565b90505b6001811115611b77577f303132333435363738396162636465660000000000000000000000000000000085600f1660108110611b1b57611b1b612331565b1a60f81b828281518110611b3157611b31612331565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c93611b7081612710565b9050611add565b5083156108f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016109e1565b803573ffffffffffffffffffffffffffffffffffffffff81168114611c0457600080fd5b919050565b60008083601f840112611c1b57600080fd5b50813567ffffffffffffffff811115611c3357600080fd5b602083019150836020828501011115611c4b57600080fd5b9250929050565b600080600080600080600060c0888a031215611c6d57600080fd5b611c7688611be0565b965060208801359550604088013567ffffffffffffffff811115611c9957600080fd5b611ca58a828b01611c09565b989b979a50986060810135976080820135975060a09091013595509350505050565b600060208284031215611cd957600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146108f657600080fd5b60008060008060008060a08789031215611d2257600080fd5b611d2b87611be0565b955060208701359450604087013567ffffffffffffffff811115611d4e57600080fd5b611d5a89828a01611c09565b979a9699509760608101359660809091013595509350505050565b600060208284031215611d8757600080fd5b5035919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715611e0457611e04611d8e565b604052919050565b600082601f830112611e1d57600080fd5b813567ffffffffffffffff811115611e3757611e37611d8e565b611e6860207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601611dbd565b818152846020838601011115611e7d57600080fd5b816020850160208301376000918101602001919091529392505050565b60008060008060808587031215611eb057600080fd5b611eb985611be0565b9350611ec760208601611be0565b925060408501359150606085013567ffffffffffffffff811115611eea57600080fd5b611ef687828801611e0c565b91505092959194509250565b60008060408385031215611f1557600080fd5b82359150611f2560208401611be0565b90509250929050565b60008083601f840112611f4057600080fd5b50813567ffffffffffffffff811115611f5857600080fd5b6020830191508360208260051b8501011115611c4b57600080fd5b600080600080600080600080600060c08a8c031215611f9157600080fd5b893567ffffffffffffffff80821115611fa957600080fd5b611fb58d838e01611f2e565b909b50995060208c0135915080821115611fce57600080fd5b611fda8d838e01611f2e565b909950975060408c0135915080821115611ff357600080fd5b506120008c828d01611f2e565b9a9d999c50979a969997986060880135976080810135975060a0013595509350505050565b60008060008060008060008060a0898b03121561204157600080fd5b883567ffffffffffffffff8082111561205957600080fd5b6120658c838d01611f2e565b909a50985060208b013591508082111561207e57600080fd5b61208a8c838d01611f2e565b909850965060408b01359150808211156120a357600080fd5b506120b08b828c01611f2e565b999c989b509699959896976060870135966080013595509350505050565b600082601f8301126120df57600080fd5b8135602067ffffffffffffffff8211156120fb576120fb611d8e565b8160051b61210a828201611dbd565b928352848101820192828101908785111561212457600080fd5b83870192505b848310156121435782358252918301919083019061212a565b979650505050505050565b600080600080600060a0868803121561216657600080fd5b61216f86611be0565b945061217d60208701611be0565b9350604086013567ffffffffffffffff8082111561219a57600080fd5b6121a689838a016120ce565b945060608801359150808211156121bc57600080fd5b6121c889838a016120ce565b935060808801359150808211156121de57600080fd5b506121eb88828901611e0c565b9150509295509295909350565b600080600080600060a0868803121561221057600080fd5b61221986611be0565b945061222760208701611be0565b93506040860135925060608601359150608086013567ffffffffffffffff81111561225157600080fd5b6121eb88828901611e0c565b8183528181602085013750600060208284010152600060207fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f840116840101905092915050565b73ffffffffffffffffffffffffffffffffffffffff8716815285602082015260a0604082015260006122dc60a08301868861225d565b60608301949094525060800152949350505050565b73ffffffffffffffffffffffffffffffffffffffff8516815283602082015260606040820152600061232760608301848661225d565b9695505050505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006020828403121561237257600080fd5b6108f682611be0565b60008083357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18436030181126123b057600080fd5b83018035915067ffffffffffffffff8211156123cb57600080fd5b602001915036819003821315611c4b57600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203612440576124406123e0565b5060010190565b81835260006020808501808196508560051b810191508460005b878110156124ea57828403895281357fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe18836030181126124a057600080fd5b8701858101903567ffffffffffffffff8111156124bc57600080fd5b8036038213156124cb57600080fd5b6124d686828461225d565b9a87019a9550505090840190600101612461565b5091979650505050505050565b60a0808252810188905260008960c08301825b8b8110156125455773ffffffffffffffffffffffffffffffffffffffff61253084611be0565b1682526020928301929091019060010161250a565b5083810360208501528881527f07ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff89111561257e57600080fd5b8860051b9150818a602083013701828103602090810160408501526125a69082018789612447565b60608401959095525050608001529695505050505050565b6000602082840312156125d057600080fd5b815180151581146108f657600080fd5b808201808211156107d9576107d96123e0565b60005b8381101561260e5781810151838201526020016125f6565b50506000910152565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161264f8160178501602088016125f3565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000601791840191820152835161268c8160288401602088016125f3565b01602801949350505050565b60208152600082518060208401526126b78160408501602087016125f3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169190910160400192915050565b8183823760009101908152919050565b80820281158282048414176107d9576107d96123e0565b60008161271f5761271f6123e0565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff019056fea2646970667358221220c474c39da3523b28ebfa5fd66c05b42d6ddcc4a57055483bdda32888b366016164736f6c63430008140033", + "storage": { + "0x0000000000000000000000000000000000000000000000000000000000000002": "0x0000000000000000000000000000000000000000000000000000000000000e10", + "0xaedcc9e7897c0d335bdc5d92fe3a8b4f23727fe558cd1c19f332b28716a30559": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xf5e61edb9c9cc6bfbae4463e9a2b1dd6ac3b44ddef38f18016e56ba0363910d9": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x64494413541ff93b31aa309254e3fed72a7456e9845988b915b4c7a7ceba8814": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0x60b9d94c75b7b3f721925089391e4644cd890cb5e6466f9596dfbd2c54e0b280": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x3412d5605ac6cd444957cedb533e5dacad6378b4bc819ebe3652188a665066d6": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0x4b63b79f1e338a49559dcd3193ac9eecc50d0f275d24e97cc8c319e5a31a8bd0": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xdae2aa361dfd1ca020a396615627d436107c35eff9fe7738a3512819782d706a": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5", + "0x800d5dfe4bba53eedee06cd4546a27da8de00f12db83f56062976d4493fda899": "0x0000000000000000000000000000000000000000000000000000000000000001", + "0xc3ad33e20b0c56a223ad5104fff154aa010f8715b9c981fd38fdc60a4d1a52fc": "0x5f58e3a2316349923ce3780f8d587db2d72378aed66a8261c916544fa6846ca5" + } + }, + { + "accountName": "keyless Deployer", + "balance": "0", + "nonce": "1", + "address": "0x28BB4e66addE1f042B77E04cf7D3784C1dcDBbA3" + }, + { + "accountName": "deployer", + "balance": "100000000000000000000000", + "nonce": "8", + "address": "0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266" + } + ] + } \ No newline at end of file diff --git a/test/config/test.node.config.toml b/test/config/test.node.config.toml index 8d6a0d215d..5b7f467457 100644 --- a/test/config/test.node.config.toml +++ b/test/config/test.node.config.toml @@ -82,7 +82,7 @@ EnableL2SuggestedGasPricePolling = true SyncInterval = "1s" SyncChunkSize = 100 TrustedSequencerURL = "" # If it is empty or not specified, then the value is read from the smc. -L1SynchronizationMode = "parallel" +L1SynchronizationMode = "sequential" [Synchronizer.L1ParallelSynchronization] MaxClients = 10 MaxPendingNoProcessedBlocks = 25 diff --git a/test/docker-compose.yml b/test/docker-compose.yml index a501465771..e6efff39e6 100644 --- a/test/docker-compose.yml +++ b/test/docker-compose.yml @@ -453,7 +453,7 @@ services: zkevm-mock-l1-network: container_name: zkevm-mock-l1-network - image: hermeznetwork/geth-zkevm-contracts:v2.1.1-fork.7-geth1.12.0 + image: hermeznetwork/geth-zkevm-contracts:v2.1.3-fork.8-geth1.12.0 ports: - 8545:8545 - 8546:8546 @@ -513,7 +513,7 @@ services: zkevm-prover: container_name: zkevm-prover - image: hermeznetwork/zkevm-prover:v4.0.14 + image: hermeznetwork/zkevm-prover:v5.0.0-RC4 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.14 + image: hermeznetwork/zkevm-prover:v5.0.0-RC4 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover diff --git a/test/e2e/jsonrpc2_test.go b/test/e2e/jsonrpc2_test.go index 54b30e194a..b2a3a2598f 100644 --- a/test/e2e/jsonrpc2_test.go +++ b/test/e2e/jsonrpc2_test.go @@ -589,7 +589,10 @@ func TestEstimateGas(t *testing.T) { if testing.Short() { t.Skip() } + + log.Info("TestEstimateGas-------------------------------------------------------") setup() + defer opsMan.ShowDockerLogs() defer teardown() ctx := context.Background() @@ -729,6 +732,7 @@ func TestEstimateGas(t *testing.T) { for _, testCase := range testCases { t.Run(testCase.name, func(t *testing.T) { + log.Info("TestEstimateGas------------------------------------------------------- subcase: ", testCase.name) msg := ethereum.CallMsg{ To: txToMsg.To(), Data: txToMsg.Data(), diff --git a/test/e2e/shared.go b/test/e2e/shared.go index dba7639e71..b8dee27c09 100644 --- a/test/e2e/shared.go +++ b/test/e2e/shared.go @@ -31,6 +31,7 @@ const ( var ( toAddress = common.HexToAddress(toAddressHex) + opsMan *operations.Manager ) var networks = []struct { @@ -65,7 +66,7 @@ func setup() { } opsCfg := operations.GetDefaultOperationsConfig() - opsMan, err := operations.NewManager(ctx, opsCfg) + opsMan, err = operations.NewManager(ctx, opsCfg) if err != nil { panic(err) } diff --git a/test/scripts/batchsender/main.go b/test/scripts/batchsender/main.go index dfe583f54e..3a2c1f369f 100644 --- a/test/scripts/batchsender/main.go +++ b/test/scripts/batchsender/main.go @@ -173,14 +173,17 @@ func sendBatches(cliCtx *cli.Context) error { for i := 0; i < nb; i++ { // empty rollup seqs = append(seqs, ethmanTypes.Sequence{ - GlobalExitRoot: common.HexToHash("0x"), - BatchL2Data: []byte{}, - Timestamp: int64(currentBlock.Time() - 1), // fit in latest-sequence < > current-block rage + BatchNumber: uint64(i), + GlobalExitRoot: common.HexToHash("0x"), + BatchL2Data: []byte{}, + LastL2BLockTimestamp: int64(currentBlock.Time() - 1), // fit in latest-sequence < > current-block rage }) } // send to L1 - to, data, err := ethMan.BuildSequenceBatchesTxData(auth.From, seqs, auth.From) + firstSequence := seqs[0] + lastSequence := seqs[len(seqs)-1] + to, data, err := ethMan.BuildSequenceBatchesTxData(auth.From, seqs, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber, auth.From) if err != nil { return err } From fabe7ee15c7864224316da9eb365aee85e11087d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Wed, 21 Feb 2024 09:28:37 +0100 Subject: [PATCH 17/51] update prover image (#3322) * update prover image * udpate prover docker memory limits * downgrade prover * upgrade prover From f0093b0752333a646add4b16f26f679c5611ac0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Wed, 21 Feb 2024 11:58:57 +0100 Subject: [PATCH 18/51] Get last l2 block in a batch by batch number (#3335) * last l2 block by batch number * optimization * change returned err in query --- sequencesender/interfaces.go | 3 +- sequencesender/mock_state.go | 60 ++++++++++++++++---------------- sequencesender/sequencesender.go | 37 ++++++-------------- state/interfaces.go | 1 + state/mocks/mock_storage.go | 60 ++++++++++++++++++++++++++++++++ state/pgstatestorage/l2block.go | 22 ++++++++++++ 6 files changed, 124 insertions(+), 59 deletions(-) diff --git a/sequencesender/interfaces.go b/sequencesender/interfaces.go index 98b516a63a..6bb8be8a87 100644 --- a/sequencesender/interfaces.go +++ b/sequencesender/interfaces.go @@ -19,7 +19,6 @@ import ( type etherman interface { BuildSequenceBatchesTxData(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address) (to *common.Address, data []byte, err error) EstimateGasSequenceBatches(sender common.Address, sequences []ethmanTypes.Sequence, maxSequenceTimestamp uint64, initSequenceBatchNumber uint64, l2Coinbase common.Address) (*types.Transaction, error) - // GetLastBatchTimestamp() (uint64, error) GetLatestBlockHeader(ctx context.Context) (*types.Header, error) GetLatestBatchNumber() (uint64, error) } @@ -34,7 +33,7 @@ type stateInterface interface { GetTimeForLatestBatchVirtualization(ctx context.Context, dbTx pgx.Tx) (time.Time, error) GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) GetLastClosedBatch(ctx context.Context, dbTx pgx.Tx) (*state.Batch, error) - GetL2BlocksByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]state.L2Block, error) + GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.L2Block, error) GetBlockByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (*state.Block, error) } diff --git a/sequencesender/mock_state.go b/sequencesender/mock_state.go index 029e6dfc14..19b6fa3c56 100644 --- a/sequencesender/mock_state.go +++ b/sequencesender/mock_state.go @@ -108,36 +108,6 @@ func (_m *StateMock) GetForcedBatch(ctx context.Context, forcedBatchNumber uint6 return r0, r1 } -// GetL2BlocksByBatchNumber provides a mock function with given fields: ctx, batchNumber, dbTx -func (_m *StateMock) GetL2BlocksByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]state.L2Block, error) { - ret := _m.Called(ctx, batchNumber, dbTx) - - if len(ret) == 0 { - panic("no return value specified for GetL2BlocksByBatchNumber") - } - - var r0 []state.L2Block - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) ([]state.L2Block, error)); ok { - return rf(ctx, batchNumber, dbTx) - } - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) []state.L2Block); ok { - r0 = rf(ctx, batchNumber, dbTx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]state.L2Block) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok { - r1 = rf(ctx, batchNumber, dbTx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - // GetLastBatchNumber provides a mock function with given fields: ctx, dbTx func (_m *StateMock) GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) { ret := _m.Called(ctx, dbTx) @@ -196,6 +166,36 @@ func (_m *StateMock) GetLastClosedBatch(ctx context.Context, dbTx pgx.Tx) (*stat return r0, r1 } +// GetLastL2BlockByBatchNumber provides a mock function with given fields: ctx, batchNumber, dbTx +func (_m *StateMock) GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.L2Block, error) { + ret := _m.Called(ctx, batchNumber, dbTx) + + if len(ret) == 0 { + panic("no return value specified for GetLastL2BlockByBatchNumber") + } + + var r0 *state.L2Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) (*state.L2Block, error)); ok { + return rf(ctx, batchNumber, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) *state.L2Block); ok { + r0 = rf(ctx, batchNumber, dbTx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*state.L2Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok { + r1 = rf(ctx, batchNumber, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // GetLastVirtualBatchNum provides a mock function with given fields: ctx, dbTx func (_m *StateMock) GetLastVirtualBatchNum(ctx context.Context, dbTx pgx.Tx) (uint64, error) { ret := _m.Called(ctx, dbTx) diff --git a/sequencesender/sequencesender.go b/sequencesender/sequencesender.go index 30e8c9f0c4..674fce1a25 100644 --- a/sequencesender/sequencesender.go +++ b/sequencesender/sequencesender.go @@ -139,25 +139,10 @@ func (s *SequenceSender) tryToSendSequence(ctx context.Context) { metrics.SequencesSentToL1(float64(sequenceCount)) // Check if we need to wait until last L1 block timestamp is L1BlockTimestampMargin seconds above the timestamp of the last L2 block in the sequence - // Get last batch in the sequence - lastSequenceBatchNum := sequences[sequenceCount-1].BatchNumber - - // Get L2 blocks for the last batch - lastBatchL2Blocks, err := s.state.GetL2BlocksByBatchNumber(ctx, lastSequenceBatchNum, nil) - if err != nil { - log.Errorf("failed to get L2 blocks for batch %d, err: %v", lastSequenceBatchNum, err) - return - } - - // Check there are L2 blocks for the last batch - if len(lastBatchL2Blocks) == 0 { - log.Errorf("no L2 blocks returned from the state for batch %d", lastSequenceBatchNum) - return - } - + // Get last sequence + lastSequence := sequences[sequenceCount-1] // Get timestamp of the last L2 block in the sequence - lastL2Block := lastBatchL2Blocks[len(lastBatchL2Blocks)-1] - lastL2BlockTimestamp := uint64(lastL2Block.ReceivedAt.Unix()) + lastL2BlockTimestamp := uint64(lastSequence.LastL2BLockTimestamp) timeMargin := int64(s.cfg.L1BlockTimestampMargin.Seconds()) @@ -174,11 +159,11 @@ func (s *SequenceSender) tryToSendSequence(ctx context.Context) { if !elapsed { log.Infof("waiting at least %d seconds to send sequences, time difference between last L1 block %d (ts: %d) and last L2 block %d (ts: %d) in the sequence is lower than %d seconds", - waitTime, lastL1BlockHeader.Number, lastL1BlockHeader.Time, lastL2Block.Number(), lastL2BlockTimestamp, timeMargin) + waitTime, lastL1BlockHeader.Number, lastL1BlockHeader.Time, lastSequence.BatchNumber, lastL2BlockTimestamp, timeMargin) time.Sleep(time.Duration(waitTime) * time.Second) } else { log.Infof("continuing, time difference between last L1 block %d (ts: %d) and last L2 block %d (ts: %d) in the sequence is greater than %d seconds", - lastL1BlockHeader.Number, lastL1BlockHeader.Time, lastL2Block.Number(), lastL2BlockTimestamp, timeMargin) + lastL1BlockHeader.Number, lastL1BlockHeader.Time, lastSequence.BatchNumber, lastL2BlockTimestamp, timeMargin) break } } @@ -192,18 +177,17 @@ func (s *SequenceSender) tryToSendSequence(ctx context.Context) { // Wait if the time difference is less than timeMargin (L1BlockTimestampMargin) if !elapsed { log.Infof("waiting at least %d seconds to send sequences, time difference between now (ts: %d) and last L2 block %d (ts: %d) in the sequence is lower than %d seconds", - waitTime, currentTime, lastL2Block.Number(), lastL2BlockTimestamp, timeMargin) + waitTime, currentTime, lastSequence.BatchNumber, lastL2BlockTimestamp, timeMargin) time.Sleep(time.Duration(waitTime) * time.Second) } else { log.Infof("sending sequences now, time difference between now (ts: %d) and last L2 block %d (ts: %d) in the sequence is also greater than %d seconds", - currentTime, lastL2Block.Number(), lastL2BlockTimestamp, timeMargin) + currentTime, lastSequence.BatchNumber, lastL2BlockTimestamp, timeMargin) break } } // add sequence to be monitored firstSequence := sequences[0] - lastSequence := sequences[len(sequences)-1] to, data, err := s.etherman.BuildSequenceBatchesTxData(s.cfg.SenderAddress, sequences, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber-1, s.cfg.L2Coinbase) if err != nil { @@ -292,16 +276,15 @@ func (s *SequenceSender) getSequencesToSend(ctx context.Context) ([]types.Sequen seq.LastL2BLockTimestamp = seq.ForcedBatchTimestamp } else { // Set sequence timestamps as the latest l2 block timestamp - l2Blocks, err := s.state.GetL2BlocksByBatchNumber(ctx, currentBatchNumToSequence, nil) + lastL2Block, err := s.state.GetLastL2BlockByBatchNumber(ctx, currentBatchNumToSequence, nil) if err != nil { return nil, err } - if len(l2Blocks) == 0 { - return nil, fmt.Errorf("no L2 blocks returned from the state for batch %d", currentBatchNumToSequence) + if lastL2Block == nil { + return nil, fmt.Errorf("no last L2 block returned from the state for batch %d", currentBatchNumToSequence) } // Get timestamp of the last L2 block in the sequence - lastL2Block := l2Blocks[len(l2Blocks)-1] seq.LastL2BLockTimestamp = lastL2Block.ReceivedAt.Unix() } diff --git a/state/interfaces.go b/state/interfaces.go index f6b5859a80..0f658e14a5 100644 --- a/state/interfaces.go +++ b/state/interfaces.go @@ -157,4 +157,5 @@ type storage interface { IsBatchChecked(ctx context.Context, batchNum uint64, dbTx pgx.Tx) (bool, error) UpdateBatchAsChecked(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error GetNotCheckedBatches(ctx context.Context, dbTx pgx.Tx) ([]*Batch, error) + GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*L2Block, error) } diff --git a/state/mocks/mock_storage.go b/state/mocks/mock_storage.go index 4856aa7e41..a8881340ea 100644 --- a/state/mocks/mock_storage.go +++ b/state/mocks/mock_storage.go @@ -3875,6 +3875,66 @@ func (_c *StorageMock_GetLastL2Block_Call) RunAndReturn(run func(context.Context return _c } +// GetLastL2BlockByBatchNumber provides a mock function with given fields: ctx, batchNumber, dbTx +func (_m *StorageMock) GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.L2Block, error) { + ret := _m.Called(ctx, batchNumber, dbTx) + + if len(ret) == 0 { + panic("no return value specified for GetLastL2BlockByBatchNumber") + } + + var r0 *state.L2Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) (*state.L2Block, error)); ok { + return rf(ctx, batchNumber, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) *state.L2Block); ok { + r0 = rf(ctx, batchNumber, dbTx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*state.L2Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok { + r1 = rf(ctx, batchNumber, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StorageMock_GetLastL2BlockByBatchNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLastL2BlockByBatchNumber' +type StorageMock_GetLastL2BlockByBatchNumber_Call struct { + *mock.Call +} + +// GetLastL2BlockByBatchNumber is a helper method to define mock.On call +// - ctx context.Context +// - batchNumber uint64 +// - dbTx pgx.Tx +func (_e *StorageMock_Expecter) GetLastL2BlockByBatchNumber(ctx interface{}, batchNumber interface{}, dbTx interface{}) *StorageMock_GetLastL2BlockByBatchNumber_Call { + return &StorageMock_GetLastL2BlockByBatchNumber_Call{Call: _e.mock.On("GetLastL2BlockByBatchNumber", ctx, batchNumber, dbTx)} +} + +func (_c *StorageMock_GetLastL2BlockByBatchNumber_Call) Run(run func(ctx context.Context, batchNumber uint64, dbTx pgx.Tx)) *StorageMock_GetLastL2BlockByBatchNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(pgx.Tx)) + }) + return _c +} + +func (_c *StorageMock_GetLastL2BlockByBatchNumber_Call) Return(_a0 *state.L2Block, _a1 error) *StorageMock_GetLastL2BlockByBatchNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *StorageMock_GetLastL2BlockByBatchNumber_Call) RunAndReturn(run func(context.Context, uint64, pgx.Tx) (*state.L2Block, error)) *StorageMock_GetLastL2BlockByBatchNumber_Call { + _c.Call.Return(run) + return _c +} + // GetLastL2BlockCreatedAt provides a mock function with given fields: ctx, dbTx func (_m *StorageMock) GetLastL2BlockCreatedAt(ctx context.Context, dbTx pgx.Tx) (*time.Time, error) { ret := _m.Called(ctx, dbTx) diff --git a/state/pgstatestorage/l2block.go b/state/pgstatestorage/l2block.go index 1b29e87b4d..f86b10d26d 100644 --- a/state/pgstatestorage/l2block.go +++ b/state/pgstatestorage/l2block.go @@ -93,6 +93,28 @@ func (p *PostgresStorage) GetL2BlocksByBatchNumber(ctx context.Context, batchNum return l2Blocks, nil } +// GetLastL2BlockByBatchNumber gets the last l2 block in a batch by batch number +func (p *PostgresStorage) GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.L2Block, error) { + const query = "SELECT block_hash, header, uncles, received_at FROM state.l2block b WHERE batch_num = $1 ORDER BY b.block_num DESC LIMIT 1" + + q := p.getExecQuerier(dbTx) + row := q.QueryRow(ctx, query, batchNumber) + header, uncles, receivedAt, err := p.scanL2BlockInfo(ctx, row, dbTx) + if err != nil { + return nil, err + } + + transactions, err := p.GetTxsByBlockNumber(ctx, header.Number.Uint64(), dbTx) + if errors.Is(err, pgx.ErrNoRows) { + transactions = []*types.Transaction{} + } else if err != nil { + return nil, err + } + + block := buildBlock(header, transactions, uncles, receivedAt) + return block, nil +} + func (p *PostgresStorage) scanL2BlockInfo(ctx context.Context, rows pgx.Row, dbTx pgx.Tx) (header *state.L2Header, uncles []*state.L2Header, receivedAt time.Time, err error) { header = &state.L2Header{} uncles = []*state.L2Header{} From c091cfbb2494330ebe8d081fb0bb7b68aff20dbf Mon Sep 17 00:00:00 2001 From: Joan Esteban <129153821+joanestebanr@users.noreply.github.com> Date: Wed, 21 Feb 2024 15:58:28 +0100 Subject: [PATCH 19/51] add selector for trusted sync to prevent from executing from an old trusted node (#3336) * add selector for trusted sync to check that batches correspond to the supported forkids --- etherman/etherman_test.go | 9 +-- state/forkid.go | 2 + .../processor_l1_sequence_batches.go | 2 +- .../sync_trusted_state_executor.go | 2 + .../processor_trusted_batch_selector.go | 56 +++++++++--------- .../processor_trusted_batch_selector_test.go | 58 +++++++++++++++---- synchronizer/synchronizer.go | 8 ++- synchronizer/synchronizer_test.go | 19 ++++++ 8 files changed, 107 insertions(+), 49 deletions(-) diff --git a/etherman/etherman_test.go b/etherman/etherman_test.go index 789e2831af..a49906765b 100644 --- a/etherman/etherman_test.go +++ b/etherman/etherman_test.go @@ -123,9 +123,6 @@ func TestForcedBatchEvent(t *testing.T) { assert.Equal(t, auth.From, blocks[0].ForcedBatches[0].Sequencer) } -// TODO: Review tests with Joan - -/* func TestSequencedBatchesEvent(t *testing.T) { // Set up testing environment etherman, ethBackend, auth, _, br := newTestingEnv() @@ -165,8 +162,7 @@ func TestSequencedBatchesEvent(t *testing.T) { }, polygonzkevm.PolygonRollupBaseEtrogBatchData{ Transactions: common.Hex2Bytes(rawTxs), }) - // TODO: Fix params - _, err = etherman.ZkEVM.SequenceBatches(auth, sequences, 0, 0, auth.From) + _, err = etherman.ZkEVM.SequenceBatches(auth, sequences, uint64(time.Now().Unix()), uint64(1), auth.From) require.NoError(t, err) // Mine the tx in a block @@ -205,7 +201,7 @@ func TestVerifyBatchEvent(t *testing.T) { Transactions: common.Hex2Bytes(rawTxs), } //TODO: Fix params - _, err = etherman.ZkEVM.SequenceBatches(auth, []polygonzkevm.PolygonRollupBaseEtrogBatchData{tx}, 0, 0, auth.From) + _, err = etherman.ZkEVM.SequenceBatches(auth, []polygonzkevm.PolygonRollupBaseEtrogBatchData{tx}, uint64(time.Now().Unix()), uint64(1), auth.From) require.NoError(t, err) // Mine the tx in a block @@ -233,7 +229,6 @@ func TestVerifyBatchEvent(t *testing.T) { assert.Equal(t, 0, order[blocks[1].BlockHash][0].Pos) assert.Equal(t, 0, order[blocks[1].BlockHash][1].Pos) } -*/ func TestSequenceForceBatchesEvent(t *testing.T) { // Set up testing environment diff --git a/state/forkid.go b/state/forkid.go index d906201135..0db73fc996 100644 --- a/state/forkid.go +++ b/state/forkid.go @@ -15,6 +15,8 @@ const ( FORKID_INCABERRY = 6 // FORKID_ETROG is the fork id 7 FORKID_ETROG = 7 + // FORKID_ELDERBERRY is the fork id 8 + FORKID_ELDERBERRY = 8 ) // ForkIDInterval is a fork id interval diff --git a/synchronizer/actions/elderberry/processor_l1_sequence_batches.go b/synchronizer/actions/elderberry/processor_l1_sequence_batches.go index f159badc48..87bf1fb468 100644 --- a/synchronizer/actions/elderberry/processor_l1_sequence_batches.go +++ b/synchronizer/actions/elderberry/processor_l1_sequence_batches.go @@ -118,7 +118,7 @@ func (g *ProcessorL1SequenceBatchesElderberry) sanityCheckTstampLastL2Block(time return nil } lastL2Block := l2blocks[len(l2blocks)-1] - if uint64(lastL2Block.ReceivedAt.Unix()) <= timeLimit { + if uint64(lastL2Block.ReceivedAt.Unix()) > timeLimit { log.Errorf("The last L2 block timestamp can't be greater than timeLimit. Expected: %d (L1 event), got: %d (last L2Block)", timeLimit, lastL2Block.ReceivedAt.Unix()) return fmt.Errorf("wrong timestamp of last L2 block timestamp with L1 event timestamp") } diff --git a/synchronizer/common/syncinterfaces/sync_trusted_state_executor.go b/synchronizer/common/syncinterfaces/sync_trusted_state_executor.go index b01f465c86..906cc73c26 100644 --- a/synchronizer/common/syncinterfaces/sync_trusted_state_executor.go +++ b/synchronizer/common/syncinterfaces/sync_trusted_state_executor.go @@ -12,6 +12,8 @@ var ( ErrMissingSyncFromL1 = errors.New("must sync from L1") // ErrFatalDesyncFromL1 is returned when trusted node and permissionless node have different data ErrFatalDesyncFromL1 = errors.New("fatal situation: the TrustedNode have another data!. Halt or do something") + // ErrCantSyncFromL2 is returned when can't sync from L2, for example the forkid is not supported by L2 sync + ErrCantSyncFromL2 = errors.New("can't sync from L2") ) // SyncTrustedStateExecutor is the interface that class that synchronize permissionless with a trusted node diff --git a/synchronizer/l2_sync/l2_shared/processor_trusted_batch_selector.go b/synchronizer/l2_sync/l2_shared/processor_trusted_batch_selector.go index 82c3f6fc71..4e596b6947 100644 --- a/synchronizer/l2_sync/l2_shared/processor_trusted_batch_selector.go +++ b/synchronizer/l2_sync/l2_shared/processor_trusted_batch_selector.go @@ -2,9 +2,7 @@ package l2_shared /* This class is a implementation of SyncTrustedStateExecutor that selects the executor to use. -It's ready to switch between pre-etrog and etrog as soon as the forkid 7 is activated. - -When ForkId7 is activated, the executor will be switched to etrog for forkid7 batches. +It have a map with the forkID and the executor class to use, if none is available skip trusted sync returning a nil */ import ( @@ -15,48 +13,46 @@ import ( "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces" ) -const etrogForkId = uint64(7) - type stateSyncTrustedStateExecutorSelector interface { GetForkIDInMemory(forkId uint64) *state.ForkIDInterval + GetForkIDByBatchNumber(batchNumber uint64) uint64 } // SyncTrustedStateExecutorSelector Implements SyncTrustedStateExecutor type SyncTrustedStateExecutorSelector struct { - executorPreEtrog syncinterfaces.SyncTrustedStateExecutor - executorEtrog syncinterfaces.SyncTrustedStateExecutor - state stateSyncTrustedStateExecutorSelector + state stateSyncTrustedStateExecutorSelector + supportedForks map[uint64]syncinterfaces.SyncTrustedStateExecutor } // NewSyncTrustedStateExecutorSelector creates a new SyncTrustedStateExecutorSelector that implements SyncTrustedStateExecutor func NewSyncTrustedStateExecutorSelector( - preEtrog syncinterfaces.SyncTrustedStateExecutor, - etrog syncinterfaces.SyncTrustedStateExecutor, + supportedForks map[uint64]syncinterfaces.SyncTrustedStateExecutor, state stateSyncTrustedStateExecutorSelector) *SyncTrustedStateExecutorSelector { return &SyncTrustedStateExecutorSelector{ - executorPreEtrog: preEtrog, - executorEtrog: etrog, - state: state, + supportedForks: supportedForks, + state: state, } } // GetExecutor returns the executor that should be used for the given batch, could be nil // it returns the executor and the maximum batch number that the executor can process func (s *SyncTrustedStateExecutorSelector) GetExecutor(latestSyncedBatch uint64, maximumBatchNumberToProcess uint64) (syncinterfaces.SyncTrustedStateExecutor, uint64) { - fork := s.state.GetForkIDInMemory(etrogForkId) + forkIDForNextBatch := s.state.GetForkIDByBatchNumber(latestSyncedBatch + 1) + executor, ok := s.supportedForks[forkIDForNextBatch] + if !ok { + log.Warnf("No supported sync from Trusted Node for forkID %d", forkIDForNextBatch) + return nil, 0 + } + fork := s.state.GetForkIDInMemory(forkIDForNextBatch) if fork == nil { - log.Debugf("ForkId7 not activated yet, using pre-etrog executor") - return s.executorPreEtrog, maximumBatchNumberToProcess + log.Errorf("ForkID %d range not available! that is UB", forkIDForNextBatch) + return nil, 0 } - if latestSyncedBatch+1 >= fork.FromBatchNumber { - log.Debugf("ForkId7 activated, batch:%d -> etrog executor", latestSyncedBatch) - return s.executorEtrog, maximumBatchNumberToProcess - } - maxCapped := min(maximumBatchNumberToProcess, fork.FromBatchNumber-1) - log.Debugf("ForkId7 activated, batch:%d -> pre-etrog executor (maxBatch from:%d to %d)", + maxCapped := min(maximumBatchNumberToProcess, fork.ToBatchNumber) + log.Debugf("using ForkID %d, lastBatch:%d (maxBatch original:%d capped:%d)", forkIDForNextBatch, latestSyncedBatch, maximumBatchNumberToProcess, maxCapped) - return s.executorPreEtrog, maxCapped + return executor, maxCapped } // SyncTrustedState syncs the trusted state with the permissionless state. In this case @@ -64,25 +60,25 @@ func (s *SyncTrustedStateExecutorSelector) GetExecutor(latestSyncedBatch uint64, func (s *SyncTrustedStateExecutorSelector) SyncTrustedState(ctx context.Context, latestSyncedBatch uint64, maximumBatchNumberToProcess uint64) error { executor, maxBatchNumber := s.GetExecutor(latestSyncedBatch, maximumBatchNumberToProcess) if executor == nil { - log.Warnf("No executor selected, skipping SyncTrustedState: latestSyncedBatch:%d, maximumBatchNumberToProcess:%d", + log.Warnf("No executor available, skipping SyncTrustedState: latestSyncedBatch:%d, maximumBatchNumberToProcess:%d", latestSyncedBatch, maximumBatchNumberToProcess) - return nil + return syncinterfaces.ErrCantSyncFromL2 } return executor.SyncTrustedState(ctx, latestSyncedBatch, maxBatchNumber) } // CleanTrustedState clean cache of Batches and StateRoot func (s *SyncTrustedStateExecutorSelector) CleanTrustedState() { - if s.executorPreEtrog != nil { - s.executorPreEtrog.CleanTrustedState() - } - if s.executorEtrog != nil { - s.executorEtrog.CleanTrustedState() + for _, executor := range s.supportedForks { + executor.CleanTrustedState() } } // GetCachedBatch implements syncinterfaces.SyncTrustedStateExecutor. Returns a cached batch func (s *SyncTrustedStateExecutorSelector) GetCachedBatch(batchNumber uint64) *state.Batch { executor, _ := s.GetExecutor(batchNumber, 0) + if executor == nil { + return nil + } return executor.GetCachedBatch(min(batchNumber)) } diff --git a/synchronizer/l2_sync/l2_shared/tests/processor_trusted_batch_selector_test.go b/synchronizer/l2_sync/l2_shared/tests/processor_trusted_batch_selector_test.go index d494d7bd99..0efa0f8b22 100644 --- a/synchronizer/l2_sync/l2_shared/tests/processor_trusted_batch_selector_test.go +++ b/synchronizer/l2_sync/l2_shared/tests/processor_trusted_batch_selector_test.go @@ -1,9 +1,11 @@ package test_l2_shared import ( + "context" "testing" "github.com/0xPolygonHermez/zkevm-node/state" + "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces" mock_syncinterfaces "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces/mocks" "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared" "github.com/stretchr/testify/require" @@ -14,29 +16,41 @@ import ( // expected: // - -func TestExecutorSelectorIncaberryBatchNoForkId7(t *testing.T) { +func TestExecutorSelectorFirstConfiguredExecutor(t *testing.T) { mockIncaberry := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) mock1Etrog := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) mockState := mock_syncinterfaces.NewStateFullInterface(t) - mockState.EXPECT().GetForkIDInMemory(uint64(7)).Return(nil) - sut := l2_shared.NewSyncTrustedStateExecutorSelector(mockIncaberry, mock1Etrog, mockState) + mockState.EXPECT().GetForkIDByBatchNumber(uint64(1 + 1)).Return(uint64(6)) + forkIdInterval := state.ForkIDInterval{ + FromBatchNumber: 0, + ToBatchNumber: ^uint64(0), + } + mockState.EXPECT().GetForkIDInMemory(uint64(6)).Return(&forkIdInterval) + sut := l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ + uint64(6): mockIncaberry, + uint64(7): mock1Etrog, + }, mockState) executor, maxBatch := sut.GetExecutor(1, 200) require.Equal(t, mockIncaberry, executor) require.Equal(t, uint64(200), maxBatch) } -func TestExecutorSelectorIncaberryBatchForkId7(t *testing.T) { +func TestExecutorSelectorFirstExecutorCapped(t *testing.T) { mockIncaberry := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) mock1Etrog := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) mockState := mock_syncinterfaces.NewStateFullInterface(t) interval := state.ForkIDInterval{ - FromBatchNumber: 100, - ToBatchNumber: 200, - ForkId: 7, + FromBatchNumber: 1, + ToBatchNumber: 99, + ForkId: 6, } - mockState.EXPECT().GetForkIDInMemory(uint64(7)).Return(&interval) - sut := l2_shared.NewSyncTrustedStateExecutorSelector(mockIncaberry, mock1Etrog, mockState) + mockState.EXPECT().GetForkIDByBatchNumber(uint64(1 + 1)).Return(uint64(6)) + mockState.EXPECT().GetForkIDInMemory(uint64(6)).Return(&interval) + sut := l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ + uint64(6): mockIncaberry, + uint64(7): mock1Etrog, + }, mockState) executor, maxBatch := sut.GetExecutor(1, 200) require.Equal(t, mockIncaberry, executor) @@ -52,10 +66,34 @@ func TestExecutorSelectorEtrogBatchForkId7(t *testing.T) { ToBatchNumber: 300, ForkId: 7, } + mockState.EXPECT().GetForkIDByBatchNumber(uint64(100 + 1)).Return(uint64(7)) mockState.EXPECT().GetForkIDInMemory(uint64(7)).Return(&interval) - sut := l2_shared.NewSyncTrustedStateExecutorSelector(mockIncaberry, mock1Etrog, mockState) + sut := l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ + uint64(6): mockIncaberry, + uint64(7): mock1Etrog, + }, mockState) executor, maxBatch := sut.GetExecutor(100, 200) require.Equal(t, mockIncaberry, executor) require.Equal(t, uint64(200), maxBatch) } + +func TestUnsupportedForkId(t *testing.T) { + mockIncaberry := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) + mock1Etrog := mock_syncinterfaces.NewSyncTrustedStateExecutor(t) + mockState := mock_syncinterfaces.NewStateFullInterface(t) + + mockState.EXPECT().GetForkIDByBatchNumber(uint64(100 + 1)).Return(uint64(8)) + + sut := l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ + uint64(6): mockIncaberry, + uint64(7): mock1Etrog, + }, mockState) + + executor, _ := sut.GetExecutor(100, 200) + require.Equal(t, nil, executor) + + err := sut.SyncTrustedState(context.Background(), 100, 200) + require.ErrorIs(t, err, syncinterfaces.ErrCantSyncFromL2) + +} diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 26b8df4d6e..54bfd5077d 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -114,7 +114,11 @@ func NewSynchronizer( syncTrustedStateEtrog := l2_sync_etrog.NewSyncTrustedBatchExecutorForEtrog(res.zkEVMClient, res.state, res.state, res, syncCommon.DefaultTimeProvider{}, L1SyncChecker) - res.syncTrustedStateExecutor = syncTrustedStateEtrog + res.syncTrustedStateExecutor = l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ + uint64(state.FORKID_ETROG): syncTrustedStateEtrog, + uint64(state.FORKID_ELDERBERRY): syncTrustedStateEtrog, + }, res.state) + res.l1EventProcessors = defaultsL1EventProcessors(res) switch cfg.L1SynchronizationMode { case ParallelMode: @@ -383,6 +387,8 @@ func (s *ClientSynchronizer) Sync() error { } } else if errors.Is(err, syncinterfaces.ErrMissingSyncFromL1) { log.Info("Syncing from trusted node need data from L1") + } else if errors.Is(err, syncinterfaces.ErrCantSyncFromL2) { + log.Info("Can't sync from L2, going to sync from L1") } else { // We break for resync from Trusted log.Debug("Sleeping for 1 second to avoid respawn too fast, error: ", err) diff --git a/synchronizer/synchronizer_test.go b/synchronizer/synchronizer_test.go index 226a4a4537..bdf3b505b6 100644 --- a/synchronizer/synchronizer_test.go +++ b/synchronizer/synchronizer_test.go @@ -56,6 +56,13 @@ func TestGivenPermissionlessNodeWhenSyncronizeAgainSameBatchThenUseTheOneInMemor batch10With3Tx := createBatch(t, lastBatchNumber, 3, ETROG_MODE_FLAG) previousBatch09 := createBatch(t, lastBatchNumber-1, 1, ETROG_MODE_FLAG) + forkIdInterval := state.ForkIDInterval{ + FromBatchNumber: 0, + ToBatchNumber: ^uint64(0), + } + m.State.EXPECT().GetForkIDInMemory(uint64(7)).Return(&forkIdInterval) + m.State.EXPECT().GetForkIDByBatchNumber(lastBatchNumber + 1).Return(uint64(7)) + expectedCallsForsyncTrustedState(t, m, sync, nil, batch10With2Tx, previousBatch09, RETRIEVE_BATCH_FROM_DB_FLAG, ETROG_MODE_FLAG) // Is the first time that appears this batch, so it need to OpenBatch expectedCallsForOpenBatch(t, m, sync, lastBatchNumber) @@ -89,6 +96,13 @@ func TestGivenPermissionlessNodeWhenSyncronizeFirstTimeABatchThenStoreItInALocal batch10With2Tx := createBatch(t, lastBatchNumber, 2, ETROG_MODE_FLAG) previousBatch09 := createBatch(t, lastBatchNumber-1, 1, ETROG_MODE_FLAG) + forkIdInterval := state.ForkIDInterval{ + FromBatchNumber: 0, + ToBatchNumber: ^uint64(0), + } + m.State.EXPECT().GetForkIDInMemory(uint64(7)).Return(&forkIdInterval) + m.State.EXPECT().GetForkIDByBatchNumber(lastBatchNumber + 1).Return(uint64(7)) + // This is a incremental process, permissionless have batch10With1Tx and we add a new block // but the cache doesnt have this information so it need to get from db expectedCallsForsyncTrustedState(t, m, sync, batch10With1Tx, batch10With2Tx, previousBatch09, RETRIEVE_BATCH_FROM_DB_FLAG, ETROG_MODE_FLAG) @@ -126,6 +140,11 @@ func TestForcedBatchEtrog(t *testing.T) { // state preparation ctxMatchBy := mock.MatchedBy(func(ctx context.Context) bool { return ctx != nil }) + forkIdInterval := state.ForkIDInterval{ + FromBatchNumber: 0, + ToBatchNumber: ^uint64(0), + } + m.State.EXPECT().GetForkIDInMemory(uint64(7)).Return(&forkIdInterval) m.State. On("BeginStateTransaction", ctxMatchBy). From a86d44474a1e34ccea420366be049c4dbba83f65 Mon Sep 17 00:00:00 2001 From: Joan Esteban <129153821+joanestebanr@users.noreply.github.com> Date: Wed, 21 Feb 2024 17:17:53 +0100 Subject: [PATCH 20/51] synchronizer adopt GetLastL2BlockByBatchNumber to check elderberry tstamp baches (#3340) * synchronizer adopt GetLastL2BlockByBatchNumber to check elderberry bacthes tstamp --- .../state_l1_sequence_batches_elderberry.go | 30 ++--- .../processor_l1_sequence_batches.go | 7 +- .../mocks/state_full_interface.go | 120 +++++++++--------- synchronizer/common/syncinterfaces/state.go | 2 +- test/Makefile | 2 +- 5 files changed, 80 insertions(+), 81 deletions(-) diff --git a/synchronizer/actions/elderberry/mocks/state_l1_sequence_batches_elderberry.go b/synchronizer/actions/elderberry/mocks/state_l1_sequence_batches_elderberry.go index 61cd625e75..0dbea72eda 100644 --- a/synchronizer/actions/elderberry/mocks/state_l1_sequence_batches_elderberry.go +++ b/synchronizer/actions/elderberry/mocks/state_l1_sequence_batches_elderberry.go @@ -25,24 +25,24 @@ func (_m *StateL1SequenceBatchesElderberry) EXPECT() *StateL1SequenceBatchesElde return &StateL1SequenceBatchesElderberry_Expecter{mock: &_m.Mock} } -// GetL2BlocksByBatchNumber provides a mock function with given fields: ctx, batchNumber, dbTx -func (_m *StateL1SequenceBatchesElderberry) GetL2BlocksByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]state.L2Block, error) { +// GetLastL2BlockByBatchNumber provides a mock function with given fields: ctx, batchNumber, dbTx +func (_m *StateL1SequenceBatchesElderberry) GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.L2Block, error) { ret := _m.Called(ctx, batchNumber, dbTx) if len(ret) == 0 { - panic("no return value specified for GetL2BlocksByBatchNumber") + panic("no return value specified for GetLastL2BlockByBatchNumber") } - var r0 []state.L2Block + var r0 *state.L2Block var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) ([]state.L2Block, error)); ok { + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) (*state.L2Block, error)); ok { return rf(ctx, batchNumber, dbTx) } - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) []state.L2Block); ok { + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) *state.L2Block); ok { r0 = rf(ctx, batchNumber, dbTx) } else { if ret.Get(0) != nil { - r0 = ret.Get(0).([]state.L2Block) + r0 = ret.Get(0).(*state.L2Block) } } @@ -55,32 +55,32 @@ func (_m *StateL1SequenceBatchesElderberry) GetL2BlocksByBatchNumber(ctx context return r0, r1 } -// StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetL2BlocksByBatchNumber' -type StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call struct { +// StateL1SequenceBatchesElderberry_GetLastL2BlockByBatchNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLastL2BlockByBatchNumber' +type StateL1SequenceBatchesElderberry_GetLastL2BlockByBatchNumber_Call struct { *mock.Call } -// GetL2BlocksByBatchNumber is a helper method to define mock.On call +// GetLastL2BlockByBatchNumber is a helper method to define mock.On call // - ctx context.Context // - batchNumber uint64 // - dbTx pgx.Tx -func (_e *StateL1SequenceBatchesElderberry_Expecter) GetL2BlocksByBatchNumber(ctx interface{}, batchNumber interface{}, dbTx interface{}) *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call { - return &StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call{Call: _e.mock.On("GetL2BlocksByBatchNumber", ctx, batchNumber, dbTx)} +func (_e *StateL1SequenceBatchesElderberry_Expecter) GetLastL2BlockByBatchNumber(ctx interface{}, batchNumber interface{}, dbTx interface{}) *StateL1SequenceBatchesElderberry_GetLastL2BlockByBatchNumber_Call { + return &StateL1SequenceBatchesElderberry_GetLastL2BlockByBatchNumber_Call{Call: _e.mock.On("GetLastL2BlockByBatchNumber", ctx, batchNumber, dbTx)} } -func (_c *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call) Run(run func(ctx context.Context, batchNumber uint64, dbTx pgx.Tx)) *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call { +func (_c *StateL1SequenceBatchesElderberry_GetLastL2BlockByBatchNumber_Call) Run(run func(ctx context.Context, batchNumber uint64, dbTx pgx.Tx)) *StateL1SequenceBatchesElderberry_GetLastL2BlockByBatchNumber_Call { _c.Call.Run(func(args mock.Arguments) { run(args[0].(context.Context), args[1].(uint64), args[2].(pgx.Tx)) }) return _c } -func (_c *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call) Return(_a0 []state.L2Block, _a1 error) *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call { +func (_c *StateL1SequenceBatchesElderberry_GetLastL2BlockByBatchNumber_Call) Return(_a0 *state.L2Block, _a1 error) *StateL1SequenceBatchesElderberry_GetLastL2BlockByBatchNumber_Call { _c.Call.Return(_a0, _a1) return _c } -func (_c *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call) RunAndReturn(run func(context.Context, uint64, pgx.Tx) ([]state.L2Block, error)) *StateL1SequenceBatchesElderberry_GetL2BlocksByBatchNumber_Call { +func (_c *StateL1SequenceBatchesElderberry_GetLastL2BlockByBatchNumber_Call) RunAndReturn(run func(context.Context, uint64, pgx.Tx) (*state.L2Block, error)) *StateL1SequenceBatchesElderberry_GetLastL2BlockByBatchNumber_Call { _c.Call.Return(run) return _c } diff --git a/synchronizer/actions/elderberry/processor_l1_sequence_batches.go b/synchronizer/actions/elderberry/processor_l1_sequence_batches.go index 87bf1fb468..b7a9dd6653 100644 --- a/synchronizer/actions/elderberry/processor_l1_sequence_batches.go +++ b/synchronizer/actions/elderberry/processor_l1_sequence_batches.go @@ -27,7 +27,7 @@ type PreviousProcessor interface { // StateL1SequenceBatchesElderberry state interface type StateL1SequenceBatchesElderberry interface { GetLastVirtualBatchNum(ctx context.Context, dbTx pgx.Tx) (uint64, error) - GetL2BlocksByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]state.L2Block, error) + GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.L2Block, error) } // ProcessorL1SequenceBatchesElderberry is the processor for SequenceBatches for Elderberry @@ -108,16 +108,15 @@ func (g *ProcessorL1SequenceBatchesElderberry) sanityCheckTstampLastL2Block(time log.Errorf("Error getting last virtual batch number: %s", err) return err } - l2blocks, err := g.state.GetL2BlocksByBatchNumber(context.Background(), lastVirtualBatchNum, dbTx) + lastL2Block, err := g.state.GetLastL2BlockByBatchNumber(context.Background(), lastVirtualBatchNum, dbTx) if err != nil { log.Errorf("Error getting last virtual batch number: %s", err) return err } - if len(l2blocks) == 0 { + if lastL2Block == nil { //TODO: find the previous batch until we find a L2 block to check the timestamp return nil } - lastL2Block := l2blocks[len(l2blocks)-1] if uint64(lastL2Block.ReceivedAt.Unix()) > timeLimit { log.Errorf("The last L2 block timestamp can't be greater than timeLimit. Expected: %d (L1 event), got: %d (last L2Block)", timeLimit, lastL2Block.ReceivedAt.Unix()) return fmt.Errorf("wrong timestamp of last L2 block timestamp with L1 event timestamp") diff --git a/synchronizer/common/syncinterfaces/mocks/state_full_interface.go b/synchronizer/common/syncinterfaces/mocks/state_full_interface.go index 8c34ad92ea..c3574cae93 100644 --- a/synchronizer/common/syncinterfaces/mocks/state_full_interface.go +++ b/synchronizer/common/syncinterfaces/mocks/state_full_interface.go @@ -1216,66 +1216,6 @@ func (_c *StateFullInterface_GetL1InfoTreeDataFromBatchL2Data_Call) RunAndReturn return _c } -// GetL2BlocksByBatchNumber provides a mock function with given fields: ctx, batchNumber, dbTx -func (_m *StateFullInterface) GetL2BlocksByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]state.L2Block, error) { - ret := _m.Called(ctx, batchNumber, dbTx) - - if len(ret) == 0 { - panic("no return value specified for GetL2BlocksByBatchNumber") - } - - var r0 []state.L2Block - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) ([]state.L2Block, error)); ok { - return rf(ctx, batchNumber, dbTx) - } - if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) []state.L2Block); ok { - r0 = rf(ctx, batchNumber, dbTx) - } else { - if ret.Get(0) != nil { - r0 = ret.Get(0).([]state.L2Block) - } - } - - if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok { - r1 = rf(ctx, batchNumber, dbTx) - } else { - r1 = ret.Error(1) - } - - return r0, r1 -} - -// StateFullInterface_GetL2BlocksByBatchNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetL2BlocksByBatchNumber' -type StateFullInterface_GetL2BlocksByBatchNumber_Call struct { - *mock.Call -} - -// GetL2BlocksByBatchNumber is a helper method to define mock.On call -// - ctx context.Context -// - batchNumber uint64 -// - dbTx pgx.Tx -func (_e *StateFullInterface_Expecter) GetL2BlocksByBatchNumber(ctx interface{}, batchNumber interface{}, dbTx interface{}) *StateFullInterface_GetL2BlocksByBatchNumber_Call { - return &StateFullInterface_GetL2BlocksByBatchNumber_Call{Call: _e.mock.On("GetL2BlocksByBatchNumber", ctx, batchNumber, dbTx)} -} - -func (_c *StateFullInterface_GetL2BlocksByBatchNumber_Call) Run(run func(ctx context.Context, batchNumber uint64, dbTx pgx.Tx)) *StateFullInterface_GetL2BlocksByBatchNumber_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint64), args[2].(pgx.Tx)) - }) - return _c -} - -func (_c *StateFullInterface_GetL2BlocksByBatchNumber_Call) Return(_a0 []state.L2Block, _a1 error) *StateFullInterface_GetL2BlocksByBatchNumber_Call { - _c.Call.Return(_a0, _a1) - return _c -} - -func (_c *StateFullInterface_GetL2BlocksByBatchNumber_Call) RunAndReturn(run func(context.Context, uint64, pgx.Tx) ([]state.L2Block, error)) *StateFullInterface_GetL2BlocksByBatchNumber_Call { - _c.Call.Return(run) - return _c -} - // GetLastBatchNumber provides a mock function with given fields: ctx, dbTx func (_m *StateFullInterface) GetLastBatchNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) { ret := _m.Called(ctx, dbTx) @@ -1392,6 +1332,66 @@ func (_c *StateFullInterface_GetLastBlock_Call) RunAndReturn(run func(context.Co return _c } +// GetLastL2BlockByBatchNumber provides a mock function with given fields: ctx, batchNumber, dbTx +func (_m *StateFullInterface) GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.L2Block, error) { + ret := _m.Called(ctx, batchNumber, dbTx) + + if len(ret) == 0 { + panic("no return value specified for GetLastL2BlockByBatchNumber") + } + + var r0 *state.L2Block + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) (*state.L2Block, error)); ok { + return rf(ctx, batchNumber, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, uint64, pgx.Tx) *state.L2Block); ok { + r0 = rf(ctx, batchNumber, dbTx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*state.L2Block) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, uint64, pgx.Tx) error); ok { + r1 = rf(ctx, batchNumber, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StateFullInterface_GetLastL2BlockByBatchNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLastL2BlockByBatchNumber' +type StateFullInterface_GetLastL2BlockByBatchNumber_Call struct { + *mock.Call +} + +// GetLastL2BlockByBatchNumber is a helper method to define mock.On call +// - ctx context.Context +// - batchNumber uint64 +// - dbTx pgx.Tx +func (_e *StateFullInterface_Expecter) GetLastL2BlockByBatchNumber(ctx interface{}, batchNumber interface{}, dbTx interface{}) *StateFullInterface_GetLastL2BlockByBatchNumber_Call { + return &StateFullInterface_GetLastL2BlockByBatchNumber_Call{Call: _e.mock.On("GetLastL2BlockByBatchNumber", ctx, batchNumber, dbTx)} +} + +func (_c *StateFullInterface_GetLastL2BlockByBatchNumber_Call) Run(run func(ctx context.Context, batchNumber uint64, dbTx pgx.Tx)) *StateFullInterface_GetLastL2BlockByBatchNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(pgx.Tx)) + }) + return _c +} + +func (_c *StateFullInterface_GetLastL2BlockByBatchNumber_Call) Return(_a0 *state.L2Block, _a1 error) *StateFullInterface_GetLastL2BlockByBatchNumber_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *StateFullInterface_GetLastL2BlockByBatchNumber_Call) RunAndReturn(run func(context.Context, uint64, pgx.Tx) (*state.L2Block, error)) *StateFullInterface_GetLastL2BlockByBatchNumber_Call { + _c.Call.Return(run) + return _c +} + // GetLastVerifiedBatch provides a mock function with given fields: ctx, dbTx func (_m *StateFullInterface) GetLastVerifiedBatch(ctx context.Context, dbTx pgx.Tx) (*state.VerifiedBatch, error) { ret := _m.Called(ctx, dbTx) diff --git a/synchronizer/common/syncinterfaces/state.go b/synchronizer/common/syncinterfaces/state.go index a35ac56039..faccb495b0 100644 --- a/synchronizer/common/syncinterfaces/state.go +++ b/synchronizer/common/syncinterfaces/state.go @@ -69,5 +69,5 @@ type StateFullInterface interface { GetL1InfoTreeDataFromBatchL2Data(ctx context.Context, batchL2Data []byte, dbTx pgx.Tx) (map[uint32]state.L1DataV2, common.Hash, common.Hash, error) GetExitRootByGlobalExitRoot(ctx context.Context, ger common.Hash, dbTx pgx.Tx) (*state.GlobalExitRoot, error) GetForkIDInMemory(forkId uint64) *state.ForkIDInterval - GetL2BlocksByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) ([]state.L2Block, error) + GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.L2Block, error) } diff --git a/test/Makefile b/test/Makefile index b8883b04dc..c43d56b4c9 100644 --- a/test/Makefile +++ b/test/Makefile @@ -122,7 +122,7 @@ test-full-non-e2e: stop ## Runs non-e2e tests checking race conditions sleep 15 docker ps -a docker logs $(DOCKERCOMPOSEZKPROVER) - trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -short -race -p 1 -covermode=atomic -coverprofile=../coverage.out -timeout 70s ../... + trap '$(STOP)' EXIT; MallocNanoZone=0 go test -count=1 -short -race -p 1 -covermode=atomic -coverprofile=../coverage.out -coverpkg ./... -timeout 70s ../... .PHONY: test-e2e-group-1 test-e2e-group-1: stop ## Runs group 1 e2e tests checking race conditions From 5c2fcff2ceb65160fc1422dead2e048795aafd9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Thu, 22 Feb 2024 09:17:31 +0100 Subject: [PATCH 21/51] reserved zk counters (#3343) * reserved zk counters * new prover image * udpate counters names * udpate counters names * add gas used to reserved zkCounters * add ReservedZKCounters to pool trasactions --- docker-compose.yml | 2 +- pool/config_test.go | 36 +- pool/pgpoolstorage/pgpoolstorage.go | 56 +- pool/transaction.go | 1 + proto/src/proto/executor/v1/executor.proto | 10 + sequencer/batch.go | 56 +- sequencer/finalizer.go | 10 +- sequencer/finalizer_test.go | 58 +- sequencer/forcedbatch.go | 4 +- sequencer/l2block.go | 12 +- sequencer/txtracker.go | 6 +- sequencer/worker.go | 18 +- sequencer/worker_test.go | 42 +- state/config.go | 16 +- state/converters.go | 16 +- state/convertersV2.go | 39 +- state/pgstatestorage/pgstatestorage_test.go | 4 +- state/runtime/executor/executor.pb.go | 1442 ++++++++++--------- state/types.go | 93 +- test/docker-compose.yml | 4 +- 20 files changed, 1029 insertions(+), 896 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 36fbfe070d..4fdea07a99 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:v5.0.0-RC4 + image: hermeznetwork/zkevm-prover:v5.0.0-RC5 depends_on: zkevm-state-db: condition: service_healthy diff --git a/pool/config_test.go b/pool/config_test.go index 9c930b6283..96b2cd3831 100644 --- a/pool/config_test.go +++ b/pool/config_test.go @@ -27,30 +27,30 @@ func TestIsWithinConstraints(t *testing.T) { { desc: "All constraints within limits", counters: state.ZKCounters{ - GasUsed: 300, - UsedKeccakHashes: 50, - UsedPoseidonHashes: 100, - UsedPoseidonPaddings: 75, - UsedMemAligns: 500, - UsedArithmetics: 1000, - UsedBinaries: 2000, - UsedSteps: 2000, - UsedSha256Hashes_V2: 4000, + GasUsed: 300, + KeccakHashes: 50, + PoseidonHashes: 100, + PoseidonPaddings: 75, + MemAligns: 500, + Arithmetics: 1000, + Binaries: 2000, + Steps: 2000, + Sha256Hashes_V2: 4000, }, expected: true, }, { desc: "All constraints exceed limits", counters: state.ZKCounters{ - GasUsed: 600, - UsedKeccakHashes: 150, - UsedPoseidonHashes: 300, - UsedPoseidonPaddings: 200, - UsedMemAligns: 2000, - UsedArithmetics: 3000, - UsedBinaries: 4000, - UsedSteps: 5000, - UsedSha256Hashes_V2: 6000, + GasUsed: 600, + KeccakHashes: 150, + PoseidonHashes: 300, + PoseidonPaddings: 200, + MemAligns: 2000, + Arithmetics: 3000, + Binaries: 4000, + Steps: 5000, + Sha256Hashes_V2: 6000, }, expected: false, }, diff --git a/pool/pgpoolstorage/pgpoolstorage.go b/pool/pgpoolstorage/pgpoolstorage.go index f4db73c860..b930f25a5a 100644 --- a/pool/pgpoolstorage/pgpoolstorage.go +++ b/pool/pgpoolstorage/pgpoolstorage.go @@ -116,14 +116,14 @@ func (p *PostgresPoolStorage) AddTx(ctx context.Context, tx pool.Transaction) er gasPrice, nonce, tx.GasUsed, - tx.UsedKeccakHashes, - tx.UsedPoseidonHashes, - tx.UsedPoseidonPaddings, - tx.UsedMemAligns, - tx.UsedArithmetics, - tx.UsedBinaries, - tx.UsedSteps, - tx.UsedSha256Hashes_V2, + tx.KeccakHashes, + tx.PoseidonHashes, + tx.PoseidonPaddings, + tx.MemAligns, + tx.Arithmetics, + tx.Binaries, + tx.Steps, + tx.Sha256Hashes_V2, tx.ReceivedAt, fromAddress, tx.IsWIP, @@ -333,15 +333,15 @@ func (p *PostgresPoolStorage) GetTxs(ctx context.Context, filterStatus pool.TxSt tx.Status = pool.TxStatus(status) tx.ReceivedAt = receivedAt tx.ZKCounters = state.ZKCounters{ - GasUsed: cumulativeGasUsed, - UsedKeccakHashes: usedKeccakHashes, - UsedPoseidonHashes: usedPoseidonHashes, - UsedPoseidonPaddings: usedPoseidonPaddings, - UsedMemAligns: usedMemAligns, - UsedArithmetics: usedArithmetics, - UsedBinaries: usedBinaries, - UsedSteps: usedSteps, - UsedSha256Hashes_V2: usedSHA256Hashes, + GasUsed: cumulativeGasUsed, + KeccakHashes: usedKeccakHashes, + PoseidonHashes: usedPoseidonHashes, + PoseidonPaddings: usedPoseidonPaddings, + MemAligns: usedMemAligns, + Arithmetics: usedArithmetics, + Binaries: usedBinaries, + Steps: usedSteps, + Sha256Hashes_V2: usedSHA256Hashes, } tx.IsWIP = isWIP tx.IP = ip @@ -705,14 +705,14 @@ func scanTx(rows pgx.Rows) (*pool.Transaction, error) { tx.IsWIP = isWIP tx.IP = ip tx.ZKCounters.GasUsed = cumulativeGasUsed - tx.ZKCounters.UsedKeccakHashes = usedKeccakHashes - tx.ZKCounters.UsedPoseidonHashes = usedPoseidonHashes - tx.ZKCounters.UsedPoseidonPaddings = usedPoseidonPaddings - tx.ZKCounters.UsedMemAligns = usedMemAligns - tx.ZKCounters.UsedArithmetics = usedArithmetics - tx.ZKCounters.UsedBinaries = usedBinaries - tx.ZKCounters.UsedSteps = usedSteps - tx.ZKCounters.UsedSha256Hashes_V2 = usedSHA256Hashes + tx.ZKCounters.KeccakHashes = usedKeccakHashes + tx.ZKCounters.PoseidonHashes = usedPoseidonHashes + tx.ZKCounters.PoseidonPaddings = usedPoseidonPaddings + tx.ZKCounters.MemAligns = usedMemAligns + tx.ZKCounters.Arithmetics = usedArithmetics + tx.ZKCounters.Binaries = usedBinaries + tx.ZKCounters.Steps = usedSteps + tx.ZKCounters.Sha256Hashes_V2 = usedSHA256Hashes tx.FailedReason = failedReason return tx, nil @@ -733,9 +733,9 @@ func (p *PostgresPoolStorage) GetTxZkCountersByHash(ctx context.Context, hash co sql := `SELECT cumulative_gas_used, used_keccak_hashes, used_poseidon_hashes, used_poseidon_paddings, used_mem_aligns, used_arithmetics, used_binaries, used_steps, used_sha256_hashes FROM pool.transaction WHERE hash = $1` - err := p.db.QueryRow(ctx, sql, hash.String()).Scan(&zkCounters.GasUsed, &zkCounters.UsedKeccakHashes, - &zkCounters.UsedPoseidonHashes, &zkCounters.UsedPoseidonPaddings, - &zkCounters.UsedMemAligns, &zkCounters.UsedArithmetics, &zkCounters.UsedBinaries, &zkCounters.UsedSteps, &zkCounters.UsedSha256Hashes_V2) + err := p.db.QueryRow(ctx, sql, hash.String()).Scan(&zkCounters.GasUsed, &zkCounters.KeccakHashes, + &zkCounters.PoseidonHashes, &zkCounters.PoseidonPaddings, + &zkCounters.MemAligns, &zkCounters.Arithmetics, &zkCounters.Binaries, &zkCounters.Steps, &zkCounters.Sha256Hashes_V2) if errors.Is(err, pgx.ErrNoRows) { return nil, pool.ErrNotFound } else if err != nil { diff --git a/pool/transaction.go b/pool/transaction.go index b958b2c268..203a33b512 100644 --- a/pool/transaction.go +++ b/pool/transaction.go @@ -40,6 +40,7 @@ type Transaction struct { types.Transaction Status TxStatus state.ZKCounters + ReservedZKCounters state.ZKCounters ReceivedAt time.Time PreprocessedStateRoot common.Hash IsWIP bool diff --git a/proto/src/proto/executor/v1/executor.proto b/proto/src/proto/executor/v1/executor.proto index 2fdd32ef35..ba1f135304 100644 --- a/proto/src/proto/executor/v1/executor.proto +++ b/proto/src/proto/executor/v1/executor.proto @@ -335,6 +335,14 @@ message ProcessBatchResponseV2 { uint64 fork_id = 22; uint32 invalid_batch = 23; RomError error_rom = 24; + uint32 cnt_reserve_keccak_hashes = 25; + uint32 cnt_reserve_poseidon_hashes = 26; + uint32 cnt_reserve_poseidon_paddings = 27; + uint32 cnt_reserve_mem_aligns = 28; + uint32 cnt_reserve_arithmetics = 29; + uint32 cnt_reserve_binaries = 30; + uint32 cnt_reserve_steps = 31; + uint32 cnt_reserve_sha256_hashes = 32; } // Trace configuration request params @@ -528,6 +536,8 @@ message ProcessTransactionResponseV2 { uint32 has_gasprice_opcode = 19; // Flag to indicate if opcode 'BALANCE' has been called uint32 has_balance_opcode = 20; + // Receipt status of the transaction, 1 = success, 0 = failure + uint32 status = 21; } message LogV2 { diff --git a/sequencer/batch.go b/sequencer/batch.go index bb944dbd26..caf86142e5 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -469,34 +469,34 @@ func (f *finalizer) maxTxsPerBatchReached(batch *Batch) bool { // isBatchResourcesMarginExhausted checks if one of resources of the batch has reached the exhausted margin and returns the name of the exhausted resource func (f *finalizer) isBatchResourcesMarginExhausted(resources state.BatchResources) (bool, string) { - zkCounters := resources.ZKCounters + zkCounters := resources.UsedZKCounters result := false resourceName := "" if resources.Bytes <= f.getConstraintThresholdUint64(f.batchConstraints.MaxBatchBytesSize) { resourceName = "Bytes" result = true - } else if zkCounters.UsedSteps <= f.getConstraintThresholdUint32(f.batchConstraints.MaxSteps) { + } else if zkCounters.Steps <= f.getConstraintThresholdUint32(f.batchConstraints.MaxSteps) { resourceName = "Steps" result = true - } else if zkCounters.UsedPoseidonPaddings <= f.getConstraintThresholdUint32(f.batchConstraints.MaxPoseidonPaddings) { + } else if zkCounters.PoseidonPaddings <= f.getConstraintThresholdUint32(f.batchConstraints.MaxPoseidonPaddings) { resourceName = "PoseidonPaddings" result = true - } else if zkCounters.UsedBinaries <= f.getConstraintThresholdUint32(f.batchConstraints.MaxBinaries) { + } else if zkCounters.Binaries <= f.getConstraintThresholdUint32(f.batchConstraints.MaxBinaries) { resourceName = "Binaries" result = true - } else if zkCounters.UsedKeccakHashes <= f.getConstraintThresholdUint32(f.batchConstraints.MaxKeccakHashes) { + } else if zkCounters.KeccakHashes <= f.getConstraintThresholdUint32(f.batchConstraints.MaxKeccakHashes) { resourceName = "KeccakHashes" result = true - } else if zkCounters.UsedArithmetics <= f.getConstraintThresholdUint32(f.batchConstraints.MaxArithmetics) { + } else if zkCounters.Arithmetics <= f.getConstraintThresholdUint32(f.batchConstraints.MaxArithmetics) { resourceName = "Arithmetics" result = true - } else if zkCounters.UsedMemAligns <= f.getConstraintThresholdUint32(f.batchConstraints.MaxMemAligns) { + } else if zkCounters.MemAligns <= f.getConstraintThresholdUint32(f.batchConstraints.MaxMemAligns) { resourceName = "MemAligns" result = true } else if zkCounters.GasUsed <= f.getConstraintThresholdUint64(f.batchConstraints.MaxCumulativeGasUsed) { resourceName = "CumulativeGas" result = true - } else if zkCounters.UsedSha256Hashes_V2 <= f.getConstraintThresholdUint32(f.batchConstraints.MaxSHA256Hashes) { + } else if zkCounters.Sha256Hashes_V2 <= f.getConstraintThresholdUint32(f.batchConstraints.MaxSHA256Hashes) { resourceName = "SHA256Hashes" result = true } @@ -517,16 +517,16 @@ func (f *finalizer) getConstraintThresholdUint32(input uint32) uint32 { // getUsedBatchResources calculates and returns the used resources of a batch from remaining resources func getUsedBatchResources(constraints state.BatchConstraintsCfg, remainingResources state.BatchResources) state.BatchResources { return state.BatchResources{ - ZKCounters: state.ZKCounters{ - GasUsed: constraints.MaxCumulativeGasUsed - remainingResources.ZKCounters.GasUsed, - UsedKeccakHashes: constraints.MaxKeccakHashes - remainingResources.ZKCounters.UsedKeccakHashes, - UsedPoseidonHashes: constraints.MaxPoseidonHashes - remainingResources.ZKCounters.UsedPoseidonHashes, - UsedPoseidonPaddings: constraints.MaxPoseidonPaddings - remainingResources.ZKCounters.UsedPoseidonPaddings, - UsedMemAligns: constraints.MaxMemAligns - remainingResources.ZKCounters.UsedMemAligns, - UsedArithmetics: constraints.MaxArithmetics - remainingResources.ZKCounters.UsedArithmetics, - UsedBinaries: constraints.MaxBinaries - remainingResources.ZKCounters.UsedBinaries, - UsedSteps: constraints.MaxSteps - remainingResources.ZKCounters.UsedSteps, - UsedSha256Hashes_V2: constraints.MaxSHA256Hashes - remainingResources.ZKCounters.UsedSha256Hashes_V2, + UsedZKCounters: state.ZKCounters{ + GasUsed: constraints.MaxCumulativeGasUsed - remainingResources.UsedZKCounters.GasUsed, + KeccakHashes: constraints.MaxKeccakHashes - remainingResources.UsedZKCounters.KeccakHashes, + PoseidonHashes: constraints.MaxPoseidonHashes - remainingResources.UsedZKCounters.PoseidonHashes, + PoseidonPaddings: constraints.MaxPoseidonPaddings - remainingResources.UsedZKCounters.PoseidonPaddings, + MemAligns: constraints.MaxMemAligns - remainingResources.UsedZKCounters.MemAligns, + Arithmetics: constraints.MaxArithmetics - remainingResources.UsedZKCounters.Arithmetics, + Binaries: constraints.MaxBinaries - remainingResources.UsedZKCounters.Binaries, + Steps: constraints.MaxSteps - remainingResources.UsedZKCounters.Steps, + Sha256Hashes_V2: constraints.MaxSHA256Hashes - remainingResources.UsedZKCounters.Sha256Hashes_V2, }, Bytes: constraints.MaxBatchBytesSize - remainingResources.Bytes, } @@ -535,16 +535,16 @@ func getUsedBatchResources(constraints state.BatchConstraintsCfg, remainingResou // getMaxRemainingResources returns the max resources that can be used in a batch func getMaxRemainingResources(constraints state.BatchConstraintsCfg) state.BatchResources { return state.BatchResources{ - ZKCounters: state.ZKCounters{ - GasUsed: constraints.MaxCumulativeGasUsed, - UsedKeccakHashes: constraints.MaxKeccakHashes, - UsedPoseidonHashes: constraints.MaxPoseidonHashes, - UsedPoseidonPaddings: constraints.MaxPoseidonPaddings, - UsedMemAligns: constraints.MaxMemAligns, - UsedArithmetics: constraints.MaxArithmetics, - UsedBinaries: constraints.MaxBinaries, - UsedSteps: constraints.MaxSteps, - UsedSha256Hashes_V2: constraints.MaxSHA256Hashes, + UsedZKCounters: state.ZKCounters{ + GasUsed: constraints.MaxCumulativeGasUsed, + KeccakHashes: constraints.MaxKeccakHashes, + PoseidonHashes: constraints.MaxPoseidonHashes, + PoseidonPaddings: constraints.MaxPoseidonPaddings, + MemAligns: constraints.MaxMemAligns, + Arithmetics: constraints.MaxArithmetics, + Binaries: constraints.MaxBinaries, + Steps: constraints.MaxSteps, + Sha256Hashes_V2: constraints.MaxSHA256Hashes, }, Bytes: constraints.MaxBatchBytesSize, } diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index 3a1e451939..ad759183fd 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -374,11 +374,11 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first // Save values for later logging tx.EGPLog.L1GasPrice = tx.L1GasPrice tx.EGPLog.L2GasPrice = txL2GasPrice - tx.EGPLog.GasUsedFirst = tx.BatchResources.ZKCounters.GasUsed + tx.EGPLog.GasUsedFirst = tx.BatchResources.UsedZKCounters.GasUsed tx.EGPLog.GasPrice.Set(txGasPrice) // Calculate EffectiveGasPrice - egp, err := f.effectiveGasPrice.CalculateEffectiveGasPrice(tx.RawTx, txGasPrice, tx.BatchResources.ZKCounters.GasUsed, tx.L1GasPrice, txL2GasPrice) + egp, err := f.effectiveGasPrice.CalculateEffectiveGasPrice(tx.RawTx, txGasPrice, tx.BatchResources.UsedZKCounters.GasUsed, tx.L1GasPrice, txL2GasPrice) if err != nil { if f.effectiveGasPrice.IsEnabled() { return nil, false, err @@ -531,7 +531,7 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx // Check remaining resources - overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(state.BatchResources{ZKCounters: result.UsedZkCounters, Bytes: uint64(len(tx.RawTx))}) + overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(state.BatchResources{UsedZKCounters: result.UsedZkCounters, Bytes: uint64(len(tx.RawTx))}) if overflow { log.Infof("current tx %s exceeds the remaining batch resources, overflow resource: %s, updating metadata for tx in worker and continuing", tx.HashStr, overflowResource) if !f.batchConstraints.IsWithinConstraints(result.UsedZkCounters) { @@ -749,8 +749,8 @@ func (f *finalizer) checkIfProverRestarted(proverID string) { // logZKCounters returns a string with all the zkCounters values func (f *finalizer) logZKCounters(counters state.ZKCounters) string { return fmt.Sprintf("{gasUsed: %d, keccakHashes: %d, poseidonHashes: %d, poseidonPaddings: %d, memAligns: %d, arithmetics: %d, binaries: %d, sha256Hashes: %d, steps: %d}", - counters.GasUsed, counters.UsedKeccakHashes, counters.UsedPoseidonHashes, counters.UsedPoseidonPaddings, counters.UsedMemAligns, counters.UsedArithmetics, - counters.UsedBinaries, counters.UsedSha256Hashes_V2, counters.UsedSteps) + counters.GasUsed, counters.KeccakHashes, counters.PoseidonHashes, counters.PoseidonPaddings, counters.MemAligns, counters.Arithmetics, + counters.Binaries, counters.Sha256Hashes_V2, counters.Steps) } // Halt halts the finalizer diff --git a/sequencer/finalizer_test.go b/sequencer/finalizer_test.go index 6aa201fd29..278e8c50cd 100644 --- a/sequencer/finalizer_test.go +++ b/sequencer/finalizer_test.go @@ -1077,8 +1077,8 @@ func TestFinalizer_checkRemainingResources(t *testing.T) { BlockResponses: []*state.ProcessBlockResponse{blockResponse}, } remainingResources := state.BatchResources{ - ZKCounters: state.ZKCounters{GasUsed: 9000}, - Bytes: 10000, + UsedZKCounters: state.ZKCounters{GasUsed: 9000}, + Bytes: 10000, } f.wipBatch.imRemainingResources = remainingResources testCases := []struct { @@ -1109,7 +1109,7 @@ func TestFinalizer_checkRemainingResources(t *testing.T) { { name: "ZkCounter Resource Exceeded", remaining: state.BatchResources{ - ZKCounters: state.ZKCounters{GasUsed: 0}, + UsedZKCounters: state.ZKCounters{GasUsed: 0}, }, overflow: true, overflowResource: "CumulativeGas", @@ -1128,7 +1128,7 @@ func TestFinalizer_checkRemainingResources(t *testing.T) { } // act - overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(state.BatchResources{ZKCounters: result.UsedZkCounters, Bytes: uint64(len(tc.expectedTxTracker.RawTx))}) + overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(state.BatchResources{UsedZKCounters: result.UsedZkCounters, Bytes: uint64(len(tc.expectedTxTracker.RawTx))}) // assert assert.Equal(t, tc.overflow, overflow) @@ -1906,7 +1906,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxCumulativeGasUsed", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.GasUsed = f.getConstraintThresholdUint64(bc.MaxCumulativeGasUsed) - 1 + resources.UsedZKCounters.GasUsed = f.getConstraintThresholdUint64(bc.MaxCumulativeGasUsed) - 1 return resources }, expectedResult: true, @@ -1914,7 +1914,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxCumulativeGasUsed", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.GasUsed = f.getConstraintThresholdUint64(bc.MaxCumulativeGasUsed) + 1 + resources.UsedZKCounters.GasUsed = f.getConstraintThresholdUint64(bc.MaxCumulativeGasUsed) + 1 return resources }, expectedResult: false, @@ -1922,7 +1922,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxSteps", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedSteps = f.getConstraintThresholdUint32(bc.MaxSteps) - 1 + resources.UsedZKCounters.Steps = f.getConstraintThresholdUint32(bc.MaxSteps) - 1 return resources }, expectedResult: true, @@ -1930,7 +1930,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxSteps", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedSteps = f.getConstraintThresholdUint32(bc.MaxSteps) + 1 + resources.UsedZKCounters.Steps = f.getConstraintThresholdUint32(bc.MaxSteps) + 1 return resources }, expectedResult: false, @@ -1938,7 +1938,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxPoseidonPaddings", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedPoseidonPaddings = f.getConstraintThresholdUint32(bc.MaxPoseidonPaddings) - 1 + resources.UsedZKCounters.PoseidonPaddings = f.getConstraintThresholdUint32(bc.MaxPoseidonPaddings) - 1 return resources }, expectedResult: true, @@ -1946,7 +1946,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxPoseidonPaddings", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedPoseidonPaddings = f.getConstraintThresholdUint32(bc.MaxPoseidonPaddings) + 1 + resources.UsedZKCounters.PoseidonPaddings = f.getConstraintThresholdUint32(bc.MaxPoseidonPaddings) + 1 return resources }, expectedResult: false, @@ -1954,7 +1954,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxBinaries", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedBinaries = f.getConstraintThresholdUint32(bc.MaxBinaries) - 1 + resources.UsedZKCounters.Binaries = f.getConstraintThresholdUint32(bc.MaxBinaries) - 1 return resources }, expectedResult: true, @@ -1962,7 +1962,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxBinaries", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedBinaries = f.getConstraintThresholdUint32(bc.MaxBinaries) + 1 + resources.UsedZKCounters.Binaries = f.getConstraintThresholdUint32(bc.MaxBinaries) + 1 return resources }, expectedResult: false, @@ -1970,7 +1970,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxKeccakHashes", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedKeccakHashes = f.getConstraintThresholdUint32(bc.MaxKeccakHashes) - 1 + resources.UsedZKCounters.KeccakHashes = f.getConstraintThresholdUint32(bc.MaxKeccakHashes) - 1 return resources }, expectedResult: true, @@ -1978,7 +1978,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxKeccakHashes", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedKeccakHashes = f.getConstraintThresholdUint32(bc.MaxKeccakHashes) + 1 + resources.UsedZKCounters.KeccakHashes = f.getConstraintThresholdUint32(bc.MaxKeccakHashes) + 1 return resources }, expectedResult: false, @@ -1986,7 +1986,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxArithmetics", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedArithmetics = f.getConstraintThresholdUint32(bc.MaxArithmetics) - 1 + resources.UsedZKCounters.Arithmetics = f.getConstraintThresholdUint32(bc.MaxArithmetics) - 1 return resources }, expectedResult: true, @@ -1994,7 +1994,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxArithmetics", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedArithmetics = f.getConstraintThresholdUint32(bc.MaxArithmetics) + 1 + resources.UsedZKCounters.Arithmetics = f.getConstraintThresholdUint32(bc.MaxArithmetics) + 1 return resources }, expectedResult: false, @@ -2002,7 +2002,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxMemAligns", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedMemAligns = f.getConstraintThresholdUint32(bc.MaxMemAligns) - 1 + resources.UsedZKCounters.MemAligns = f.getConstraintThresholdUint32(bc.MaxMemAligns) - 1 return resources }, expectedResult: true, @@ -2010,7 +2010,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxMemAligns", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedMemAligns = f.getConstraintThresholdUint32(bc.MaxMemAligns) + 1 + resources.UsedZKCounters.MemAligns = f.getConstraintThresholdUint32(bc.MaxMemAligns) + 1 return resources }, expectedResult: false, @@ -2018,7 +2018,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxSHA256Hashes", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedSha256Hashes_V2 = f.getConstraintThresholdUint32(bc.MaxSHA256Hashes) - 1 + resources.UsedZKCounters.Sha256Hashes_V2 = f.getConstraintThresholdUint32(bc.MaxSHA256Hashes) - 1 return resources }, expectedResult: true, @@ -2026,7 +2026,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxSHA256Hashes", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.ZKCounters.UsedSha256Hashes_V2 = f.getConstraintThresholdUint32(bc.MaxSHA256Hashes) + 1 + resources.UsedZKCounters.Sha256Hashes_V2 = f.getConstraintThresholdUint32(bc.MaxSHA256Hashes) + 1 return resources }, expectedResult: false, @@ -2101,15 +2101,15 @@ func TestFinalizer_getRemainingResources(t *testing.T) { remainingResources := getMaxRemainingResources(bc) // assert - assert.Equal(t, remainingResources.ZKCounters.GasUsed, bc.MaxCumulativeGasUsed) - assert.Equal(t, remainingResources.ZKCounters.UsedKeccakHashes, bc.MaxKeccakHashes) - assert.Equal(t, remainingResources.ZKCounters.UsedPoseidonHashes, bc.MaxPoseidonHashes) - assert.Equal(t, remainingResources.ZKCounters.UsedPoseidonPaddings, bc.MaxPoseidonPaddings) - assert.Equal(t, remainingResources.ZKCounters.UsedMemAligns, bc.MaxMemAligns) - assert.Equal(t, remainingResources.ZKCounters.UsedArithmetics, bc.MaxArithmetics) - assert.Equal(t, remainingResources.ZKCounters.UsedBinaries, bc.MaxBinaries) - assert.Equal(t, remainingResources.ZKCounters.UsedSteps, bc.MaxSteps) - assert.Equal(t, remainingResources.ZKCounters.UsedSha256Hashes_V2, bc.MaxSHA256Hashes) + assert.Equal(t, remainingResources.UsedZKCounters.GasUsed, bc.MaxCumulativeGasUsed) + assert.Equal(t, remainingResources.UsedZKCounters.KeccakHashes, bc.MaxKeccakHashes) + assert.Equal(t, remainingResources.UsedZKCounters.PoseidonHashes, bc.MaxPoseidonHashes) + assert.Equal(t, remainingResources.UsedZKCounters.PoseidonPaddings, bc.MaxPoseidonPaddings) + assert.Equal(t, remainingResources.UsedZKCounters.MemAligns, bc.MaxMemAligns) + assert.Equal(t, remainingResources.UsedZKCounters.Arithmetics, bc.MaxArithmetics) + assert.Equal(t, remainingResources.UsedZKCounters.Binaries, bc.MaxBinaries) + assert.Equal(t, remainingResources.UsedZKCounters.Steps, bc.MaxSteps) + assert.Equal(t, remainingResources.UsedZKCounters.Sha256Hashes_V2, bc.MaxSHA256Hashes) assert.Equal(t, remainingResources.Bytes, bc.MaxBatchBytesSize) } diff --git a/sequencer/forcedbatch.go b/sequencer/forcedbatch.go index 4f035ec708..d27485377b 100644 --- a/sequencer/forcedbatch.go +++ b/sequencer/forcedbatch.go @@ -121,8 +121,8 @@ func (f *finalizer) processForcedBatch(ctx context.Context, forcedBatch state.Fo LocalExitRoot: batchResponse.NewLocalExitRoot, BatchL2Data: forcedBatch.RawTxsData, BatchResources: state.BatchResources{ - ZKCounters: batchResponse.UsedZkCounters, - Bytes: uint64(len(forcedBatch.RawTxsData)), + UsedZKCounters: batchResponse.UsedZkCounters, + Bytes: uint64(len(forcedBatch.RawTxsData)), }, ClosingReason: state.ForcedBatchClosingReason, } diff --git a/sequencer/l2block.go b/sequencer/l2block.go index 6cdc814753..b9ed8d0b6c 100644 --- a/sequencer/l2block.go +++ b/sequencer/l2block.go @@ -197,10 +197,10 @@ func (f *finalizer) processL2Block(ctx context.Context, l2Block *L2Block) error l2Block.batchResponse = batchResponse // Update finalRemainingResources of the batch - overflow, overflowResource := f.wipBatch.finalRemainingResources.Sub(state.BatchResources{ZKCounters: batchResponse.UsedZkCounters, Bytes: batchL2DataSize}) + overflow, overflowResource := f.wipBatch.finalRemainingResources.Sub(state.BatchResources{UsedZKCounters: batchResponse.UsedZkCounters, Bytes: batchL2DataSize}) if overflow { return fmt.Errorf("error sustracting L2 block %d [%d] resources from the batch %d, overflow resource: %s, batch remaining counters: %s, L2Block used counters: %s, batch remaining bytes: %d, L2Block used bytes: %d", - blockResponse.BlockNumber, l2Block.trackingNum, f.wipBatch.batchNumber, overflowResource, f.logZKCounters(f.wipBatch.finalRemainingResources.ZKCounters), f.logZKCounters(batchResponse.UsedZkCounters), f.wipBatch.finalRemainingResources.Bytes, batchL2DataSize) + blockResponse.BlockNumber, l2Block.trackingNum, f.wipBatch.batchNumber, overflowResource, f.logZKCounters(f.wipBatch.finalRemainingResources.UsedZKCounters), f.logZKCounters(batchResponse.UsedZkCounters), f.wipBatch.finalRemainingResources.Bytes, batchL2DataSize) } // Update finalStateRoot of the batch to the newStateRoot for the L2 block @@ -360,7 +360,7 @@ func (f *finalizer) storeL2Block(ctx context.Context, l2Block *L2Block) error { } batch.BatchL2Data = append(batch.BatchL2Data, blockL2Data...) - batch.Resources.SumUp(state.BatchResources{ZKCounters: l2Block.batchResponse.UsedZkCounters, Bytes: uint64(len(blockL2Data))}) + batch.Resources.SumUp(state.BatchResources{UsedZKCounters: l2Block.batchResponse.UsedZkCounters, Bytes: uint64(len(blockL2Data))}) receipt := state.ProcessingReceipt{ BatchNumber: f.wipBatch.batchNumber, @@ -506,8 +506,8 @@ func (f *finalizer) openNewWIPL2Block(ctx context.Context, prevTimestamp uint64, // Save and sustract the resources used by the new WIP L2 block from the wip batch // We need to increase the poseidon hashes to reserve in the batch the hashes needed to write the L1InfoRoot when processing the final L2 Block (SkipWriteBlockInfoRoot_V2=false) - f.wipL2Block.usedResources.ZKCounters = batchResponse.UsedZkCounters - f.wipL2Block.usedResources.ZKCounters.UsedPoseidonHashes = (batchResponse.UsedZkCounters.UsedPoseidonHashes * 2) + 2 // nolint:gomnd + f.wipL2Block.usedResources.UsedZKCounters = batchResponse.UsedZkCounters + f.wipL2Block.usedResources.UsedZKCounters.PoseidonHashes = (batchResponse.UsedZkCounters.PoseidonHashes * 2) + 2 // nolint:gomnd f.wipL2Block.usedResources.Bytes = changeL2BlockSize overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(f.wipL2Block.usedResources) @@ -522,7 +522,7 @@ func (f *finalizer) openNewWIPL2Block(ctx context.Context, prevTimestamp uint64, log.Infof("created new WIP L2 block [%d], batch: %d, deltaTimestamp: %d, timestamp: %d, l1InfoTreeIndex: %d, l1InfoTreeIndexChanged: %v, oldStateRoot: %s, imStateRoot: %s, used counters: %s", f.wipL2Block.trackingNum, f.wipBatch.batchNumber, f.wipL2Block.deltaTimestamp, f.wipL2Block.timestamp, f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex, - f.wipL2Block.l1InfoTreeExitRootChanged, oldIMStateRoot, f.wipL2Block.imStateRoot, f.logZKCounters(f.wipL2Block.usedResources.ZKCounters)) + f.wipL2Block.l1InfoTreeExitRootChanged, oldIMStateRoot, f.wipL2Block.imStateRoot, f.logZKCounters(f.wipL2Block.usedResources.UsedZKCounters)) } // executeNewWIPL2Block executes an empty L2 Block in the executor and returns the batch response from the executor diff --git a/sequencer/txtracker.go b/sequencer/txtracker.go index ecf9001714..4f85ef947f 100644 --- a/sequencer/txtracker.go +++ b/sequencer/txtracker.go @@ -54,8 +54,8 @@ func newTxTracker(tx types.Transaction, counters state.ZKCounters, ip string) (* GasPrice: tx.GasPrice(), Cost: tx.Cost(), BatchResources: state.BatchResources{ - Bytes: uint64(len(rawTx)) + state.EfficiencyPercentageByteLength, - ZKCounters: counters, + Bytes: uint64(len(rawTx)) + state.EfficiencyPercentageByteLength, + UsedZKCounters: counters, }, RawTx: rawTx, ReceivedAt: time.Now(), @@ -76,5 +76,5 @@ func newTxTracker(tx types.Transaction, counters state.ZKCounters, ip string) (* // updateZKCounters updates the counters of the tx func (tx *TxTracker) updateZKCounters(counters state.ZKCounters) { - tx.BatchResources.ZKCounters = counters + tx.BatchResources.UsedZKCounters = counters } diff --git a/sequencer/worker.go b/sequencer/worker.go index 0d770e6396..919fe50132 100644 --- a/sequencer/worker.go +++ b/sequencer/worker.go @@ -52,7 +52,7 @@ func (w *Worker) AddTxTracker(ctx context.Context, tx *TxTracker) (replacedTx *T } // Make sure the transaction's batch resources are within the constraints. - if !w.batchConstraints.IsWithinConstraints(tx.BatchResources.ZKCounters) { + if !w.batchConstraints.IsWithinConstraints(tx.BatchResources.UsedZKCounters) { log.Errorf("outOfCounters error (node level) for tx %s", tx.Hash.String()) w.workerMutex.Unlock() return nil, pool.ErrOutOfCounters @@ -225,14 +225,14 @@ func (w *Worker) UpdateTxZKCounters(txHash common.Hash, addr common.Address, cou log.Infof("update ZK counters for tx %s addr %s", txHash.String(), addr.String()) log.Debugf("counters.CumulativeGasUsed: %d", counters.GasUsed) - log.Debugf("counters.UsedKeccakHashes: %d", counters.UsedKeccakHashes) - log.Debugf("counters.UsedPoseidonHashes: %d", counters.UsedPoseidonHashes) - log.Debugf("counters.UsedPoseidonPaddings: %d", counters.UsedPoseidonPaddings) - log.Debugf("counters.UsedMemAligns: %d", counters.UsedMemAligns) - log.Debugf("counters.UsedArithmetics: %d", counters.UsedArithmetics) - log.Debugf("counters.UsedBinaries: %d", counters.UsedBinaries) - log.Debugf("counters.UsedSteps: %d", counters.UsedSteps) - log.Debugf("counters.UsedSha256Hashes_V2: %d", counters.UsedSha256Hashes_V2) + log.Debugf("counters.UsedKeccakHashes: %d", counters.KeccakHashes) + log.Debugf("counters.UsedPoseidonHashes: %d", counters.PoseidonHashes) + log.Debugf("counters.UsedPoseidonPaddings: %d", counters.PoseidonPaddings) + log.Debugf("counters.UsedMemAligns: %d", counters.MemAligns) + log.Debugf("counters.UsedArithmetics: %d", counters.Arithmetics) + log.Debugf("counters.UsedBinaries: %d", counters.Binaries) + log.Debugf("counters.UsedSteps: %d", counters.Steps) + log.Debugf("counters.UsedSha256Hashes_V2: %d", counters.Sha256Hashes_V2) addrQueue, found := w.pool[addr.String()] diff --git a/sequencer/worker_test.go b/sequencer/worker_test.go index d68556ef71..0acbe9c798 100644 --- a/sequencer/worker_test.go +++ b/sequencer/worker_test.go @@ -118,7 +118,7 @@ func TestWorkerAddTx(t *testing.T) { { name: "Adding from:0x01, tx:0x01/gp:10", from: common.Address{1}, txHash: common.Hash{1}, nonce: 1, gasPrice: new(big.Int).SetInt64(10), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 1, UsedKeccakHashes: 1, UsedPoseidonHashes: 1, UsedPoseidonPaddings: 1, UsedMemAligns: 1, UsedArithmetics: 1, UsedBinaries: 1, UsedSteps: 1, UsedSha256Hashes_V2: 1}, + counters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 1}, usedBytes: 1, expectedTxSortedList: []common.Hash{ {1}, @@ -127,7 +127,7 @@ func TestWorkerAddTx(t *testing.T) { { name: "Adding from:0x02, tx:0x02/gp:4", from: common.Address{2}, txHash: common.Hash{2}, nonce: 1, gasPrice: new(big.Int).SetInt64(4), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 1, UsedKeccakHashes: 1, UsedPoseidonHashes: 1, UsedPoseidonPaddings: 1, UsedMemAligns: 1, UsedArithmetics: 1, UsedBinaries: 1, UsedSteps: 1, UsedSha256Hashes_V2: 1}, + counters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 1}, usedBytes: 1, expectedTxSortedList: []common.Hash{ {1}, {2}, @@ -136,7 +136,7 @@ func TestWorkerAddTx(t *testing.T) { { name: "Readding from:0x02, tx:0x02/gp:20", from: common.Address{2}, txHash: common.Hash{2}, nonce: 1, gasPrice: new(big.Int).SetInt64(20), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 5, UsedKeccakHashes: 5, UsedPoseidonHashes: 5, UsedPoseidonPaddings: 5, UsedMemAligns: 5, UsedArithmetics: 5, UsedBinaries: 5, UsedSteps: 5, UsedSha256Hashes_V2: 5}, + counters: state.ZKCounters{GasUsed: 5, KeccakHashes: 5, PoseidonHashes: 5, PoseidonPaddings: 5, MemAligns: 5, Arithmetics: 5, Binaries: 5, Steps: 5, Sha256Hashes_V2: 5}, usedBytes: 5, expectedTxSortedList: []common.Hash{ {2}, {1}, @@ -145,7 +145,7 @@ func TestWorkerAddTx(t *testing.T) { { name: "Readding from:0x03, tx:0x03/gp:25", from: common.Address{3}, txHash: common.Hash{3}, nonce: 1, gasPrice: new(big.Int).SetInt64(25), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 2, UsedKeccakHashes: 2, UsedPoseidonHashes: 2, UsedPoseidonPaddings: 2, UsedMemAligns: 2, UsedArithmetics: 2, UsedBinaries: 2, UsedSteps: 2, UsedSha256Hashes_V2: 2}, + counters: state.ZKCounters{GasUsed: 2, KeccakHashes: 2, PoseidonHashes: 2, PoseidonPaddings: 2, MemAligns: 2, Arithmetics: 2, Binaries: 2, Steps: 2, Sha256Hashes_V2: 2}, usedBytes: 2, expectedTxSortedList: []common.Hash{ {3}, {2}, {1}, @@ -153,7 +153,7 @@ func TestWorkerAddTx(t *testing.T) { }, { name: "Invalid IP address", from: common.Address{5}, txHash: common.Hash{5}, nonce: 1, - counters: state.ZKCounters{GasUsed: 1, UsedKeccakHashes: 1, UsedPoseidonHashes: 1, UsedPoseidonPaddings: 1, UsedMemAligns: 1, UsedArithmetics: 1, UsedBinaries: 1, UsedSteps: 1, UsedSha256Hashes_V2: 2}, + counters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 2}, usedBytes: 1, ip: "invalid IP", expectedErr: pool.ErrInvalidIP, @@ -164,15 +164,15 @@ func TestWorkerAddTx(t *testing.T) { cost: new(big.Int).SetInt64(5), // Here, we intentionally set the counters such that they violate the constraints counters: state.ZKCounters{ - GasUsed: worker.batchConstraints.MaxCumulativeGasUsed + 1, - UsedKeccakHashes: worker.batchConstraints.MaxKeccakHashes + 1, - UsedPoseidonHashes: worker.batchConstraints.MaxPoseidonHashes + 1, - UsedPoseidonPaddings: worker.batchConstraints.MaxPoseidonPaddings + 1, - UsedMemAligns: worker.batchConstraints.MaxMemAligns + 1, - UsedArithmetics: worker.batchConstraints.MaxArithmetics + 1, - UsedBinaries: worker.batchConstraints.MaxBinaries + 1, - UsedSteps: worker.batchConstraints.MaxSteps + 1, - UsedSha256Hashes_V2: worker.batchConstraints.MaxSHA256Hashes + 1, + GasUsed: worker.batchConstraints.MaxCumulativeGasUsed + 1, + KeccakHashes: worker.batchConstraints.MaxKeccakHashes + 1, + PoseidonHashes: worker.batchConstraints.MaxPoseidonHashes + 1, + PoseidonPaddings: worker.batchConstraints.MaxPoseidonPaddings + 1, + MemAligns: worker.batchConstraints.MaxMemAligns + 1, + Arithmetics: worker.batchConstraints.MaxArithmetics + 1, + Binaries: worker.batchConstraints.MaxBinaries + 1, + Steps: worker.batchConstraints.MaxSteps + 1, + Sha256Hashes_V2: worker.batchConstraints.MaxSHA256Hashes + 1, }, usedBytes: 1, expectedErr: pool.ErrOutOfCounters, @@ -180,7 +180,7 @@ func TestWorkerAddTx(t *testing.T) { { name: "Adding from:0x04, tx:0x04/gp:100", from: common.Address{4}, txHash: common.Hash{4}, nonce: 1, gasPrice: new(big.Int).SetInt64(100), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 1, UsedKeccakHashes: 1, UsedPoseidonHashes: 1, UsedPoseidonPaddings: 1, UsedMemAligns: 1, UsedArithmetics: 1, UsedBinaries: 1, UsedSteps: 1, UsedSha256Hashes_V2: 1}, + counters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 1}, usedBytes: 1, expectedTxSortedList: []common.Hash{ {4}, {3}, {2}, {1}, @@ -195,8 +195,8 @@ func TestWorkerGetBestTx(t *testing.T) { var nilErr error rc := state.BatchResources{ - ZKCounters: state.ZKCounters{GasUsed: 10, UsedKeccakHashes: 10, UsedPoseidonHashes: 10, UsedPoseidonPaddings: 10, UsedMemAligns: 10, UsedArithmetics: 10, UsedBinaries: 10, UsedSteps: 10, UsedSha256Hashes_V2: 10}, - Bytes: 10, + UsedZKCounters: state.ZKCounters{GasUsed: 10, KeccakHashes: 10, PoseidonHashes: 10, PoseidonPaddings: 10, MemAligns: 10, Arithmetics: 10, Binaries: 10, Steps: 10, Sha256Hashes_V2: 10}, + Bytes: 10, } stateMock := NewStateMock(t) @@ -222,7 +222,7 @@ func TestWorkerGetBestTx(t *testing.T) { { name: "Adding from:0x01, tx:0x01/gp:10", from: common.Address{1}, txHash: common.Hash{1}, nonce: 1, gasPrice: new(big.Int).SetInt64(10), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 1, UsedKeccakHashes: 1, UsedPoseidonHashes: 1, UsedPoseidonPaddings: 1, UsedMemAligns: 1, UsedArithmetics: 1, UsedBinaries: 1, UsedSteps: 1, UsedSha256Hashes_V2: 1}, + counters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 1}, usedBytes: 1, expectedTxSortedList: []common.Hash{ {1}, @@ -231,7 +231,7 @@ func TestWorkerGetBestTx(t *testing.T) { { name: "Adding from:0x02, tx:0x02/gp:12", from: common.Address{2}, txHash: common.Hash{2}, nonce: 1, gasPrice: new(big.Int).SetInt64(12), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 5, UsedKeccakHashes: 5, UsedPoseidonHashes: 5, UsedPoseidonPaddings: 5, UsedMemAligns: 5, UsedArithmetics: 5, UsedBinaries: 5, UsedSteps: 5, UsedSha256Hashes_V2: 5}, + counters: state.ZKCounters{GasUsed: 5, KeccakHashes: 5, PoseidonHashes: 5, PoseidonPaddings: 5, MemAligns: 5, Arithmetics: 5, Binaries: 5, Steps: 5, Sha256Hashes_V2: 5}, usedBytes: 5, expectedTxSortedList: []common.Hash{ {2}, {1}, @@ -240,7 +240,7 @@ func TestWorkerGetBestTx(t *testing.T) { { name: "Readding from:0x03, tx:0x03/gp:25", from: common.Address{3}, txHash: common.Hash{3}, nonce: 1, gasPrice: new(big.Int).SetInt64(25), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 2, UsedKeccakHashes: 2, UsedPoseidonHashes: 2, UsedPoseidonPaddings: 2, UsedMemAligns: 2, UsedArithmetics: 2, UsedBinaries: 2, UsedSteps: 2, UsedSha256Hashes_V2: 2}, + counters: state.ZKCounters{GasUsed: 2, KeccakHashes: 2, PoseidonHashes: 2, PoseidonPaddings: 2, MemAligns: 2, Arithmetics: 2, Binaries: 2, Steps: 2, Sha256Hashes_V2: 2}, usedBytes: 2, expectedTxSortedList: []common.Hash{ {3}, {2}, {1}, @@ -249,7 +249,7 @@ func TestWorkerGetBestTx(t *testing.T) { { name: "Adding from:0x04, tx:0x04/gp:100", from: common.Address{4}, txHash: common.Hash{4}, nonce: 1, gasPrice: new(big.Int).SetInt64(100), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 4, UsedKeccakHashes: 4, UsedPoseidonHashes: 4, UsedPoseidonPaddings: 4, UsedMemAligns: 4, UsedArithmetics: 4, UsedBinaries: 4, UsedSteps: 4, UsedSha256Hashes_V2: 4}, + counters: state.ZKCounters{GasUsed: 4, KeccakHashes: 4, PoseidonHashes: 4, PoseidonPaddings: 4, MemAligns: 4, Arithmetics: 4, Binaries: 4, Steps: 4, Sha256Hashes_V2: 4}, usedBytes: 4, expectedTxSortedList: []common.Hash{ {4}, {3}, {2}, {1}, diff --git a/state/config.go b/state/config.go index 598b65681b..61e74e63d6 100644 --- a/state/config.go +++ b/state/config.go @@ -74,12 +74,12 @@ type BatchConstraintsCfg struct { // IsWithinConstraints checks if the counters are within the batch constraints func (c BatchConstraintsCfg) IsWithinConstraints(counters ZKCounters) bool { return counters.GasUsed <= c.MaxCumulativeGasUsed && - counters.UsedKeccakHashes <= c.MaxKeccakHashes && - counters.UsedPoseidonHashes <= c.MaxPoseidonHashes && - counters.UsedPoseidonPaddings <= c.MaxPoseidonPaddings && - counters.UsedMemAligns <= c.MaxMemAligns && - counters.UsedArithmetics <= c.MaxArithmetics && - counters.UsedBinaries <= c.MaxBinaries && - counters.UsedSteps <= c.MaxSteps && - counters.UsedSha256Hashes_V2 <= c.MaxSHA256Hashes + counters.KeccakHashes <= c.MaxKeccakHashes && + counters.PoseidonHashes <= c.MaxPoseidonHashes && + counters.PoseidonPaddings <= c.MaxPoseidonPaddings && + counters.MemAligns <= c.MaxMemAligns && + counters.Arithmetics <= c.MaxArithmetics && + counters.Binaries <= c.MaxBinaries && + counters.Steps <= c.MaxSteps && + counters.Sha256Hashes_V2 <= c.MaxSHA256Hashes } diff --git a/state/converters.go b/state/converters.go index 9d26ac975a..c4816b92d1 100644 --- a/state/converters.go +++ b/state/converters.go @@ -307,13 +307,13 @@ func convertToInstrumentationContract(response *executor.Contract) instrumentati func convertToCounters(resp *executor.ProcessBatchResponse) ZKCounters { return ZKCounters{ - GasUsed: resp.CumulativeGasUsed, - UsedKeccakHashes: resp.CntKeccakHashes, - UsedPoseidonHashes: resp.CntPoseidonHashes, - UsedPoseidonPaddings: resp.CntPoseidonPaddings, - UsedMemAligns: resp.CntMemAligns, - UsedArithmetics: resp.CntArithmetics, - UsedBinaries: resp.CntBinaries, - UsedSteps: resp.CntSteps, + GasUsed: resp.CumulativeGasUsed, + KeccakHashes: resp.CntKeccakHashes, + PoseidonHashes: resp.CntPoseidonHashes, + PoseidonPaddings: resp.CntPoseidonPaddings, + MemAligns: resp.CntMemAligns, + Arithmetics: resp.CntArithmetics, + Binaries: resp.CntBinaries, + Steps: resp.CntSteps, } } diff --git a/state/convertersV2.go b/state/convertersV2.go index 9b19898d93..d2e6274497 100644 --- a/state/convertersV2.go +++ b/state/convertersV2.go @@ -49,7 +49,8 @@ func (s *State) convertToProcessBatchResponseV2(batchResponse *executor.ProcessB NewAccInputHash: common.BytesToHash(batchResponse.NewAccInputHash), NewLocalExitRoot: common.BytesToHash(batchResponse.NewLocalExitRoot), NewBatchNumber: batchResponse.NewBatchNum, - UsedZkCounters: convertToCountersV2(batchResponse), + UsedZkCounters: convertToUsedZKCountersV2(batchResponse), + ReservedZkCounters: convertToReservedZKCountersV2(batchResponse), BlockResponses: blockResponses, ExecutorError: executor.ExecutorErr(batchResponse.Error), ReadWriteAddresses: readWriteAddresses, @@ -141,6 +142,7 @@ func (s *State) convertToProcessTransactionResponseV2(responses []*executor.Proc result.EffectivePercentage = response.EffectivePercentage result.HasGaspriceOpcode = (response.HasGaspriceOpcode == 1) result.HasBalanceOpcode = (response.HasBalanceOpcode == 1) + result.Status = response.Status var tx *types.Transaction if response.Error != executor.RomError_ROM_ERROR_INVALID_RLP { @@ -285,17 +287,32 @@ func convertToInstrumentationContractV2(response *executor.ContractV2) instrumen } } -func convertToCountersV2(resp *executor.ProcessBatchResponseV2) ZKCounters { +func convertToUsedZKCountersV2(resp *executor.ProcessBatchResponseV2) ZKCounters { return ZKCounters{ - GasUsed: resp.GasUsed, - UsedKeccakHashes: resp.CntKeccakHashes, - UsedPoseidonHashes: resp.CntPoseidonHashes, - UsedPoseidonPaddings: resp.CntPoseidonPaddings, - UsedMemAligns: resp.CntMemAligns, - UsedArithmetics: resp.CntArithmetics, - UsedBinaries: resp.CntBinaries, - UsedSteps: resp.CntSteps, - UsedSha256Hashes_V2: resp.CntSha256Hashes, + GasUsed: resp.GasUsed, + KeccakHashes: resp.CntKeccakHashes, + PoseidonHashes: resp.CntPoseidonHashes, + PoseidonPaddings: resp.CntPoseidonPaddings, + MemAligns: resp.CntMemAligns, + Arithmetics: resp.CntArithmetics, + Binaries: resp.CntBinaries, + Steps: resp.CntSteps, + Sha256Hashes_V2: resp.CntSha256Hashes, + } +} + +func convertToReservedZKCountersV2(resp *executor.ProcessBatchResponseV2) ZKCounters { + return ZKCounters{ + // There is no "ReserveGasUsed" in the response, so we use "GasUsed" as it will make calculations easier + GasUsed: resp.GasUsed, + KeccakHashes: resp.CntReserveKeccakHashes, + PoseidonHashes: resp.CntReservePoseidonHashes, + PoseidonPaddings: resp.CntReservePoseidonPaddings, + MemAligns: resp.CntReserveMemAligns, + Arithmetics: resp.CntReserveArithmetics, + Binaries: resp.CntReserveBinaries, + Steps: resp.CntReserveSteps, + Sha256Hashes_V2: resp.CntReserveSha256Hashes, } } diff --git a/state/pgstatestorage/pgstatestorage_test.go b/state/pgstatestorage/pgstatestorage_test.go index 9407701b17..3433619603 100644 --- a/state/pgstatestorage/pgstatestorage_test.go +++ b/state/pgstatestorage/pgstatestorage_test.go @@ -55,8 +55,8 @@ var ( mtDBServiceClient hashdb.HashDBServiceClient executorClientConn, mtDBClientConn *grpc.ClientConn batchResources = state.BatchResources{ - ZKCounters: state.ZKCounters{ - UsedKeccakHashes: 1, + UsedZKCounters: state.ZKCounters{ + KeccakHashes: 1, }, Bytes: 1, } diff --git a/state/runtime/executor/executor.pb.go b/state/runtime/executor/executor.pb.go index 7ee33be204..ab7c53e6d6 100644 --- a/state/runtime/executor/executor.pb.go +++ b/state/runtime/executor/executor.pb.go @@ -2589,30 +2589,38 @@ type ProcessBatchResponseV2 struct { sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields - NewStateRoot []byte `protobuf:"bytes,1,opt,name=new_state_root,json=newStateRoot,proto3" json:"new_state_root,omitempty"` - NewAccInputHash []byte `protobuf:"bytes,2,opt,name=new_acc_input_hash,json=newAccInputHash,proto3" json:"new_acc_input_hash,omitempty"` - NewLocalExitRoot []byte `protobuf:"bytes,3,opt,name=new_local_exit_root,json=newLocalExitRoot,proto3" json:"new_local_exit_root,omitempty"` - NewBatchNum uint64 `protobuf:"varint,4,opt,name=new_batch_num,json=newBatchNum,proto3" json:"new_batch_num,omitempty"` - CntKeccakHashes uint32 `protobuf:"varint,5,opt,name=cnt_keccak_hashes,json=cntKeccakHashes,proto3" json:"cnt_keccak_hashes,omitempty"` - CntPoseidonHashes uint32 `protobuf:"varint,6,opt,name=cnt_poseidon_hashes,json=cntPoseidonHashes,proto3" json:"cnt_poseidon_hashes,omitempty"` - CntPoseidonPaddings uint32 `protobuf:"varint,7,opt,name=cnt_poseidon_paddings,json=cntPoseidonPaddings,proto3" json:"cnt_poseidon_paddings,omitempty"` - CntMemAligns uint32 `protobuf:"varint,8,opt,name=cnt_mem_aligns,json=cntMemAligns,proto3" json:"cnt_mem_aligns,omitempty"` - CntArithmetics uint32 `protobuf:"varint,9,opt,name=cnt_arithmetics,json=cntArithmetics,proto3" json:"cnt_arithmetics,omitempty"` - CntBinaries uint32 `protobuf:"varint,10,opt,name=cnt_binaries,json=cntBinaries,proto3" json:"cnt_binaries,omitempty"` - CntSteps uint32 `protobuf:"varint,11,opt,name=cnt_steps,json=cntSteps,proto3" json:"cnt_steps,omitempty"` - CntSha256Hashes uint32 `protobuf:"varint,12,opt,name=cnt_sha256_hashes,json=cntSha256Hashes,proto3" json:"cnt_sha256_hashes,omitempty"` - BlockResponses []*ProcessBlockResponseV2 `protobuf:"bytes,13,rep,name=block_responses,json=blockResponses,proto3" json:"block_responses,omitempty"` - Error ExecutorError `protobuf:"varint,14,opt,name=error,proto3,enum=executor.v1.ExecutorError" json:"error,omitempty"` - ReadWriteAddresses map[string]*InfoReadWriteV2 `protobuf:"bytes,15,rep,name=read_write_addresses,json=readWriteAddresses,proto3" json:"read_write_addresses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` - FlushId uint64 `protobuf:"varint,16,opt,name=flush_id,json=flushId,proto3" json:"flush_id,omitempty"` - StoredFlushId uint64 `protobuf:"varint,17,opt,name=stored_flush_id,json=storedFlushId,proto3" json:"stored_flush_id,omitempty"` - ProverId string `protobuf:"bytes,18,opt,name=prover_id,json=proverId,proto3" json:"prover_id,omitempty"` - GasUsed uint64 `protobuf:"varint,19,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` - SmtKeys [][]byte `protobuf:"bytes,20,rep,name=smt_keys,json=smtKeys,proto3" json:"smt_keys,omitempty"` - ProgramKeys [][]byte `protobuf:"bytes,21,rep,name=program_keys,json=programKeys,proto3" json:"program_keys,omitempty"` - ForkId uint64 `protobuf:"varint,22,opt,name=fork_id,json=forkId,proto3" json:"fork_id,omitempty"` - InvalidBatch uint32 `protobuf:"varint,23,opt,name=invalid_batch,json=invalidBatch,proto3" json:"invalid_batch,omitempty"` - ErrorRom RomError `protobuf:"varint,24,opt,name=error_rom,json=errorRom,proto3,enum=executor.v1.RomError" json:"error_rom,omitempty"` + NewStateRoot []byte `protobuf:"bytes,1,opt,name=new_state_root,json=newStateRoot,proto3" json:"new_state_root,omitempty"` + NewAccInputHash []byte `protobuf:"bytes,2,opt,name=new_acc_input_hash,json=newAccInputHash,proto3" json:"new_acc_input_hash,omitempty"` + NewLocalExitRoot []byte `protobuf:"bytes,3,opt,name=new_local_exit_root,json=newLocalExitRoot,proto3" json:"new_local_exit_root,omitempty"` + NewBatchNum uint64 `protobuf:"varint,4,opt,name=new_batch_num,json=newBatchNum,proto3" json:"new_batch_num,omitempty"` + CntKeccakHashes uint32 `protobuf:"varint,5,opt,name=cnt_keccak_hashes,json=cntKeccakHashes,proto3" json:"cnt_keccak_hashes,omitempty"` + CntPoseidonHashes uint32 `protobuf:"varint,6,opt,name=cnt_poseidon_hashes,json=cntPoseidonHashes,proto3" json:"cnt_poseidon_hashes,omitempty"` + CntPoseidonPaddings uint32 `protobuf:"varint,7,opt,name=cnt_poseidon_paddings,json=cntPoseidonPaddings,proto3" json:"cnt_poseidon_paddings,omitempty"` + CntMemAligns uint32 `protobuf:"varint,8,opt,name=cnt_mem_aligns,json=cntMemAligns,proto3" json:"cnt_mem_aligns,omitempty"` + CntArithmetics uint32 `protobuf:"varint,9,opt,name=cnt_arithmetics,json=cntArithmetics,proto3" json:"cnt_arithmetics,omitempty"` + CntBinaries uint32 `protobuf:"varint,10,opt,name=cnt_binaries,json=cntBinaries,proto3" json:"cnt_binaries,omitempty"` + CntSteps uint32 `protobuf:"varint,11,opt,name=cnt_steps,json=cntSteps,proto3" json:"cnt_steps,omitempty"` + CntSha256Hashes uint32 `protobuf:"varint,12,opt,name=cnt_sha256_hashes,json=cntSha256Hashes,proto3" json:"cnt_sha256_hashes,omitempty"` + BlockResponses []*ProcessBlockResponseV2 `protobuf:"bytes,13,rep,name=block_responses,json=blockResponses,proto3" json:"block_responses,omitempty"` + Error ExecutorError `protobuf:"varint,14,opt,name=error,proto3,enum=executor.v1.ExecutorError" json:"error,omitempty"` + ReadWriteAddresses map[string]*InfoReadWriteV2 `protobuf:"bytes,15,rep,name=read_write_addresses,json=readWriteAddresses,proto3" json:"read_write_addresses,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` + FlushId uint64 `protobuf:"varint,16,opt,name=flush_id,json=flushId,proto3" json:"flush_id,omitempty"` + StoredFlushId uint64 `protobuf:"varint,17,opt,name=stored_flush_id,json=storedFlushId,proto3" json:"stored_flush_id,omitempty"` + ProverId string `protobuf:"bytes,18,opt,name=prover_id,json=proverId,proto3" json:"prover_id,omitempty"` + GasUsed uint64 `protobuf:"varint,19,opt,name=gas_used,json=gasUsed,proto3" json:"gas_used,omitempty"` + SmtKeys [][]byte `protobuf:"bytes,20,rep,name=smt_keys,json=smtKeys,proto3" json:"smt_keys,omitempty"` + ProgramKeys [][]byte `protobuf:"bytes,21,rep,name=program_keys,json=programKeys,proto3" json:"program_keys,omitempty"` + ForkId uint64 `protobuf:"varint,22,opt,name=fork_id,json=forkId,proto3" json:"fork_id,omitempty"` + InvalidBatch uint32 `protobuf:"varint,23,opt,name=invalid_batch,json=invalidBatch,proto3" json:"invalid_batch,omitempty"` + ErrorRom RomError `protobuf:"varint,24,opt,name=error_rom,json=errorRom,proto3,enum=executor.v1.RomError" json:"error_rom,omitempty"` + CntReserveKeccakHashes uint32 `protobuf:"varint,25,opt,name=cnt_reserve_keccak_hashes,json=cntReserveKeccakHashes,proto3" json:"cnt_reserve_keccak_hashes,omitempty"` + CntReservePoseidonHashes uint32 `protobuf:"varint,26,opt,name=cnt_reserve_poseidon_hashes,json=cntReservePoseidonHashes,proto3" json:"cnt_reserve_poseidon_hashes,omitempty"` + CntReservePoseidonPaddings uint32 `protobuf:"varint,27,opt,name=cnt_reserve_poseidon_paddings,json=cntReservePoseidonPaddings,proto3" json:"cnt_reserve_poseidon_paddings,omitempty"` + CntReserveMemAligns uint32 `protobuf:"varint,28,opt,name=cnt_reserve_mem_aligns,json=cntReserveMemAligns,proto3" json:"cnt_reserve_mem_aligns,omitempty"` + CntReserveArithmetics uint32 `protobuf:"varint,29,opt,name=cnt_reserve_arithmetics,json=cntReserveArithmetics,proto3" json:"cnt_reserve_arithmetics,omitempty"` + CntReserveBinaries uint32 `protobuf:"varint,30,opt,name=cnt_reserve_binaries,json=cntReserveBinaries,proto3" json:"cnt_reserve_binaries,omitempty"` + CntReserveSteps uint32 `protobuf:"varint,31,opt,name=cnt_reserve_steps,json=cntReserveSteps,proto3" json:"cnt_reserve_steps,omitempty"` + CntReserveSha256Hashes uint32 `protobuf:"varint,32,opt,name=cnt_reserve_sha256_hashes,json=cntReserveSha256Hashes,proto3" json:"cnt_reserve_sha256_hashes,omitempty"` } func (x *ProcessBatchResponseV2) Reset() { @@ -2815,6 +2823,62 @@ func (x *ProcessBatchResponseV2) GetErrorRom() RomError { return RomError_ROM_ERROR_UNSPECIFIED } +func (x *ProcessBatchResponseV2) GetCntReserveKeccakHashes() uint32 { + if x != nil { + return x.CntReserveKeccakHashes + } + return 0 +} + +func (x *ProcessBatchResponseV2) GetCntReservePoseidonHashes() uint32 { + if x != nil { + return x.CntReservePoseidonHashes + } + return 0 +} + +func (x *ProcessBatchResponseV2) GetCntReservePoseidonPaddings() uint32 { + if x != nil { + return x.CntReservePoseidonPaddings + } + return 0 +} + +func (x *ProcessBatchResponseV2) GetCntReserveMemAligns() uint32 { + if x != nil { + return x.CntReserveMemAligns + } + return 0 +} + +func (x *ProcessBatchResponseV2) GetCntReserveArithmetics() uint32 { + if x != nil { + return x.CntReserveArithmetics + } + return 0 +} + +func (x *ProcessBatchResponseV2) GetCntReserveBinaries() uint32 { + if x != nil { + return x.CntReserveBinaries + } + return 0 +} + +func (x *ProcessBatchResponseV2) GetCntReserveSteps() uint32 { + if x != nil { + return x.CntReserveSteps + } + return 0 +} + +func (x *ProcessBatchResponseV2) GetCntReserveSha256Hashes() uint32 { + if x != nil { + return x.CntReserveSha256Hashes + } + return 0 +} + // Trace configuration request params type TraceConfigV2 struct { state protoimpl.MessageState @@ -3739,6 +3803,8 @@ type ProcessTransactionResponseV2 struct { HasGaspriceOpcode uint32 `protobuf:"varint,19,opt,name=has_gasprice_opcode,json=hasGaspriceOpcode,proto3" json:"has_gasprice_opcode,omitempty"` // Flag to indicate if opcode 'BALANCE' has been called HasBalanceOpcode uint32 `protobuf:"varint,20,opt,name=has_balance_opcode,json=hasBalanceOpcode,proto3" json:"has_balance_opcode,omitempty"` + // Receipt status of the transaction, 1 = success, 0 = failure + Status uint32 `protobuf:"varint,21,opt,name=status,proto3" json:"status,omitempty"` } func (x *ProcessTransactionResponseV2) Reset() { @@ -3913,6 +3979,13 @@ func (x *ProcessTransactionResponseV2) GetHasBalanceOpcode() uint32 { return 0 } +func (x *ProcessTransactionResponseV2) GetStatus() uint32 { + if x != nil { + return x.Status + } + return 0 +} + type LogV2 struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4469,7 +4542,7 @@ var file_executor_proto_rawDesc = []byte{ 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x77, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, - 0x77, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4e, 0x75, 0x6d, 0x22, 0x88, 0x09, 0x0a, 0x16, 0x50, 0x72, + 0x77, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4e, 0x75, 0x6d, 0x22, 0xcb, 0x0c, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, @@ -4535,682 +4608,711 @@ var file_executor_proto_rawDesc = []byte{ 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x32, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x6d, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x6f, 0x6d, 0x1a, - 0x63, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, - 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x32, 0x0a, 0x05, - 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x65, 0x78, - 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, - 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, - 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf3, 0x01, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, - 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, - 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, - 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, - 0x74, 0x61, 0x63, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, - 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6e, 0x61, - 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, - 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x1e, 0x74, 0x78, 0x5f, 0x68, 0x61, - 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x66, - 0x75, 0x6c, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x19, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x22, 0xde, 0x02, 0x0a, 0x11, 0x4f, - 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, - 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, - 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, - 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, - 0x63, 0x6f, 0x64, 0x65, 0x12, 0x3f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, - 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x64, - 0x69, 0x66, 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, - 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x44, - 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x44, - 0x69, 0x66, 0x66, 0x1a, 0x38, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, - 0x0e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x41, 0x0a, 0x0f, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x56, 0x32, 0x12, 0x14, - 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, - 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x80, - 0x01, 0x0a, 0x0b, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, 0x32, 0x12, 0x3b, - 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x21, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, - 0x56, 0x32, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x34, 0x0a, 0x05, 0x73, - 0x74, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x78, 0x65, - 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, - 0x73, 0x22, 0x92, 0x03, 0x0a, 0x14, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, - 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x56, 0x32, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, - 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, - 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, - 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, - 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, - 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, - 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, - 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x25, 0x0a, - 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, - 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6f, 0x6c, - 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, - 0x6e, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, - 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x19, 0x0a, 0x08, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x63, - 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0xae, 0x04, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, - 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x12, 0x1d, 0x0a, 0x0a, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, - 0x65, 0x70, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, - 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x70, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x70, - 0x63, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, - 0x67, 0x61, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x12, 0x1d, - 0x0a, 0x0a, 0x67, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x09, 0x67, 0x61, 0x73, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x12, 0x0e, 0x0a, - 0x02, 0x6f, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x14, 0x0a, - 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x09, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, - 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x23, 0x0a, 0x0d, - 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x0b, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4f, 0x66, 0x66, 0x73, 0x65, - 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, - 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, - 0x74, 0x61, 0x12, 0x33, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x0d, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, 0x52, 0x08, 0x63, - 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x12, 0x45, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, - 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, - 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, - 0x74, 0x65, 0x70, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x53, - 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8e, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, - 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, - 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, - 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, - 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, - 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x03, 0x67, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, - 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xe9, 0x03, 0x0a, 0x16, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x56, 0x32, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, - 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, - 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x21, 0x0a, - 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, - 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x10, - 0x0a, 0x03, 0x67, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x67, 0x65, 0x72, - 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, - 0x31, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, - 0x73, 0x68, 0x4c, 0x31, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, - 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, - 0x26, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x72, 0x6f, - 0x6f, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x49, - 0x6e, 0x66, 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x47, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, - 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x56, 0x32, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, - 0x26, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x56, - 0x32, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, - 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x22, 0x83, 0x06, 0x0a, 0x1c, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, - 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, - 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x32, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x32, 0x12, 0x15, 0x0a, 0x06, - 0x72, 0x6c, 0x70, 0x5f, 0x74, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x6c, - 0x70, 0x54, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, - 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, - 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x74, - 0x75, 0x72, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x19, 0x0a, 0x08, - 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x65, 0x66, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, - 0x67, 0x61, 0x73, 0x4c, 0x65, 0x66, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, - 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, - 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, - 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x11, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x47, 0x61, 0x73, 0x55, 0x73, - 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, - 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x67, 0x61, 0x73, 0x52, 0x65, 0x66, - 0x75, 0x6e, 0x64, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, - 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, - 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, - 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x56, 0x32, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, - 0x12, 0x37, 0x0a, 0x0a, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x10, - 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, - 0x76, 0x31, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, 0x32, 0x52, 0x09, - 0x66, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, - 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, - 0x65, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x65, 0x66, 0x66, - 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, - 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, - 0x76, 0x65, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x13, - 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x73, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x63, - 0x6f, 0x64, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x68, 0x61, 0x73, 0x47, 0x61, - 0x73, 0x70, 0x72, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x2c, 0x0a, 0x12, - 0x68, 0x61, 0x73, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x63, 0x6f, - 0x64, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x68, 0x61, 0x73, 0x42, 0x61, 0x6c, - 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x22, 0xf7, 0x01, 0x0a, 0x05, 0x4c, - 0x6f, 0x67, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, - 0x0a, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, - 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x17, 0x0a, - 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, - 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x5f, 0x6c, 0x32, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, - 0x73, 0x68, 0x4c, 0x32, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, - 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, - 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x08, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x14, - 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, - 0x6e, 0x64, 0x65, 0x78, 0x2a, 0xbd, 0x0a, 0x0a, 0x08, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, - 0x72, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, - 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, - 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x47, 0x41, 0x53, 0x10, 0x02, 0x12, 0x1c, - 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x43, - 0x4b, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, - 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x5f, - 0x55, 0x4e, 0x44, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x04, 0x12, 0x24, 0x0a, 0x20, 0x52, - 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x43, 0x4f, 0x44, - 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, - 0x05, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, - 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, - 0x43, 0x4f, 0x4c, 0x4c, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x12, 0x20, 0x0a, 0x1c, 0x52, - 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x49, - 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x56, 0x45, 0x52, 0x54, 0x45, 0x44, 0x10, 0x07, 0x12, 0x22, 0x0a, - 0x1e, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, - 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x10, - 0x08, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, - 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4b, - 0x45, 0x43, 0x43, 0x41, 0x4b, 0x10, 0x09, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, - 0x54, 0x45, 0x52, 0x53, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x0a, 0x12, 0x21, 0x0a, - 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, - 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x10, 0x0b, - 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, - 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x41, 0x52, - 0x49, 0x54, 0x48, 0x10, 0x0c, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, - 0x52, 0x53, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x0d, 0x12, 0x26, 0x0a, 0x22, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x6f, 0x6d, 0x12, + 0x39, 0x0a, 0x19, 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x6b, + 0x65, 0x63, 0x63, 0x61, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x19, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x16, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4b, 0x65, + 0x63, 0x63, 0x61, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x1b, 0x63, 0x6e, + 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x65, 0x69, 0x64, + 0x6f, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x18, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x50, 0x6f, 0x73, 0x65, 0x69, + 0x64, 0x6f, 0x6e, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x1d, 0x63, 0x6e, 0x74, + 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, + 0x6e, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x1a, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x50, 0x6f, 0x73, 0x65, + 0x69, 0x64, 0x6f, 0x6e, 0x50, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x33, 0x0a, 0x16, + 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, + 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x63, 0x6e, + 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x41, 0x6c, 0x69, 0x67, 0x6e, + 0x73, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, + 0x5f, 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x73, 0x18, 0x1d, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x15, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x41, 0x72, + 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x6e, 0x74, + 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, + 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, + 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, + 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x63, 0x6e, 0x74, 0x5f, 0x72, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, + 0x73, 0x68, 0x65, 0x73, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x63, 0x6e, 0x74, 0x52, + 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, + 0x65, 0x73, 0x1a, 0x63, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, + 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x32, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, + 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, + 0x6f, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf3, 0x01, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x63, + 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, + 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, + 0x6c, 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, + 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x12, + 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, + 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x1e, 0x74, 0x78, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, + 0x65, 0x5f, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x19, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x65, 0x6e, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x22, 0xde, 0x02, + 0x0a, 0x11, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, + 0x74, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, + 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0c, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x3f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, + 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, + 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x73, 0x74, 0x61, + 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x1a, 0x38, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x1a, 0x3c, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x41, + 0x0a, 0x0f, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x56, + 0x32, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, + 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, + 0x65, 0x22, 0x80, 0x01, 0x0a, 0x0b, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, + 0x32, 0x12, 0x3b, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, + 0x65, 0x78, 0x74, 0x56, 0x32, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x34, + 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, + 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x52, 0x05, 0x73, + 0x74, 0x65, 0x70, 0x73, 0x22, 0x92, 0x03, 0x0a, 0x14, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, + 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x56, 0x32, 0x12, 0x12, 0x0a, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, + 0x75, 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, + 0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, + 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, + 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, + 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x73, + 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0c, 0x6f, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, + 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, + 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x19, + 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0xae, 0x04, 0x0a, 0x11, 0x54, 0x72, + 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x12, + 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, + 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, + 0x65, 0x70, 0x74, 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x70, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, + 0x52, 0x02, 0x70, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x63, 0x6f, + 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, + 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x67, 0x61, 0x73, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, + 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x6f, 0x70, + 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, + 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, + 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x1f, + 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x12, + 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, + 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4f, 0x66, + 0x66, 0x73, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, + 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, + 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, + 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, + 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x45, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, + 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x1a, 0x3a, + 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, + 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, + 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8e, 0x01, 0x0a, 0x0a, 0x43, + 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x76, + 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xe9, 0x03, 0x0a, 0x16, + 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, + 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, + 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, + 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, + 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, + 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, + 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, + 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, + 0x70, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, + 0x67, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x5f, 0x6c, 0x31, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x31, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, + 0x73, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, + 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, + 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x47, 0x0a, 0x09, 0x72, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, + 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, + 0x73, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, + 0x32, 0x12, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, + 0x6f, 0x67, 0x56, 0x32, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, + 0x72, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, + 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x9b, 0x06, 0x0a, 0x1c, 0x50, 0x72, 0x6f, 0x63, + 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, + 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, + 0x68, 0x12, 0x1c, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x32, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x32, 0x12, + 0x15, 0x0a, 0x06, 0x72, 0x6c, 0x70, 0x5f, 0x74, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x05, 0x72, 0x6c, 0x70, 0x54, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, + 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, + 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, + 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, + 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x65, 0x66, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x4c, 0x65, 0x66, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, + 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, + 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, + 0x69, 0x76, 0x65, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x11, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x47, 0x61, + 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x66, + 0x75, 0x6e, 0x64, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x67, 0x61, 0x73, + 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, + 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, + 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, + 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, + 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x6c, + 0x6f, 0x67, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x56, 0x32, 0x52, 0x04, 0x6c, + 0x6f, 0x67, 0x73, 0x12, 0x37, 0x0a, 0x0a, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, + 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, + 0x32, 0x52, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, + 0x69, 0x63, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, + 0x74, 0x69, 0x76, 0x65, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x14, + 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, + 0x74, 0x61, 0x67, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x65, 0x66, 0x66, 0x65, + 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, + 0x2e, 0x0a, 0x13, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x73, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, + 0x6f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x68, 0x61, + 0x73, 0x47, 0x61, 0x73, 0x70, 0x72, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x12, + 0x2c, 0x0a, 0x12, 0x68, 0x61, 0x73, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6f, + 0x70, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x68, 0x61, 0x73, + 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, + 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x56, 0x32, 0x12, + 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x70, + 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, + 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, + 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, + 0x68, 0x12, 0x1c, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x32, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x32, 0x12, + 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, + 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2a, + 0xbd, 0x0a, 0x0a, 0x08, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x15, + 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, + 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x4f, 0x4d, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, + 0x18, 0x0a, 0x14, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, + 0x5f, 0x4f, 0x46, 0x5f, 0x47, 0x41, 0x53, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x4d, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x4f, 0x56, 0x45, + 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x4d, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x52, + 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x04, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x49, 0x5a, + 0x45, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x05, 0x12, 0x28, 0x0a, 0x24, + 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, + 0x43, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x49, + 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, + 0x56, 0x45, 0x52, 0x54, 0x45, 0x44, 0x10, 0x07, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x4f, 0x4d, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x10, 0x08, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, - 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x45, 0x49, 0x44, - 0x4f, 0x4e, 0x10, 0x0e, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, - 0x53, 0x5f, 0x53, 0x48, 0x41, 0x10, 0x0f, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x4f, 0x4d, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4a, 0x55, 0x4d, - 0x50, 0x10, 0x10, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4f, 0x50, 0x43, 0x4f, 0x44, 0x45, 0x10, - 0x11, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, - 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x12, 0x12, - 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, - 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, - 0x41, 0x52, 0x54, 0x53, 0x5f, 0x45, 0x46, 0x10, 0x13, 0x12, 0x29, 0x0a, 0x25, 0x52, 0x4f, 0x4d, + 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, + 0x10, 0x09, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, + 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x0a, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x52, + 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, + 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x10, 0x0c, + 0x12, 0x25, 0x0a, 0x21, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, + 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x50, 0x41, + 0x44, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x0d, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x4f, 0x4d, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, + 0x54, 0x45, 0x52, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x45, 0x49, 0x44, 0x4f, 0x4e, 0x10, 0x0e, 0x12, + 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, + 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x53, 0x48, 0x41, + 0x10, 0x0f, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4a, 0x55, 0x4d, 0x50, 0x10, 0x10, 0x12, 0x1c, + 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x5f, 0x4f, 0x50, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x11, 0x12, 0x1c, 0x0a, 0x18, + 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x12, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, + 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, + 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x53, 0x5f, + 0x45, 0x46, 0x10, 0x13, 0x12, 0x29, 0x0a, 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0x14, 0x12, + 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, + 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, + 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x10, 0x15, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, - 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55, - 0x52, 0x45, 0x10, 0x14, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x16, + 0x12, 0x29, 0x0a, 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, + 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, + 0x47, 0x41, 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x17, 0x12, 0x27, 0x0a, 0x23, 0x52, + 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, + 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, + 0x43, 0x45, 0x10, 0x18, 0x12, 0x2f, 0x0a, 0x2b, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x10, 0x15, 0x12, 0x25, - 0x0a, 0x21, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, - 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, - 0x4e, 0x43, 0x45, 0x10, 0x16, 0x12, 0x29, 0x0a, 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, + 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4c, 0x49, + 0x4d, 0x49, 0x54, 0x10, 0x19, 0x12, 0x2b, 0x0a, 0x27, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, - 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x17, - 0x12, 0x27, 0x0a, 0x23, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, - 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, - 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x18, 0x12, 0x2f, 0x0a, 0x2b, 0x52, 0x4f, 0x4d, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, - 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x47, - 0x41, 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x19, 0x12, 0x2b, 0x0a, 0x27, 0x52, 0x4f, - 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, - 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x45, 0x52, - 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x1a, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x4f, 0x4d, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x54, - 0x58, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x1b, - 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x42, 0x41, - 0x54, 0x43, 0x48, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x42, 0x49, 0x47, - 0x10, 0x1c, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x4b, - 0x5f, 0x49, 0x44, 0x10, 0x1d, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x4c, 0x50, 0x10, 0x1e, - 0x12, 0x2c, 0x0a, 0x28, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x48, 0x41, - 0x4e, 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x1f, 0x12, 0x32, - 0x0a, 0x2e, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x5f, 0x54, 0x58, - 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, - 0x10, 0x20, 0x12, 0x38, 0x0a, 0x34, 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, 0x4c, 0x49, 0x4d, 0x49, 0x54, - 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 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, 0xb9, 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, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x44, 0x42, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, - 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, - 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x45, - 0x50, 0x53, 0x10, 0x03, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, + 0x10, 0x1a, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x54, 0x58, 0x5f, 0x47, 0x41, 0x53, + 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x1b, 0x12, 0x20, 0x0a, 0x1c, 0x52, + 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x44, + 0x41, 0x54, 0x41, 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x42, 0x49, 0x47, 0x10, 0x1c, 0x12, 0x21, 0x0a, + 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x55, 0x50, + 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x4b, 0x5f, 0x49, 0x44, 0x10, 0x1d, + 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x4c, 0x50, 0x10, 0x1e, 0x12, 0x2c, 0x0a, 0x28, 0x52, + 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x5f, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4c, + 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x1f, 0x12, 0x32, 0x0a, 0x2e, 0x52, 0x4f, 0x4d, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, + 0x4f, 0x54, 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x5f, 0x54, 0x58, 0x5f, 0x43, 0x48, 0x41, 0x4e, + 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x20, 0x12, 0x38, 0x0a, + 0x34, 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, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, + 0x53, 0x54, 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, + 0xb9, 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, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x1b, + 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x44, 0x42, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x32, 0x0a, 0x2e, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, + 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x53, 0x10, 0x03, 0x12, + 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, + 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x4b, 0x45, 0x43, 0x43, + 0x41, 0x4b, 0x10, 0x04, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, - 0x5f, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x10, 0x04, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, + 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x05, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, - 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x05, 0x12, 0x30, - 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, - 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x4d, 0x45, 0x4d, 0x10, 0x06, - 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, - 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x41, 0x52, 0x49, - 0x54, 0x48, 0x10, 0x07, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, - 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, - 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x08, 0x12, 0x35, 0x0a, 0x31, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, - 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x50, 0x4f, 0x53, 0x45, 0x49, 0x44, 0x4f, 0x4e, 0x10, - 0x09, 0x12, 0x26, 0x0a, 0x22, 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, - 0x46, 0x4f, 0x52, 0x4b, 0x5f, 0x49, 0x44, 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x42, 0x41, 0x4c, 0x41, - 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x0b, 0x12, 0x1d, - 0x0a, 0x19, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x46, 0x45, 0x41, 0x32, 0x53, 0x43, 0x41, 0x4c, 0x41, 0x52, 0x10, 0x0c, 0x12, 0x18, 0x0a, - 0x14, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x54, 0x4f, 0x53, 0x33, 0x32, 0x10, 0x0d, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, - 0x45, 0x44, 0x5f, 0x54, 0x58, 0x10, 0x0e, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x4d, 0x45, 0x4d, 0x10, 0x06, 0x12, 0x32, 0x0a, 0x2e, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, + 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x10, 0x07, 0x12, + 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, + 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x50, 0x41, 0x44, 0x44, + 0x49, 0x4e, 0x47, 0x10, 0x08, 0x12, 0x35, 0x0a, 0x31, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, + 0x57, 0x5f, 0x50, 0x4f, 0x53, 0x45, 0x49, 0x44, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x26, 0x0a, 0x22, + 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, 0x46, 0x4f, 0x52, 0x4b, 0x5f, + 0x49, 0x44, 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x0b, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x46, 0x45, 0x41, 0x32, + 0x53, 0x43, 0x41, 0x4c, 0x41, 0x52, 0x10, 0x0c, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x54, 0x4f, 0x53, 0x33, 0x32, + 0x10, 0x0d, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x5f, 0x54, 0x58, + 0x10, 0x0e, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, + 0x10, 0x0f, 0x12, 0x39, 0x0a, 0x35, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, + 0x54, 0x48, 0x5f, 0x45, 0x43, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x49, 0x56, + 0x49, 0x44, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x10, 0x12, 0x2f, 0x0a, + 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, + 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x11, 0x12, 0x2b, + 0x0a, 0x27, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, + 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x12, 0x12, 0x2e, 0x0a, 0x2a, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x13, 0x12, 0x20, 0x0a, 0x1c, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x10, 0x14, 0x12, 0x32, 0x0a, + 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x53, 0x49, + 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, + 0x15, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, + 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, + 0x49, 0x56, 0x45, 0x10, 0x16, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, + 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, + 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x17, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x55, - 0x4e, 0x54, 0x45, 0x52, 0x53, 0x10, 0x0f, 0x12, 0x39, 0x0a, 0x35, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, + 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, + 0x18, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, + 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, + 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x19, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x45, 0x43, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, - 0x52, 0x5f, 0x44, 0x49, 0x56, 0x49, 0x44, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x5a, 0x45, 0x52, 0x4f, - 0x10, 0x10, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x44, 0x44, - 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, - 0x45, 0x10, 0x11, 0x12, 0x2b, 0x0a, 0x27, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x44, - 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x12, - 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, - 0x47, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x13, - 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, - 0x10, 0x14, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, - 0x48, 0x4b, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, - 0x41, 0x4e, 0x47, 0x45, 0x10, 0x15, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x16, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, - 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, - 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x17, 0x12, 0x38, 0x0a, 0x34, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, - 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, - 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x18, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, - 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x19, 0x12, 0x20, 0x0a, 0x1c, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x10, 0x1a, 0x12, 0x32, - 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x53, - 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, - 0x10, 0x1b, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, - 0x48, 0x50, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, - 0x54, 0x49, 0x56, 0x45, 0x10, 0x1c, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, - 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, - 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x1d, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, - 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, - 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, - 0x10, 0x1e, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, - 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, - 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x1f, 0x12, 0x37, 0x0a, 0x33, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, - 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x53, - 0x45, 0x54, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, - 0x20, 0x12, 0x2a, 0x0a, 0x26, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x55, 0x4c, 0x54, - 0x49, 0x50, 0x4c, 0x45, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x49, 0x4e, 0x10, 0x21, 0x12, 0x21, 0x0a, - 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x10, 0x22, - 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, - 0x59, 0x10, 0x23, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, - 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, - 0x54, 0x43, 0x48, 0x10, 0x24, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4d, 0x49, - 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x25, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, - 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, - 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x26, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, + 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x10, 0x1a, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, - 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x27, 0x12, 0x2e, 0x0a, 0x2a, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x53, 0x49, 0x5a, - 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x28, 0x12, 0x33, 0x0a, 0x2f, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x4c, 0x45, 0x4e, 0x5f, - 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, - 0x29, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, + 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x1b, 0x12, 0x32, 0x0a, + 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, 0x4f, + 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, + 0x1c, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, - 0x4b, 0x4c, 0x45, 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, - 0x45, 0x10, 0x2a, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, - 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, - 0x55, 0x4e, 0x44, 0x10, 0x2b, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, - 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x2c, 0x12, 0x33, 0x0a, - 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, - 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, - 0x10, 0x2d, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, - 0x48, 0x50, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x2e, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x50, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, + 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, + 0x45, 0x10, 0x1d, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, - 0x53, 0x48, 0x50, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, - 0x41, 0x54, 0x43, 0x48, 0x10, 0x2f, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, - 0x41, 0x54, 0x43, 0x48, 0x10, 0x30, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, - 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x31, 0x12, 0x30, 0x0a, 0x2c, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x4c, 0x45, 0x4e, 0x5f, 0x43, - 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x32, 0x12, 0x36, 0x0a, - 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, + 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x1e, 0x12, 0x34, 0x0a, + 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, - 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, - 0x54, 0x43, 0x48, 0x10, 0x33, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, - 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x34, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, - 0x54, 0x43, 0x48, 0x10, 0x35, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x45, 0x43, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, - 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x36, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x41, 0x44, 0x44, 0x5f, - 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x37, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x53, 0x55, 0x42, 0x5f, - 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x38, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4c, 0x54, 0x5f, 0x4d, - 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x39, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x53, 0x4c, 0x54, 0x5f, 0x4d, - 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3a, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x45, 0x51, 0x5f, 0x4d, 0x49, - 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3b, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, - 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x49, - 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3c, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, + 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, + 0x44, 0x10, 0x1f, 0x12, 0x37, 0x0a, 0x33, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, + 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x4f, 0x55, + 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x20, 0x12, 0x2a, 0x0a, 0x26, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x50, 0x4c, 0x45, 0x5f, + 0x46, 0x52, 0x45, 0x45, 0x49, 0x4e, 0x10, 0x21, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, - 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4f, 0x52, 0x5f, 0x4d, 0x49, 0x53, - 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3d, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x58, 0x4f, 0x52, 0x5f, 0x4d, 0x49, 0x53, - 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3e, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, - 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3f, 0x12, 0x33, 0x0a, 0x2f, 0x45, + 0x49, 0x4e, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x10, 0x22, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x57, - 0x52, 0x49, 0x54, 0x45, 0x38, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x40, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x10, 0x23, 0x12, 0x30, + 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, + 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x24, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, - 0x49, 0x47, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x41, 0x12, 0x2c, 0x0a, 0x28, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4a, 0x4d, - 0x50, 0x4e, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, - 0x42, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, + 0x47, 0x45, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, + 0x48, 0x10, 0x25, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, + 0x53, 0x48, 0x4b, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, + 0x43, 0x48, 0x10, 0x26, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, + 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x27, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, + 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x28, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, + 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, + 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x29, 0x12, 0x30, 0x0a, 0x2c, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x4c, 0x45, 0x4e, 0x5f, + 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x2a, 0x12, 0x30, + 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, + 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x2b, + 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, + 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, + 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x2c, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, + 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x2d, 0x12, 0x2f, 0x0a, + 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x56, 0x41, + 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x2e, 0x12, 0x31, + 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, + 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, + 0x2f, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, + 0x50, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, + 0x30, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, - 0x4b, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, - 0x4e, 0x47, 0x45, 0x10, 0x43, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x50, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, + 0x41, 0x54, 0x43, 0x48, 0x10, 0x31, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x4c, 0x45, 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, + 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x32, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, + 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x33, + 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, + 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, + 0x49, 0x43, 0x45, 0x10, 0x34, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, - 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x44, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x5f, 0x4f, 0x4c, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, - 0x4f, 0x54, 0x10, 0x45, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x35, + 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, + 0x5f, 0x45, 0x43, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, + 0x54, 0x43, 0x48, 0x10, 0x36, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, + 0x54, 0x43, 0x48, 0x10, 0x37, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x53, 0x55, 0x42, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, + 0x54, 0x43, 0x48, 0x10, 0x38, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4c, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, + 0x43, 0x48, 0x10, 0x39, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, + 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x53, 0x4c, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, + 0x43, 0x48, 0x10, 0x3a, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, + 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x45, 0x51, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, + 0x48, 0x10, 0x3b, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, + 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, + 0x48, 0x10, 0x3c, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, + 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4f, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, + 0x10, 0x3d, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, + 0x41, 0x52, 0x59, 0x5f, 0x58, 0x4f, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, + 0x10, 0x3e, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, + 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, + 0x41, 0x54, 0x43, 0x48, 0x10, 0x3f, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, + 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x38, + 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x40, 0x12, 0x31, 0x0a, 0x2d, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x52, + 0x45, 0x41, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x41, 0x12, 0x2c, + 0x0a, 0x28, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4a, 0x4d, 0x50, 0x4e, 0x5f, 0x4f, 0x55, + 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x42, 0x12, 0x32, 0x0a, 0x2e, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x52, 0x45, 0x41, + 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x43, + 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, + 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, + 0x47, 0x45, 0x10, 0x44, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4f, - 0x4c, 0x44, 0x5f, 0x41, 0x43, 0x43, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x48, 0x41, 0x53, - 0x48, 0x10, 0x46, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x48, - 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x10, 0x47, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4c, 0x32, 0x5f, 0x44, 0x41, 0x54, 0x41, - 0x10, 0x48, 0x12, 0x2b, 0x0a, 0x27, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x47, 0x4c, 0x4f, - 0x42, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x49, 0x12, - 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x49, 0x4e, 0x42, 0x41, - 0x53, 0x45, 0x10, 0x4a, 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, 0x46, - 0x52, 0x4f, 0x4d, 0x10, 0x4b, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, - 0x44, 0x42, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x4c, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, + 0x4c, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x45, 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, 0x4f, 0x4c, 0x44, 0x5f, 0x41, 0x43, + 0x43, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x46, 0x12, 0x23, + 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, + 0x44, 0x10, 0x47, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, + 0x54, 0x43, 0x48, 0x5f, 0x4c, 0x32, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x10, 0x48, 0x12, 0x2b, 0x0a, + 0x27, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x45, + 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x49, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, + 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x49, 0x4e, 0x42, 0x41, 0x53, 0x45, 0x10, 0x4a, 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, 0x46, 0x52, 0x4f, 0x4d, 0x10, 0x4b, + 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x4b, 0x45, + 0x59, 0x10, 0x4c, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x42, + 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x4d, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x4d, 0x12, 0x31, 0x0a, - 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, - 0x53, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x4e, - 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, - 0x41, 0x43, 0x54, 0x53, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x56, 0x41, - 0x4c, 0x55, 0x45, 0x10, 0x4f, 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, - 0x47, 0x45, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x50, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, + 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, 0x53, 0x5f, 0x42, 0x59, 0x54, + 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x4e, 0x12, 0x33, 0x0a, 0x2f, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, + 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, 0x53, 0x5f, + 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x4f, + 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, 0x47, 0x45, 0x54, 0x5f, 0x4b, + 0x45, 0x59, 0x10, 0x50, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, + 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x51, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, - 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x51, 0x12, 0x20, - 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x10, 0x52, - 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, - 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, - 0x47, 0x45, 0x10, 0x53, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, - 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, - 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x54, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, - 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, - 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, - 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x55, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, - 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, - 0x4e, 0x44, 0x10, 0x56, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, - 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, - 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x57, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, - 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x58, 0x12, 0x31, 0x0a, 0x2d, 0x45, + 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x10, 0x52, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x41, 0x44, 0x44, - 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x59, 0x12, 0x2e, - 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x53, - 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5a, 0x12, 0x33, - 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x4c, 0x45, - 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x5b, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, + 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x53, 0x12, + 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, + 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, + 0x45, 0x10, 0x54, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, - 0x53, 0x48, 0x53, 0x4c, 0x45, 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, - 0x49, 0x43, 0x45, 0x10, 0x5c, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x53, 0x48, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, + 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, + 0x4e, 0x47, 0x45, 0x10, 0x55, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, - 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x5d, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, - 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5e, 0x12, - 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, + 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x56, 0x12, + 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, - 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, - 0x43, 0x45, 0x10, 0x5f, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, - 0x41, 0x53, 0x48, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, - 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x60, 0x12, 0x27, 0x0a, 0x23, 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, 0x52, 0x4f, 0x4f, 0x54, 0x10, - 0x61, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x43, - 0x45, 0x44, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x4c, 0x31, 0x10, - 0x62, 0x12, 0x36, 0x0a, 0x32, 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, 0x44, - 0x41, 0x54, 0x41, 0x5f, 0x56, 0x32, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x45, 0x58, - 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x63, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, + 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, + 0x54, 0x45, 0x44, 0x10, 0x57, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, + 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, + 0x41, 0x54, 0x43, 0x48, 0x10, 0x58, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x59, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, + 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5a, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, + 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, + 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5b, 0x12, 0x30, + 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x4c, 0x45, + 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x5c, + 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, + 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, + 0x10, 0x5d, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, + 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, + 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5e, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, + 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x5f, 0x12, + 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, + 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, + 0x45, 0x10, 0x60, 0x12, 0x27, 0x0a, 0x23, 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, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x61, 0x12, 0x2e, 0x0a, 0x2a, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x42, 0x4c, + 0x4f, 0x43, 0x4b, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x4c, 0x31, 0x10, 0x62, 0x12, 0x36, 0x0a, 0x32, + 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, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x56, + 0x32, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, + 0x4f, 0x54, 0x10, 0x63, 0x12, 0x33, 0x0a, 0x2f, 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, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x56, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, + 0x48, 0x41, 0x53, 0x48, 0x5f, 0x4c, 0x31, 0x10, 0x64, 0x12, 0x27, 0x0a, 0x23, 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, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x56, 0x32, 0x5f, 0x42, - 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x4c, 0x31, 0x10, 0x64, 0x12, 0x27, - 0x0a, 0x23, 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, 0x53, 0x4d, 0x54, 0x5f, - 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x10, 0x65, 0x12, 0x22, 0x0a, 0x1e, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x4c, 0x49, 0x44, 0x5f, 0x4c, 0x31, 0x5f, 0x53, 0x4d, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, + 0x10, 0x65, 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, 0x42, 0x41, 0x4c, + 0x41, 0x4e, 0x43, 0x45, 0x10, 0x66, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, + 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4c, 0x54, 0x34, 0x5f, 0x4d, 0x49, 0x53, 0x4d, + 0x41, 0x54, 0x43, 0x48, 0x10, 0x67, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, + 0x68, 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, 0x4e, 0x45, 0x57, 0x5f, + 0x41, 0x43, 0x43, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x69, + 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x4c, + 0x4f, 0x43, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x6a, + 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x44, 0x42, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, + 0x55, 0x4e, 0x44, 0x10, 0x6b, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x54, 0x5f, 0x49, 0x4e, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x10, 0x6c, 0x12, + 0x24, 0x0a, 0x20, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x44, 0x42, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x10, 0x6d, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4d, 0x41, + 0x4e, 0x41, 0x47, 0x45, 0x52, 0x10, 0x6e, 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, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x66, 0x12, 0x2e, 0x0a, 0x2a, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4c, 0x54, 0x34, - 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x67, 0x12, 0x29, 0x0a, 0x25, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, - 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x68, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x44, 0x5f, 0x4c, 0x31, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x5f, 0x49, + 0x4e, 0x44, 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, 0x4e, 0x45, 0x57, 0x5f, 0x41, 0x43, 0x43, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x48, - 0x41, 0x53, 0x48, 0x10, 0x69, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, - 0x4e, 0x45, 0x57, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, - 0x4f, 0x4f, 0x54, 0x10, 0x6a, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x44, 0x42, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4e, - 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x6b, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x54, - 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x53, 0x49, - 0x5a, 0x45, 0x10, 0x6c, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x44, 0x42, 0x5f, 0x47, 0x52, - 0x50, 0x43, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x6d, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, - 0x54, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x52, 0x10, 0x6e, 0x12, 0x2d, 0x0a, 0x29, + 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, 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, 0x4c, 0x31, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x54, - 0x52, 0x45, 0x45, 0x5f, 0x49, 0x4e, 0x44, 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, 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, - 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, + 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, 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, 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, + 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/types.go b/state/types.go index 10b3f64cb2..d5c0da1c3a 100644 --- a/state/types.go +++ b/state/types.go @@ -44,11 +44,12 @@ type L1DataV2 struct { // ProcessBatchResponse represents the response of a batch process. type ProcessBatchResponse struct { - NewStateRoot common.Hash - NewAccInputHash common.Hash - NewLocalExitRoot common.Hash - NewBatchNumber uint64 - UsedZkCounters ZKCounters + NewStateRoot common.Hash + NewAccInputHash common.Hash + NewLocalExitRoot common.Hash + NewBatchNumber uint64 + UsedZkCounters ZKCounters + ReservedZkCounters ZKCounters // TransactionResponses_V1 []*ProcessTransactionResponse BlockResponses []*ProcessBlockResponse ExecutorError error @@ -117,12 +118,14 @@ type ProcessTransactionResponse struct { FullTrace instrumentation.FullTrace // EffectiveGasPrice effective gas price used for the tx EffectiveGasPrice string - //EffectivePercentage effective percentage used for the tx + // EffectivePercentage effective percentage used for the tx EffectivePercentage uint32 - //HasGaspriceOpcode flag to indicate if opcode 'GASPRICE' has been called + // HasGaspriceOpcode flag to indicate if opcode 'GASPRICE' has been called HasGaspriceOpcode bool - //HasBalanceOpcode flag to indicate if opcode 'BALANCE' has been called + // HasBalanceOpcode flag to indicate if opcode 'BALANCE' has been called HasBalanceOpcode bool + // Status of the transaction, 1 = success, 0 = failure + Status uint32 } // EffectiveGasPriceLog contains all the data needed to calculate the effective gas price for logging purposes @@ -153,28 +156,28 @@ type StoreTxEGPData struct { // ZKCounters counters for the tx type ZKCounters struct { - GasUsed uint64 - UsedKeccakHashes uint32 - UsedPoseidonHashes uint32 - UsedPoseidonPaddings uint32 - UsedMemAligns uint32 - UsedArithmetics uint32 - UsedBinaries uint32 - UsedSteps uint32 - UsedSha256Hashes_V2 uint32 + GasUsed uint64 + KeccakHashes uint32 + PoseidonHashes uint32 + PoseidonPaddings uint32 + MemAligns uint32 + Arithmetics uint32 + Binaries uint32 + Steps uint32 + Sha256Hashes_V2 uint32 } // SumUp sum ups zk counters with passed tx zk counters func (z *ZKCounters) SumUp(other ZKCounters) { z.GasUsed += other.GasUsed - z.UsedKeccakHashes += other.UsedKeccakHashes - z.UsedPoseidonHashes += other.UsedPoseidonHashes - z.UsedPoseidonPaddings += other.UsedPoseidonPaddings - z.UsedMemAligns += other.UsedMemAligns - z.UsedArithmetics += other.UsedArithmetics - z.UsedBinaries += other.UsedBinaries - z.UsedSteps += other.UsedSteps - z.UsedSha256Hashes_V2 += other.UsedSha256Hashes_V2 + z.KeccakHashes += other.KeccakHashes + z.PoseidonHashes += other.PoseidonHashes + z.PoseidonPaddings += other.PoseidonPaddings + z.MemAligns += other.MemAligns + z.Arithmetics += other.Arithmetics + z.Binaries += other.Binaries + z.Steps += other.Steps + z.Sha256Hashes_V2 += other.Sha256Hashes_V2 } // Sub subtract zk counters with passed zk counters (not safe). if there is a counter underflow it returns true and the name of the counter that caused the overflow @@ -183,48 +186,48 @@ func (z *ZKCounters) Sub(other ZKCounters) (bool, string) { if other.GasUsed > z.GasUsed { return true, "CumulativeGas" } - if other.UsedKeccakHashes > z.UsedKeccakHashes { + if other.KeccakHashes > z.KeccakHashes { return true, "KeccakHashes" } - if other.UsedPoseidonHashes > z.UsedPoseidonHashes { + if other.PoseidonHashes > z.PoseidonHashes { return true, "PoseidonHashes" } - if other.UsedPoseidonPaddings > z.UsedPoseidonPaddings { + if other.PoseidonPaddings > z.PoseidonPaddings { return true, "PoseidonPaddings" } - if other.UsedMemAligns > z.UsedMemAligns { + if other.MemAligns > z.MemAligns { return true, "UsedMemAligns" } - if other.UsedArithmetics > z.UsedArithmetics { + if other.Arithmetics > z.Arithmetics { return true, "UsedArithmetics" } - if other.UsedBinaries > z.UsedBinaries { + if other.Binaries > z.Binaries { return true, "UsedBinaries" } - if other.UsedSteps > z.UsedSteps { + if other.Steps > z.Steps { return true, "UsedSteps" } - if other.UsedSha256Hashes_V2 > z.UsedSha256Hashes_V2 { + if other.Sha256Hashes_V2 > z.Sha256Hashes_V2 { return true, "UsedSha256Hashes_V2" } z.GasUsed -= other.GasUsed - z.UsedKeccakHashes -= other.UsedKeccakHashes - z.UsedPoseidonHashes -= other.UsedPoseidonHashes - z.UsedPoseidonPaddings -= other.UsedPoseidonPaddings - z.UsedMemAligns -= other.UsedMemAligns - z.UsedArithmetics -= other.UsedArithmetics - z.UsedBinaries -= other.UsedBinaries - z.UsedSteps -= other.UsedSteps - z.UsedSha256Hashes_V2 -= other.UsedSha256Hashes_V2 + z.KeccakHashes -= other.KeccakHashes + z.PoseidonHashes -= other.PoseidonHashes + z.PoseidonPaddings -= other.PoseidonPaddings + z.MemAligns -= other.MemAligns + z.Arithmetics -= other.Arithmetics + z.Binaries -= other.Binaries + z.Steps -= other.Steps + z.Sha256Hashes_V2 -= other.Sha256Hashes_V2 return false, "" } // BatchResources is a struct that contains the ZKEVM resources used by a batch/tx type BatchResources struct { - ZKCounters ZKCounters - Bytes uint64 + UsedZKCounters ZKCounters + Bytes uint64 } // Sub subtracts the batch resources from other. if there is a resource underflow it returns true and the name of the resource that caused the overflow @@ -235,7 +238,7 @@ func (r *BatchResources) Sub(other BatchResources) (bool, string) { } bytesBackup := r.Bytes r.Bytes -= other.Bytes - exhausted, resourceName := r.ZKCounters.Sub(other.ZKCounters) + exhausted, resourceName := r.UsedZKCounters.Sub(other.UsedZKCounters) if exhausted { r.Bytes = bytesBackup return exhausted, resourceName @@ -247,7 +250,7 @@ func (r *BatchResources) Sub(other BatchResources) (bool, string) { // SumUp sum ups the batch resources from other func (r *BatchResources) SumUp(other BatchResources) { r.Bytes += other.Bytes - r.ZKCounters.SumUp(other.ZKCounters) + r.UsedZKCounters.SumUp(other.UsedZKCounters) } // InfoReadWrite has information about modified addresses during the execution diff --git a/test/docker-compose.yml b/test/docker-compose.yml index e6efff39e6..2b006678cb 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:v5.0.0-RC4 + image: hermeznetwork/zkevm-prover:v5.0.0-RC5 ports: - 50061:50061 # MT - 50071:50071 # Executor @@ -602,7 +602,7 @@ services: zkevm-permissionless-prover: container_name: zkevm-permissionless-prover - image: hermeznetwork/zkevm-prover:v5.0.0-RC4 + image: hermeznetwork/zkevm-prover:v5.0.0-RC5 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover From a039a0aa78ad96f4510c00cb5d9f33bec90b281b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Thu, 22 Feb 2024 12:36:11 +0100 Subject: [PATCH 22/51] Add reserved zk counters to pool transactions (#3346) * add reserved zk counters to pool transaction * add reserved zk counters to pool transaction * correct migration test --- db/migrations/pool/0013.sql | 7 +++ db/migrations/pool/0013_test.go | 50 +++++++++++++++++ pool/interfaces.go | 2 +- pool/pgpoolstorage/pgpoolstorage.go | 55 +++++++++++-------- pool/pool.go | 14 +++-- sequencer/interfaces.go | 2 +- sequencer/mock_pool.go | 21 +++++-- ...te_sync_trusted_state_executor_selector.go | 46 ++++++++++++++++ 8 files changed, 162 insertions(+), 35 deletions(-) create mode 100644 db/migrations/pool/0013.sql create mode 100644 db/migrations/pool/0013_test.go diff --git a/db/migrations/pool/0013.sql b/db/migrations/pool/0013.sql new file mode 100644 index 0000000000..fcf7a58674 --- /dev/null +++ b/db/migrations/pool/0013.sql @@ -0,0 +1,7 @@ +-- +migrate Up +ALTER TABLE pool.transaction + ADD COLUMN reserved_zkcounters jsonb; + +-- +migrate Down +ALTER TABLE pool.transaction + DROP COLUMN reserved_zkcounters; diff --git a/db/migrations/pool/0013_test.go b/db/migrations/pool/0013_test.go new file mode 100644 index 0000000000..e25417a944 --- /dev/null +++ b/db/migrations/pool/0013_test.go @@ -0,0 +1,50 @@ +package pool_migrations_test + +import ( + "database/sql" + "testing" + + "github.com/0xPolygonHermez/zkevm-node/state" + "github.com/stretchr/testify/require" +) + +// this migration adds reserved_zkcounters to the transaction +type migrationTest0013 struct{} + +func (m migrationTest0013) InsertData(db *sql.DB) error { + return nil +} + +func (m migrationTest0013) RunAssertsAfterMigrationUp(t *testing.T, db *sql.DB) { + var reserved_zkcounters = state.ZKCounters{ + GasUsed: 0, + KeccakHashes: 1, + PoseidonHashes: 2, + } + + const insertTx = ` + INSERT INTO pool.transaction (hash, ip, received_at, from_address, reserved_zkcounters) + VALUES ('0x0001', '127.0.0.1', '2023-12-07', '0x0011', $1)` + + _, err := db.Exec(insertTx, reserved_zkcounters) + require.NoError(t, err) +} + +func (m migrationTest0013) RunAssertsAfterMigrationDown(t *testing.T, db *sql.DB) { + var reserved_zkcounters = state.ZKCounters{ + GasUsed: 0, + KeccakHashes: 1, + PoseidonHashes: 2, + } + + const insertTx = ` + INSERT INTO pool.transaction (hash, ip, received_at, from_address, reserved_zkcounters) + VALUES ('0x0001', '127.0.0.1', '2023-12-07', '0x0011', $1)` + + _, err := db.Exec(insertTx, reserved_zkcounters) + require.Error(t, err) +} + +func TestMigration0013(t *testing.T) { + runMigrationTest(t, 13, migrationTest0013{}) +} diff --git a/pool/interfaces.go b/pool/interfaces.go index e61796453a..0544acfe76 100644 --- a/pool/interfaces.go +++ b/pool/interfaces.go @@ -33,7 +33,7 @@ type storage interface { GetTxFromAddressFromByHash(ctx context.Context, hash common.Hash) (common.Address, uint64, error) GetTransactionByHash(ctx context.Context, hash common.Hash) (*Transaction, error) GetTransactionByL2Hash(ctx context.Context, hash common.Hash) (*Transaction, error) - GetTxZkCountersByHash(ctx context.Context, hash common.Hash) (*state.ZKCounters, error) + GetTxZkCountersByHash(ctx context.Context, hash common.Hash) (*state.ZKCounters, *state.ZKCounters, error) DeleteTransactionByHash(ctx context.Context, hash common.Hash) error MarkWIPTxsAsPending(ctx context.Context) error GetAllAddressesBlocked(ctx context.Context) ([]common.Address, error) diff --git a/pool/pgpoolstorage/pgpoolstorage.go b/pool/pgpoolstorage/pgpoolstorage.go index b930f25a5a..fbc0aaea62 100644 --- a/pool/pgpoolstorage/pgpoolstorage.go +++ b/pool/pgpoolstorage/pgpoolstorage.go @@ -75,10 +75,11 @@ func (p *PostgresPoolStorage) AddTx(ctx context.Context, tx pool.Transaction) er from_address, is_wip, ip, - failed_reason + failed_reason, + reserved_zkcounters ) VALUES - ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, NULL) + ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17, $18, $19, NULL, $20) ON CONFLICT (hash) DO UPDATE SET encoded = $2, decoded = $3, @@ -98,7 +99,8 @@ func (p *PostgresPoolStorage) AddTx(ctx context.Context, tx pool.Transaction) er from_address = $17, is_wip = $18, ip = $19, - failed_reason = NULL + failed_reason = NULL, + reserved_zkcounters = $20 ` // Get FromAddress from the JSON data @@ -127,7 +129,8 @@ func (p *PostgresPoolStorage) AddTx(ctx context.Context, tx pool.Transaction) er tx.ReceivedAt, fromAddress, tx.IsWIP, - tx.IP); err != nil { + tx.IP, + tx.ReservedZKCounters); err != nil { return err } return nil @@ -144,11 +147,11 @@ func (p *PostgresPoolStorage) GetTxsByStatus(ctx context.Context, status pool.Tx ) if limit == 0 { sql = `SELECT encoded, status, received_at, is_wip, ip, cumulative_gas_used, used_keccak_hashes, used_poseidon_hashes, used_poseidon_paddings, used_mem_aligns, - used_arithmetics, used_binaries, used_steps, used_sha256_hashes, failed_reason FROM pool.transaction WHERE status = $1 ORDER BY gas_price DESC` + used_arithmetics, used_binaries, used_steps, used_sha256_hashes, failed_reason, reserved_zkcounters FROM pool.transaction WHERE status = $1 ORDER BY gas_price DESC` rows, err = p.db.Query(ctx, sql, status.String()) } else { sql = `SELECT encoded, status, received_at, is_wip, ip, cumulative_gas_used, used_keccak_hashes, used_poseidon_hashes, used_poseidon_paddings, used_mem_aligns, - used_arithmetics, used_binaries, used_steps, used_sha256_hashes, failed_reason FROM pool.transaction WHERE status = $1 ORDER BY gas_price DESC LIMIT $2` + used_arithmetics, used_binaries, used_steps, used_sha256_hashes, failed_reason, reserved_zkcounters FROM pool.transaction WHERE status = $1 ORDER BY gas_price DESC LIMIT $2` rows, err = p.db.Query(ctx, sql, status.String(), limit) } if err != nil { @@ -177,7 +180,7 @@ func (p *PostgresPoolStorage) GetNonWIPPendingTxs(ctx context.Context) ([]pool.T ) sql = `SELECT encoded, status, received_at, is_wip, ip, cumulative_gas_used, used_keccak_hashes, used_poseidon_hashes, used_poseidon_paddings, used_mem_aligns, - used_arithmetics, used_binaries, used_steps, used_sha256_hashes, failed_reason FROM pool.transaction WHERE is_wip IS FALSE and status = $1` + used_arithmetics, used_binaries, used_steps, used_sha256_hashes, failed_reason, reserved_zkcounters FROM pool.transaction WHERE is_wip IS FALSE and status = $1` rows, err = p.db.Query(ctx, sql, pool.TxStatusPending) if err != nil { @@ -236,7 +239,8 @@ func (p *PostgresPoolStorage) GetTxs(ctx context.Context, filterStatus pool.TxSt received_at, nonce, is_wip, - ip + ip, + reserved_zkcounters FROM pool.transaction p1 WHERE @@ -265,7 +269,8 @@ func (p *PostgresPoolStorage) GetTxs(ctx context.Context, filterStatus pool.TxSt received_at, nonce, is_wip, - ip + ip, + reserved_zkcounters FROM pool.transaction p1 WHERE @@ -285,8 +290,9 @@ func (p *PostgresPoolStorage) GetTxs(ctx context.Context, filterStatus pool.TxSt cumulativeGasUsed uint64 usedKeccakHashes, usedPoseidonHashes, usedPoseidonPaddings, usedMemAligns, usedArithmetics, usedBinaries, usedSteps, usedSHA256Hashes uint32 - nonce uint64 - isWIP bool + nonce uint64 + isWIP bool + reservedZKCounters state.ZKCounters ) args := []interface{}{filterStatus, minGasPrice, limit} @@ -316,6 +322,7 @@ func (p *PostgresPoolStorage) GetTxs(ctx context.Context, filterStatus pool.TxSt &nonce, &isWIP, &ip, + &reservedZKCounters, ) if err != nil { @@ -345,6 +352,7 @@ func (p *PostgresPoolStorage) GetTxs(ctx context.Context, filterStatus pool.TxSt } tx.IsWIP = isWIP tx.IP = ip + tx.ReservedZKCounters = reservedZKCounters txs = append(txs, tx) } @@ -511,7 +519,7 @@ func (p *PostgresPoolStorage) IsTxPending(ctx context.Context, hash common.Hash) // GetTxsByFromAndNonce get all the transactions from the pool with the same from and nonce func (p *PostgresPoolStorage) GetTxsByFromAndNonce(ctx context.Context, from common.Address, nonce uint64) ([]pool.Transaction, error) { sql := `SELECT encoded, status, received_at, is_wip, ip, cumulative_gas_used, used_keccak_hashes, used_poseidon_hashes, - used_poseidon_paddings, used_mem_aligns, used_arithmetics, used_binaries, used_steps, used_sha256_hashes, failed_reason + used_poseidon_paddings, used_mem_aligns, used_arithmetics, used_binaries, used_steps, used_sha256_hashes, failed_reason, reserved_zkcounters FROM pool.transaction WHERE from_address = $1 AND nonce = $2` @@ -682,10 +690,11 @@ func scanTx(rows pgx.Rows) (*pool.Transaction, error) { usedSteps uint32 usedSHA256Hashes uint32 failedReason *string + reservedZKCounters state.ZKCounters ) if err := rows.Scan(&encoded, &status, &receivedAt, &isWIP, &ip, &cumulativeGasUsed, &usedKeccakHashes, &usedPoseidonHashes, - &usedPoseidonPaddings, &usedMemAligns, &usedArithmetics, &usedBinaries, &usedSteps, &usedSHA256Hashes, &failedReason); err != nil { + &usedPoseidonPaddings, &usedMemAligns, &usedArithmetics, &usedBinaries, &usedSteps, &usedSHA256Hashes, &failedReason, &reservedZKCounters); err != nil { return nil, err } @@ -714,6 +723,7 @@ func scanTx(rows pgx.Rows) (*pool.Transaction, error) { tx.ZKCounters.Steps = usedSteps tx.ZKCounters.Sha256Hashes_V2 = usedSHA256Hashes tx.FailedReason = failedReason + tx.ReservedZKCounters = reservedZKCounters return tx, nil } @@ -728,21 +738,22 @@ func (p *PostgresPoolStorage) DeleteTransactionByHash(ctx context.Context, hash } // GetTxZkCountersByHash gets a transaction zkcounters by its hash -func (p *PostgresPoolStorage) GetTxZkCountersByHash(ctx context.Context, hash common.Hash) (*state.ZKCounters, error) { - var zkCounters state.ZKCounters +func (p *PostgresPoolStorage) GetTxZkCountersByHash(ctx context.Context, hash common.Hash) (*state.ZKCounters, *state.ZKCounters, error) { + var usedZKCounters state.ZKCounters + var reservedZKCounters state.ZKCounters sql := `SELECT cumulative_gas_used, used_keccak_hashes, used_poseidon_hashes, used_poseidon_paddings, used_mem_aligns, - used_arithmetics, used_binaries, used_steps, used_sha256_hashes FROM pool.transaction WHERE hash = $1` - err := p.db.QueryRow(ctx, sql, hash.String()).Scan(&zkCounters.GasUsed, &zkCounters.KeccakHashes, - &zkCounters.PoseidonHashes, &zkCounters.PoseidonPaddings, - &zkCounters.MemAligns, &zkCounters.Arithmetics, &zkCounters.Binaries, &zkCounters.Steps, &zkCounters.Sha256Hashes_V2) + used_arithmetics, used_binaries, used_steps, used_sha256_hashes, reserved_zkcounters FROM pool.transaction WHERE hash = $1` + err := p.db.QueryRow(ctx, sql, hash.String()).Scan(&usedZKCounters.GasUsed, &usedZKCounters.KeccakHashes, + &usedZKCounters.PoseidonHashes, &usedZKCounters.PoseidonPaddings, + &usedZKCounters.MemAligns, &usedZKCounters.Arithmetics, &usedZKCounters.Binaries, &usedZKCounters.Steps, &usedZKCounters.Sha256Hashes_V2, &reservedZKCounters) if errors.Is(err, pgx.ErrNoRows) { - return nil, pool.ErrNotFound + return nil, nil, pool.ErrNotFound } else if err != nil { - return nil, err + return nil, nil, err } - return &zkCounters, nil + return &usedZKCounters, &reservedZKCounters, nil } // MarkWIPTxsAsPending updates WIP status to non WIP diff --git a/pool/pool.go b/pool/pool.go index 6f67982665..b15df8ebd2 100644 --- a/pool/pool.go +++ b/pool/pool.go @@ -53,7 +53,8 @@ type Pool struct { } type preExecutionResponse struct { - usedZkCounters state.ZKCounters + usedZKCounters state.ZKCounters + reservedZKCounters state.ZKCounters isExecutorLevelError bool OOCError error OOGError error @@ -238,7 +239,8 @@ func (p *Pool) StoreTx(ctx context.Context, tx types.Transaction, ip string, isW } poolTx := NewTransaction(tx, ip, isWIP) - poolTx.ZKCounters = preExecutionResponse.usedZkCounters + poolTx.ZKCounters = preExecutionResponse.usedZKCounters + poolTx.ReservedZKCounters = preExecutionResponse.reservedZKCounters return p.storage.AddTx(ctx, *poolTx) } @@ -292,7 +294,7 @@ func (p *Pool) ValidateBreakEvenGasPrice(ctx context.Context, tx types.Transacti // preExecuteTx executes a transaction to calculate its zkCounters func (p *Pool) preExecuteTx(ctx context.Context, tx types.Transaction) (preExecutionResponse, error) { - response := preExecutionResponse{usedZkCounters: state.ZKCounters{}, OOCError: nil, OOGError: nil, isReverted: false} + response := preExecutionResponse{usedZKCounters: state.ZKCounters{}, reservedZKCounters: state.ZKCounters{}, OOCError: nil, OOGError: nil, isReverted: false} // TODO: Add effectivePercentage = 0xFF to the request (factor of 1) when gRPC message is updated processBatchResponse, err := p.state.PreProcessTransaction(ctx, &tx, nil) @@ -309,7 +311,8 @@ func (p *Pool) preExecuteTx(ctx context.Context, tx types.Transaction) (preExecu response.OOGError = err } if processBatchResponse != nil && processBatchResponse.BlockResponses != nil && len(processBatchResponse.BlockResponses) > 0 { - response.usedZkCounters = processBatchResponse.UsedZkCounters + response.usedZKCounters = processBatchResponse.UsedZkCounters + response.reservedZKCounters = processBatchResponse.ReservedZkCounters response.txResponse = processBatchResponse.BlockResponses[0].TransactionResponses[0] } return response, nil @@ -335,7 +338,8 @@ func (p *Pool) preExecuteTx(ctx context.Context, tx types.Transaction) (preExecu } } - response.usedZkCounters = processBatchResponse.UsedZkCounters + response.usedZKCounters = processBatchResponse.UsedZkCounters + response.reservedZKCounters = processBatchResponse.ReservedZkCounters response.txResponse = processBatchResponse.BlockResponses[0].TransactionResponses[0] } diff --git a/sequencer/interfaces.go b/sequencer/interfaces.go index 21347787c1..9008fbef09 100644 --- a/sequencer/interfaces.go +++ b/sequencer/interfaces.go @@ -22,7 +22,7 @@ type txPool interface { MarkWIPTxsAsPending(ctx context.Context) error GetNonWIPPendingTxs(ctx context.Context) ([]pool.Transaction, error) UpdateTxStatus(ctx context.Context, hash common.Hash, newStatus pool.TxStatus, isWIP bool, failedReason *string) error - GetTxZkCountersByHash(ctx context.Context, hash common.Hash) (*state.ZKCounters, error) + GetTxZkCountersByHash(ctx context.Context, hash common.Hash) (*state.ZKCounters, *state.ZKCounters, error) UpdateTxWIPStatus(ctx context.Context, hash common.Hash, isWIP bool) error GetGasPrices(ctx context.Context) (pool.GasPrices, error) GetDefaultMinGasPriceAllowed() uint64 diff --git a/sequencer/mock_pool.go b/sequencer/mock_pool.go index 5882c83557..00bc480699 100644 --- a/sequencer/mock_pool.go +++ b/sequencer/mock_pool.go @@ -210,7 +210,7 @@ func (_m *PoolMock) GetNonWIPPendingTxs(ctx context.Context) ([]pool.Transaction } // GetTxZkCountersByHash provides a mock function with given fields: ctx, hash -func (_m *PoolMock) GetTxZkCountersByHash(ctx context.Context, hash common.Hash) (*state.ZKCounters, error) { +func (_m *PoolMock) GetTxZkCountersByHash(ctx context.Context, hash common.Hash) (*state.ZKCounters, *state.ZKCounters, error) { ret := _m.Called(ctx, hash) if len(ret) == 0 { @@ -218,8 +218,9 @@ func (_m *PoolMock) GetTxZkCountersByHash(ctx context.Context, hash common.Hash) } var r0 *state.ZKCounters - var r1 error - if rf, ok := ret.Get(0).(func(context.Context, common.Hash) (*state.ZKCounters, error)); ok { + var r1 *state.ZKCounters + var r2 error + if rf, ok := ret.Get(0).(func(context.Context, common.Hash) (*state.ZKCounters, *state.ZKCounters, error)); ok { return rf(ctx, hash) } if rf, ok := ret.Get(0).(func(context.Context, common.Hash) *state.ZKCounters); ok { @@ -230,13 +231,21 @@ func (_m *PoolMock) GetTxZkCountersByHash(ctx context.Context, hash common.Hash) } } - if rf, ok := ret.Get(1).(func(context.Context, common.Hash) error); ok { + if rf, ok := ret.Get(1).(func(context.Context, common.Hash) *state.ZKCounters); ok { r1 = rf(ctx, hash) } else { - r1 = ret.Error(1) + if ret.Get(1) != nil { + r1 = ret.Get(1).(*state.ZKCounters) + } } - return r0, r1 + if rf, ok := ret.Get(2).(func(context.Context, common.Hash) error); ok { + r2 = rf(ctx, hash) + } else { + r2 = ret.Error(2) + } + + return r0, r1, r2 } // MarkWIPTxsAsPending provides a mock function with given fields: ctx diff --git a/synchronizer/l2_sync/l2_shared/mocks/state_sync_trusted_state_executor_selector.go b/synchronizer/l2_sync/l2_shared/mocks/state_sync_trusted_state_executor_selector.go index 443130ad92..3e73051404 100644 --- a/synchronizer/l2_sync/l2_shared/mocks/state_sync_trusted_state_executor_selector.go +++ b/synchronizer/l2_sync/l2_shared/mocks/state_sync_trusted_state_executor_selector.go @@ -20,6 +20,52 @@ func (_m *stateSyncTrustedStateExecutorSelector) EXPECT() *stateSyncTrustedState return &stateSyncTrustedStateExecutorSelector_Expecter{mock: &_m.Mock} } +// GetForkIDByBatchNumber provides a mock function with given fields: batchNumber +func (_m *stateSyncTrustedStateExecutorSelector) GetForkIDByBatchNumber(batchNumber uint64) uint64 { + ret := _m.Called(batchNumber) + + if len(ret) == 0 { + panic("no return value specified for GetForkIDByBatchNumber") + } + + var r0 uint64 + if rf, ok := ret.Get(0).(func(uint64) uint64); ok { + r0 = rf(batchNumber) + } else { + r0 = ret.Get(0).(uint64) + } + + return r0 +} + +// stateSyncTrustedStateExecutorSelector_GetForkIDByBatchNumber_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetForkIDByBatchNumber' +type stateSyncTrustedStateExecutorSelector_GetForkIDByBatchNumber_Call struct { + *mock.Call +} + +// GetForkIDByBatchNumber is a helper method to define mock.On call +// - batchNumber uint64 +func (_e *stateSyncTrustedStateExecutorSelector_Expecter) GetForkIDByBatchNumber(batchNumber interface{}) *stateSyncTrustedStateExecutorSelector_GetForkIDByBatchNumber_Call { + return &stateSyncTrustedStateExecutorSelector_GetForkIDByBatchNumber_Call{Call: _e.mock.On("GetForkIDByBatchNumber", batchNumber)} +} + +func (_c *stateSyncTrustedStateExecutorSelector_GetForkIDByBatchNumber_Call) Run(run func(batchNumber uint64)) *stateSyncTrustedStateExecutorSelector_GetForkIDByBatchNumber_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(uint64)) + }) + return _c +} + +func (_c *stateSyncTrustedStateExecutorSelector_GetForkIDByBatchNumber_Call) Return(_a0 uint64) *stateSyncTrustedStateExecutorSelector_GetForkIDByBatchNumber_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *stateSyncTrustedStateExecutorSelector_GetForkIDByBatchNumber_Call) RunAndReturn(run func(uint64) uint64) *stateSyncTrustedStateExecutorSelector_GetForkIDByBatchNumber_Call { + _c.Call.Return(run) + return _c +} + // GetForkIDInMemory provides a mock function with given fields: forkId func (_m *stateSyncTrustedStateExecutorSelector) GetForkIDInMemory(forkId uint64) *state.ForkIDInterval { ret := _m.Called(forkId) From d218fe283bd8cd70deaf9d780307b5e2d9ce4d6b Mon Sep 17 00:00:00 2001 From: Thiago Coimbra Lemos Date: Thu, 22 Feb 2024 12:29:01 -0300 Subject: [PATCH 23/51] Merge v0.5.13 into v0.6.0 (#3350) --- Dockerfile | 2 +- cmd/run.go | 10 ++ docs/config-file/node-config-doc.html | 2 +- docs/config-file/node-config-doc.md | 113 ++++++++++++++ docs/config-file/node-config-schema.json | 39 +++++ docs/json-rpc-endpoints.md | 10 +- jsonrpc/config.go | 15 ++ jsonrpc/endpoints_eth.go | 6 + jsonrpc/endpoints_eth_test.go | 37 +++-- jsonrpc/endpoints_zkevm.go | 186 +++++++++++++++++------ jsonrpc/endpoints_zkevm.openrpc.json | 155 +++++++++++++++++++ jsonrpc/endpoints_zkevm_test.go | 37 +++-- jsonrpc/mocks/mock_state.go | 30 ++++ jsonrpc/types/interfaces.go | 1 + jsonrpc/types/types.go | 97 +++++++++--- state/errors.go | 4 +- state/pgstatestorage/pgstatestorage.go | 6 +- state/pgstatestorage/transaction.go | 8 +- state/trace.go | 1 + state/transaction.go | 28 +++- test/e2e/debug_calltracer_test.go | 2 +- test/e2e/jsonrpc1_test.go | 121 +++++++++++++++ test/e2e/sc_test.go | 147 +++++++++++++++++- 23 files changed, 950 insertions(+), 107 deletions(-) diff --git a/Dockerfile b/Dockerfile index 8784ba0aa0..510daccca4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,7 +12,7 @@ RUN cd /src/db && packr2 RUN cd /src && make build # CONTAINER FOR RUNNING BINARY -FROM alpine:3.18.4 +FROM alpine:3.18 COPY --from=build /src/dist/zkevm-node /app/zkevm-node COPY --from=build /src/config/environments/testnet/node.config.toml /app/example.config.toml RUN apk update && apk add postgresql15-client diff --git a/cmd/run.go b/cmd/run.go index 17f1d1be5b..072d3faa26 100644 --- a/cmd/run.go +++ b/cmd/run.go @@ -326,6 +326,16 @@ func runJSONRPCServer(c config.Config, etherman *etherman.Client, chainID uint64 storage := jsonrpc.NewStorage() c.RPC.MaxCumulativeGasUsed = c.State.Batch.Constraints.MaxCumulativeGasUsed c.RPC.L2Coinbase = c.SequenceSender.L2Coinbase + c.RPC.ZKCountersLimits = jsonrpc.ZKCountersLimits{ + MaxKeccakHashes: c.State.Batch.Constraints.MaxKeccakHashes, + MaxPoseidonHashes: c.State.Batch.Constraints.MaxPoseidonHashes, + MaxPoseidonPaddings: c.State.Batch.Constraints.MaxPoseidonPaddings, + MaxMemAligns: c.State.Batch.Constraints.MaxMemAligns, + MaxArithmetics: c.State.Batch.Constraints.MaxArithmetics, + MaxBinaries: c.State.Batch.Constraints.MaxBinaries, + MaxSteps: c.State.Batch.Constraints.MaxSteps, + MaxSHA256Hashes: c.State.Batch.Constraints.MaxSHA256Hashes, + } if !c.IsTrustedSequencer { if c.RPC.SequencerNodeURI == "" { log.Debug("getting trusted sequencer URL from smc") diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index f578dbcd6a..3fcf675c97 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -14,7 +14,7 @@
"300ms"
 

Default: "1m0s"Type: string

WriteTimeout is the HTTP server write timeout
check net/http.server.WriteTimeout


Examples:

"1m"
 
"300ms"
-

Default: 500Type: number

MaxRequestsPerIPAndSecond defines how much requests a single IP can
send within a single second


Default: ""Type: string

SequencerNodeURI is used allow Non-Sequencer nodes
to relay transactions to the Sequencer node


Default: 0Type: integer

MaxCumulativeGasUsed is the max gas allowed per batch


WebSockets configuration
Default: trueType: boolean

Enabled defines if the WebSocket requests are enabled or disabled


Default: "0.0.0.0"Type: string

Host defines the network adapter that will be used to serve the WS requests


Default: 8546Type: integer

Port defines the port to serve the endpoints via WS


Default: 104857600Type: integer

ReadLimit defines the maximum size of a message read from the client (in bytes)


Default: trueType: boolean

EnableL2SuggestedGasPricePolling enables polling of the L2 gas price to block tx in the RPC with lower gas price.


Default: falseType: boolean

BatchRequestsEnabled defines if the Batch requests are enabled or disabled


Default: 20Type: integer

BatchRequestsLimit defines the limit of requests that can be incorporated into each batch request


Type: array of integer

L2Coinbase defines which address is going to receive the fees

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Default: 10000Type: integer

MaxLogsCount is a configuration to set the max number of logs that can be returned
in a single call to the state, if zero it means no limit


Default: 10000Type: integer

MaxLogsBlockRange is a configuration to set the max range for block number when querying TXs
logs in a single call to the state, if zero it means no limit


Default: 60000Type: integer

MaxNativeBlockHashBlockRange is a configuration to set the max range for block number when querying
native block hashes in a single call to the state, if zero it means no limit


Default: trueType: boolean

EnableHttpLog allows the user to enable or disable the logs related to the HTTP
requests to be captured by the server.


Configuration of service `Syncrhonizer`. For this service is also really important the value of `IsTrustedSequencer` because depending of this values is going to ask to a trusted node for trusted transactions or not
Default: "1s"Type: string

SyncInterval is the delay interval between reading new rollup information


Examples:

"1m"
+

Default: 500Type: number

MaxRequestsPerIPAndSecond defines how much requests a single IP can
send within a single second


Default: ""Type: string

SequencerNodeURI is used allow Non-Sequencer nodes
to relay transactions to the Sequencer node


Default: 0Type: integer

MaxCumulativeGasUsed is the max gas allowed per batch


WebSockets configuration
Default: trueType: boolean

Enabled defines if the WebSocket requests are enabled or disabled


Default: "0.0.0.0"Type: string

Host defines the network adapter that will be used to serve the WS requests


Default: 8546Type: integer

Port defines the port to serve the endpoints via WS


Default: 104857600Type: integer

ReadLimit defines the maximum size of a message read from the client (in bytes)


Default: trueType: boolean

EnableL2SuggestedGasPricePolling enables polling of the L2 gas price to block tx in the RPC with lower gas price.


Default: falseType: boolean

BatchRequestsEnabled defines if the Batch requests are enabled or disabled


Default: 20Type: integer

BatchRequestsLimit defines the limit of requests that can be incorporated into each batch request


Type: array of integer

L2Coinbase defines which address is going to receive the fees

Must contain a minimum of 20 items

Must contain a maximum of 20 items

Each item of this array must be:


Default: 10000Type: integer

MaxLogsCount is a configuration to set the max number of logs that can be returned
in a single call to the state, if zero it means no limit


Default: 10000Type: integer

MaxLogsBlockRange is a configuration to set the max range for block number when querying TXs
logs in a single call to the state, if zero it means no limit


Default: 60000Type: integer

MaxNativeBlockHashBlockRange is a configuration to set the max range for block number when querying
native block hashes in a single call to the state, if zero it means no limit


Default: trueType: boolean

EnableHttpLog allows the user to enable or disable the logs related to the HTTP
requests to be captured by the server.


ZKCountersLimits defines the ZK Counter limits
Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Default: 0Type: integer

Configuration of service `Syncrhonizer`. For this service is also really important the value of `IsTrustedSequencer` because depending of this values is going to ask to a trusted node for trusted transactions or not
Default: "1s"Type: string

SyncInterval is the delay interval between reading new rollup information


Examples:

"1m"
 
"300ms"
 

Default: 100Type: integer

SyncChunkSize is the number of blocks to sync on each chunk


Default: ""Type: string

TrustedSequencerURL is the rpc url to connect and sync the trusted state


Default: "sequential"Type: enum (of string)

L1SynchronizationMode define how to synchronize with L1:
- parallel: Request data to L1 in parallel, and process sequentially. The advantage is that executor is not blocked waiting for L1 data
- sequential: Request data to L1 and execute

Must be one of:

  • "sequential"
  • "parallel"

L1ParallelSynchronization Configuration for parallel mode (if L1SynchronizationMode equal to 'parallel')
Default: 10Type: integer

MaxClients Number of clients used to synchronize with L1


Default: 25Type: integer

MaxPendingNoProcessedBlocks Size of the buffer used to store rollup information from L1, must be >= to NumberOfEthereumClientsToSync
sugested twice of NumberOfParallelOfEthereumClients


Default: "5s"Type: string

RequestLastBlockPeriod is the time to wait to request the
last block to L1 to known if we need to retrieve more data.
This value only apply when the system is synchronized


Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index 249daf8660..484f48e913 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -913,6 +913,7 @@ ForkID=0
 | - [MaxLogsBlockRange](#RPC_MaxLogsBlockRange )                               | No      | integer          | No         | -          | MaxLogsBlockRange is a configuration to set the max range for block number when querying TXs
logs in a single call to the state, if zero it means no limit | | - [MaxNativeBlockHashBlockRange](#RPC_MaxNativeBlockHashBlockRange ) | No | integer | No | - | MaxNativeBlockHashBlockRange is a configuration to set the max range for block number when querying
native block hashes in a single call to the state, if zero it means no limit | | - [EnableHttpLog](#RPC_EnableHttpLog ) | No | boolean | No | - | EnableHttpLog allows the user to enable or disable the logs related to the HTTP
requests to be captured by the server. | +| - [ZKCountersLimits](#RPC_ZKCountersLimits ) | No | object | No | - | ZKCountersLimits defines the ZK Counter limits | ### 8.1. `RPC.Host` @@ -1215,6 +1216,118 @@ requests to be captured by the server. EnableHttpLog=true ``` +### 8.17. `[RPC.ZKCountersLimits]` + +**Type:** : `object` +**Description:** ZKCountersLimits defines the ZK Counter limits + +| Property | Pattern | Type | Deprecated | Definition | Title/Description | +| ------------------------------------------------------------------- | ------- | ------- | ---------- | ---------- | ----------------- | +| - [MaxKeccakHashes](#RPC_ZKCountersLimits_MaxKeccakHashes ) | No | integer | No | - | - | +| - [MaxPoseidonHashes](#RPC_ZKCountersLimits_MaxPoseidonHashes ) | No | integer | No | - | - | +| - [MaxPoseidonPaddings](#RPC_ZKCountersLimits_MaxPoseidonPaddings ) | No | integer | No | - | - | +| - [MaxMemAligns](#RPC_ZKCountersLimits_MaxMemAligns ) | No | integer | No | - | - | +| - [MaxArithmetics](#RPC_ZKCountersLimits_MaxArithmetics ) | No | integer | No | - | - | +| - [MaxBinaries](#RPC_ZKCountersLimits_MaxBinaries ) | No | integer | No | - | - | +| - [MaxSteps](#RPC_ZKCountersLimits_MaxSteps ) | No | integer | No | - | - | +| - [MaxSHA256Hashes](#RPC_ZKCountersLimits_MaxSHA256Hashes ) | No | integer | No | - | - | + +#### 8.17.1. `RPC.ZKCountersLimits.MaxKeccakHashes` + +**Type:** : `integer` + +**Default:** `0` + +**Example setting the default value** (0): +``` +[RPC.ZKCountersLimits] +MaxKeccakHashes=0 +``` + +#### 8.17.2. `RPC.ZKCountersLimits.MaxPoseidonHashes` + +**Type:** : `integer` + +**Default:** `0` + +**Example setting the default value** (0): +``` +[RPC.ZKCountersLimits] +MaxPoseidonHashes=0 +``` + +#### 8.17.3. `RPC.ZKCountersLimits.MaxPoseidonPaddings` + +**Type:** : `integer` + +**Default:** `0` + +**Example setting the default value** (0): +``` +[RPC.ZKCountersLimits] +MaxPoseidonPaddings=0 +``` + +#### 8.17.4. `RPC.ZKCountersLimits.MaxMemAligns` + +**Type:** : `integer` + +**Default:** `0` + +**Example setting the default value** (0): +``` +[RPC.ZKCountersLimits] +MaxMemAligns=0 +``` + +#### 8.17.5. `RPC.ZKCountersLimits.MaxArithmetics` + +**Type:** : `integer` + +**Default:** `0` + +**Example setting the default value** (0): +``` +[RPC.ZKCountersLimits] +MaxArithmetics=0 +``` + +#### 8.17.6. `RPC.ZKCountersLimits.MaxBinaries` + +**Type:** : `integer` + +**Default:** `0` + +**Example setting the default value** (0): +``` +[RPC.ZKCountersLimits] +MaxBinaries=0 +``` + +#### 8.17.7. `RPC.ZKCountersLimits.MaxSteps` + +**Type:** : `integer` + +**Default:** `0` + +**Example setting the default value** (0): +``` +[RPC.ZKCountersLimits] +MaxSteps=0 +``` + +#### 8.17.8. `RPC.ZKCountersLimits.MaxSHA256Hashes` + +**Type:** : `integer` + +**Default:** `0` + +**Example setting the default value** (0): +``` +[RPC.ZKCountersLimits] +MaxSHA256Hashes=0 +``` + ## 9. `[Synchronizer]` **Type:** : `object` diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json index 95e2e2b248..dfdbad179c 100644 --- a/docs/config-file/node-config-schema.json +++ b/docs/config-file/node-config-schema.json @@ -450,6 +450,45 @@ "type": "boolean", "description": "EnableHttpLog allows the user to enable or disable the logs related to the HTTP\nrequests to be captured by the server.", "default": true + }, + "ZKCountersLimits": { + "properties": { + "MaxKeccakHashes": { + "type": "integer", + "default": 0 + }, + "MaxPoseidonHashes": { + "type": "integer", + "default": 0 + }, + "MaxPoseidonPaddings": { + "type": "integer", + "default": 0 + }, + "MaxMemAligns": { + "type": "integer", + "default": 0 + }, + "MaxArithmetics": { + "type": "integer", + "default": 0 + }, + "MaxBinaries": { + "type": "integer", + "default": 0 + }, + "MaxSteps": { + "type": "integer", + "default": 0 + }, + "MaxSHA256Hashes": { + "type": "integer", + "default": 0 + } + }, + "additionalProperties": false, + "type": "object", + "description": "ZKCountersLimits defines the ZK Counter limits" } }, "additionalProperties": false, diff --git a/docs/json-rpc-endpoints.md b/docs/json-rpc-endpoints.md index ec68b7eb51..659b619ec0 100644 --- a/docs/json-rpc-endpoints.md +++ b/docs/json-rpc-endpoints.md @@ -62,14 +62,18 @@ If the endpoint is not in the list below, it means this specific endpoint is not - `zkevm_batchNumber` - `zkevm_batchNumberByBlockNumber` - `zkevm_consolidatedBlockNumber` +- `zkevm_estimateFee` +- `zkevm_estimateGasPrice` +- `zkevm_estimateCounters` - `zkevm_getBatchByNumber` +- `zkevm_getExitRootsByGER` - `zkevm_getFullBlockByHash` - `zkevm_getFullBlockByNumber` +- `zkevm_getLatestGlobalExitRoot` - `zkevm_getNativeBlockHashesInRange` +- `zkevm_getTransactionByL2Hash` +- `zkevm_getTransactionReceiptByL2Hash` - `zkevm_isBlockConsolidated` - `zkevm_isBlockVirtualized` - `zkevm_verifiedBatchNumber` - `zkevm_virtualBatchNumber` -- `zkevm_getTransactionByL2Hash` -- `zkevm_getTransactionReceiptByL2Hash` -- `zkevm_getExitRootsByGER` diff --git a/jsonrpc/config.go b/jsonrpc/config.go index c2eaa3c75b..183b6c6ff5 100644 --- a/jsonrpc/config.go +++ b/jsonrpc/config.go @@ -62,6 +62,21 @@ type Config struct { // EnableHttpLog allows the user to enable or disable the logs related to the HTTP // requests to be captured by the server. EnableHttpLog bool `mapstructure:"EnableHttpLog"` + + // ZKCountersLimits defines the ZK Counter limits + ZKCountersLimits ZKCountersLimits +} + +// ZKCountersLimits defines the ZK Counter limits +type ZKCountersLimits struct { + MaxKeccakHashes uint32 + MaxPoseidonHashes uint32 + MaxPoseidonPaddings uint32 + MaxMemAligns uint32 + MaxArithmetics uint32 + MaxBinaries uint32 + MaxSteps uint32 + MaxSHA256Hashes uint32 } // WebSocketsConfig has parameters to config the rpc websocket support diff --git a/jsonrpc/endpoints_eth.go b/jsonrpc/endpoints_eth.go index 4d9ffe0270..22fee88874 100644 --- a/jsonrpc/endpoints_eth.go +++ b/jsonrpc/endpoints_eth.go @@ -351,6 +351,12 @@ func (e *EthEndpoints) GetBlockByNumber(number types.BlockNumber, fullTx bool, i return RPCErrorResponse(types.DefaultErrorCode, "couldn't build the pending block response", err, true) } + // clean fields that are not available for pending block + rpcBlock.Hash = nil + rpcBlock.Miner = nil + rpcBlock.Nonce = nil + rpcBlock.TotalDifficulty = nil + return rpcBlock, nil } var err error diff --git a/jsonrpc/endpoints_eth_test.go b/jsonrpc/endpoints_eth_test.go index efa876fb21..60067ab1b3 100644 --- a/jsonrpc/endpoints_eth_test.go +++ b/jsonrpc/endpoints_eth_test.go @@ -1223,7 +1223,7 @@ func TestGetL2BlockByNumber(t *testing.T) { } n := big.NewInt(0).SetUint64(l2Block.Nonce()) - rpcBlockNonce := common.LeftPadBytes(n.Bytes(), 8) //nolint:gomnd + rpcBlockNonce := types.ArgBytes(common.LeftPadBytes(n.Bytes(), 8)) //nolint:gomnd difficulty := types.ArgUint64(0) var totalDifficulty *types.ArgUint64 @@ -1249,7 +1249,7 @@ func TestGetL2BlockByNumber(t *testing.T) { Timestamp: types.ArgUint64(l2Block.Time()), ExtraData: l2Block.Extra(), MixHash: l2Block.MixDigest(), - Nonce: rpcBlockNonce, + Nonce: &rpcBlockNonce, Hash: state.Ptr(l2Block.Hash()), GlobalExitRoot: state.Ptr(l2Block.GlobalExitRoot()), BlockInfoRoot: state.Ptr(l2Block.BlockInfoRoot()), @@ -1422,8 +1422,10 @@ func TestGetL2BlockByNumber(t *testing.T) { tc.ExpectedResult.ExtraData = []byte{} tc.ExpectedResult.GlobalExitRoot = state.Ptr(common.Hash{}) tc.ExpectedResult.BlockInfoRoot = state.Ptr(common.Hash{}) - rpcBlockNonce := common.LeftPadBytes(big.NewInt(0).Bytes(), 8) //nolint:gomnd - tc.ExpectedResult.Nonce = rpcBlockNonce + tc.ExpectedResult.Hash = nil + tc.ExpectedResult.Miner = nil + tc.ExpectedResult.Nonce = nil + tc.ExpectedResult.TotalDifficulty = nil m.DbTx. On("Commit", context.Background()). @@ -1480,17 +1482,11 @@ func TestGetL2BlockByNumber(t *testing.T) { if result != nil || tc.ExpectedResult != nil { assert.Equal(t, tc.ExpectedResult.ParentHash.String(), result.ParentHash.String()) assert.Equal(t, tc.ExpectedResult.Sha3Uncles.String(), result.Sha3Uncles.String()) - if tc.ExpectedResult.Miner != nil { - assert.Equal(t, tc.ExpectedResult.Miner.String(), result.Miner.String()) - } else { - assert.Nil(t, result.Miner) - } assert.Equal(t, tc.ExpectedResult.StateRoot.String(), result.StateRoot.String()) assert.Equal(t, tc.ExpectedResult.TxRoot.String(), result.TxRoot.String()) assert.Equal(t, tc.ExpectedResult.ReceiptsRoot.String(), result.ReceiptsRoot.String()) assert.Equal(t, tc.ExpectedResult.LogsBloom, result.LogsBloom) assert.Equal(t, tc.ExpectedResult.Difficulty, result.Difficulty) - assert.Equal(t, tc.ExpectedResult.TotalDifficulty, result.TotalDifficulty) assert.Equal(t, tc.ExpectedResult.Size, result.Size) assert.Equal(t, tc.ExpectedResult.Number, result.Number) assert.Equal(t, tc.ExpectedResult.GasLimit, result.GasLimit) @@ -1498,14 +1494,29 @@ func TestGetL2BlockByNumber(t *testing.T) { assert.Equal(t, tc.ExpectedResult.Timestamp, result.Timestamp) assert.Equal(t, tc.ExpectedResult.ExtraData, result.ExtraData) assert.Equal(t, tc.ExpectedResult.MixHash, result.MixHash) - assert.Equal(t, tc.ExpectedResult.Nonce, result.Nonce) + assert.Equal(t, tc.ExpectedResult.GlobalExitRoot, result.GlobalExitRoot) + assert.Equal(t, tc.ExpectedResult.BlockInfoRoot, result.BlockInfoRoot) + if tc.ExpectedResult.Hash != nil { assert.Equal(t, tc.ExpectedResult.Hash.String(), result.Hash.String()) } else { assert.Nil(t, result.Hash) } - assert.Equal(t, tc.ExpectedResult.GlobalExitRoot, result.GlobalExitRoot) - assert.Equal(t, tc.ExpectedResult.BlockInfoRoot, result.BlockInfoRoot) + if tc.ExpectedResult.Miner != nil { + assert.Equal(t, tc.ExpectedResult.Miner.String(), result.Miner.String()) + } else { + assert.Nil(t, result.Miner) + } + if tc.ExpectedResult.Nonce != nil { + assert.Equal(t, tc.ExpectedResult.Nonce, result.Nonce) + } else { + assert.Nil(t, result.Nonce) + } + if tc.ExpectedResult.TotalDifficulty != nil { + assert.Equal(t, tc.ExpectedResult.TotalDifficulty, result.TotalDifficulty) + } else { + assert.Nil(t, result.TotalDifficulty) + } assert.Equal(t, len(tc.ExpectedResult.Transactions), len(result.Transactions)) assert.Equal(t, len(tc.ExpectedResult.Uncles), len(result.Uncles)) diff --git a/jsonrpc/endpoints_zkevm.go b/jsonrpc/endpoints_zkevm.go index ab82cc476f..f4c6020ba8 100644 --- a/jsonrpc/endpoints_zkevm.go +++ b/jsonrpc/endpoints_zkevm.go @@ -15,6 +15,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/pool" "github.com/0xPolygonHermez/zkevm-node/state" "github.com/0xPolygonHermez/zkevm-node/state/runtime" + "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/ethereum/go-ethereum/common" ethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/jackc/pgx/v4" @@ -223,6 +224,12 @@ func (z *ZKEVMEndpoints) GetFullBlockByNumber(number types.BlockNumber, fullTx b return RPCErrorResponse(types.DefaultErrorCode, "couldn't build the pending block response", err, true) } + // clean fields that are not available for pending block + rpcBlock.Hash = nil + rpcBlock.Miner = nil + rpcBlock.Nonce = nil + rpcBlock.TotalDifficulty = nil + return rpcBlock, nil } var err error @@ -427,8 +434,112 @@ func (z *ZKEVMEndpoints) GetExitRootsByGER(globalExitRoot common.Hash) (interfac }) } +// EstimateGasPrice returns an estimate gas price for the transaction. +func (z *ZKEVMEndpoints) EstimateGasPrice(arg *types.TxArgs, blockArg *types.BlockNumberOrHash) (interface{}, types.Error) { + return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { + gasPrice, _, err := z.internalEstimateGasPriceAndFee(ctx, arg, blockArg, dbTx) + if err != nil { + return nil, err + } + return hex.EncodeBig(gasPrice), nil + }) +} + // EstimateFee returns an estimate fee for the transaction. func (z *ZKEVMEndpoints) EstimateFee(arg *types.TxArgs, blockArg *types.BlockNumberOrHash) (interface{}, types.Error) { + return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { + _, fee, err := z.internalEstimateGasPriceAndFee(ctx, arg, blockArg, dbTx) + if err != nil { + return nil, err + } + return hex.EncodeBig(fee), nil + }) +} + +// internalEstimateGasPriceAndFee computes the estimated gas price and the estimated fee for the transaction +func (z *ZKEVMEndpoints) internalEstimateGasPriceAndFee(ctx context.Context, arg *types.TxArgs, blockArg *types.BlockNumberOrHash, dbTx pgx.Tx) (*big.Int, *big.Int, types.Error) { + if arg == nil { + return nil, nil, types.NewRPCError(types.InvalidParamsErrorCode, "missing value for required argument 0") + } + + block, respErr := z.getBlockByArg(ctx, blockArg, dbTx) + if respErr != nil { + return nil, nil, respErr + } + + var blockToProcess *uint64 + if blockArg != nil { + blockNumArg := blockArg.Number() + if blockNumArg != nil && (*blockArg.Number() == types.LatestBlockNumber || *blockArg.Number() == types.PendingBlockNumber) { + blockToProcess = nil + } else { + n := block.NumberU64() + blockToProcess = &n + } + } + + defaultSenderAddress := common.HexToAddress(state.DefaultSenderAddress) + sender, tx, err := arg.ToTransaction(ctx, z.state, z.cfg.MaxCumulativeGasUsed, block.Root(), defaultSenderAddress, dbTx) + if err != nil { + return nil, nil, types.NewRPCError(types.DefaultErrorCode, "failed to convert arguments into an unsigned transaction") + } + + gasEstimation, returnValue, err := z.state.EstimateGas(tx, sender, blockToProcess, dbTx) + if errors.Is(err, runtime.ErrExecutionReverted) { + data := make([]byte, len(returnValue)) + copy(data, returnValue) + return nil, nil, types.NewRPCErrorWithData(types.RevertedErrorCode, err.Error(), data) + } else if err != nil { + errMsg := fmt.Sprintf("failed to estimate gas: %v", err.Error()) + return nil, nil, types.NewRPCError(types.DefaultErrorCode, errMsg) + } + + gasPrices, err := z.pool.GetGasPrices(ctx) + if err != nil { + return nil, nil, types.NewRPCError(types.DefaultErrorCode, "failed to get L2 gas price", err, false) + } + + txGasPrice := new(big.Int).SetUint64(gasPrices.L2GasPrice) // by default we assume the tx gas price is the current L2 gas price + txEGPPct := state.MaxEffectivePercentage + egpEnabled := z.pool.EffectiveGasPriceEnabled() + + if egpEnabled { + rawTx, err := state.EncodeTransactionWithoutEffectivePercentage(*tx) + if err != nil { + return nil, nil, types.NewRPCError(types.DefaultErrorCode, "failed to encode tx", err, false) + } + + txEGP, err := z.pool.CalculateEffectiveGasPrice(rawTx, txGasPrice, gasEstimation, gasPrices.L1GasPrice, gasPrices.L2GasPrice) + if err != nil { + return nil, nil, types.NewRPCError(types.DefaultErrorCode, "failed to calculate effective gas price", err, false) + } + + if txEGP.Cmp(txGasPrice) == -1 { // txEGP < txGasPrice + // We need to "round" the final effectiveGasPrice to a 256 fraction of the txGasPrice + txEGPPct, err = z.pool.CalculateEffectiveGasPricePercentage(txGasPrice, txEGP) + if err != nil { + return nil, nil, types.NewRPCError(types.DefaultErrorCode, "failed to calculate effective gas price percentage", err, false) + } + // txGasPriceFraction = txGasPrice/256 + txGasPriceFraction := new(big.Int).Div(txGasPrice, new(big.Int).SetUint64(256)) //nolint:gomnd + // txGasPrice = txGasPriceFraction*(txEGPPct+1) + txGasPrice = new(big.Int).Mul(txGasPriceFraction, new(big.Int).SetUint64(uint64(txEGPPct+1))) + } + + log.Infof("[internalEstimateGasPriceAndFee] finalGasPrice: %d, effectiveGasPrice: %d, egpPct: %d, l2GasPrice: %d, len: %d, gas: %d, l1GasPrice: %d", + txGasPrice, txEGP, txEGPPct, gasPrices.L2GasPrice, len(rawTx), gasEstimation, gasPrices.L1GasPrice) + } + + fee := new(big.Int).Mul(txGasPrice, new(big.Int).SetUint64(gasEstimation)) + + log.Infof("[internalEstimateGasPriceAndFee] egpEnabled: %t, fee: %d, gasPrice: %d, gas: %d", egpEnabled, fee, txGasPrice, gasEstimation) + + return txGasPrice, fee, nil +} + +// EstimateCounters returns an estimation of the counters that are going to be used while executing +// this transaction. +func (z *ZKEVMEndpoints) EstimateCounters(arg *types.TxArgs, blockArg *types.BlockNumberOrHash) (interface{}, types.Error) { return z.txMan.NewDbTxScope(z.state, func(ctx context.Context, dbTx pgx.Tx) (interface{}, types.Error) { if arg == nil { return RPCErrorResponse(types.InvalidParamsErrorCode, "missing value for required argument 0", nil, false) @@ -456,57 +567,44 @@ func (z *ZKEVMEndpoints) EstimateFee(arg *types.TxArgs, blockArg *types.BlockNum return RPCErrorResponse(types.DefaultErrorCode, "failed to convert arguments into an unsigned transaction", err, false) } - gasEstimation, returnValue, err := z.state.EstimateGas(tx, sender, blockToProcess, dbTx) - if errors.Is(err, runtime.ErrExecutionReverted) { - data := make([]byte, len(returnValue)) - copy(data, returnValue) - return nil, types.NewRPCErrorWithData(types.RevertedErrorCode, err.Error(), data) - } else if err != nil { - errMsg := fmt.Sprintf("failed to estimate gas: %v", err.Error()) - return nil, types.NewRPCError(types.DefaultErrorCode, errMsg) - } - - gasPrices, err := z.pool.GetGasPrices(ctx) + var oocErr error + processBatchResponse, err := z.state.PreProcessUnsignedTransaction(ctx, tx, sender, blockToProcess, dbTx) if err != nil { - return RPCErrorResponse(types.DefaultErrorCode, "failed to get L2 gas price", err, false) - } - - txGasPrice := new(big.Int).SetUint64(gasPrices.L2GasPrice) // by default we assume the tx gas price is the current L2 gas price - txEGPPct := state.MaxEffectivePercentage - egpEnabled := z.pool.EffectiveGasPriceEnabled() - - if egpEnabled { - rawTx, err := state.EncodeTransactionWithoutEffectivePercentage(*tx) - if err != nil { - return RPCErrorResponse(types.DefaultErrorCode, "failed to encode tx", err, false) - } - - txEGP, err := z.pool.CalculateEffectiveGasPrice(rawTx, txGasPrice, gasEstimation, gasPrices.L1GasPrice, gasPrices.L2GasPrice) - if err != nil { - return RPCErrorResponse(types.DefaultErrorCode, "failed to calculate effective gas price", err, false) + if executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) { + oocErr = err + } else { + errMsg := fmt.Sprintf("failed to estimate counters: %v", err.Error()) + return nil, types.NewRPCError(types.DefaultErrorCode, errMsg) } + } - if txEGP.Cmp(txGasPrice) == -1 { // txEGP < txGasPrice - // We need to "round" the final effectiveGasPrice to a 256 fraction of the txGasPrice - txEGPPct, err = z.pool.CalculateEffectiveGasPricePercentage(txGasPrice, txEGP) - if err != nil { - return RPCErrorResponse(types.DefaultErrorCode, "failed to calculate effective gas price percentage", err, false) + var revert *types.RevertInfo + if len(processBatchResponse.BlockResponses) > 0 && len(processBatchResponse.BlockResponses[0].TransactionResponses) > 0 { + txResponse := processBatchResponse.BlockResponses[0].TransactionResponses[0] + err = txResponse.RomError + if errors.Is(err, runtime.ErrExecutionReverted) { + returnValue := make([]byte, len(txResponse.ReturnValue)) + copy(returnValue, txResponse.ReturnValue) + err := state.ConstructErrorFromRevert(err, returnValue) + revert = &types.RevertInfo{ + Message: err.Error(), + Data: state.Ptr(types.ArgBytes(returnValue)), } - // txGasPriceFraction = txGasPrice/256 - txGasPriceFraction := new(big.Int).Div(txGasPrice, new(big.Int).SetUint64(256)) //nolint:gomnd - // txGasPrice = txGasPriceFraction*(txEGPPct+1) - txGasPrice = new(big.Int).Mul(txGasPriceFraction, new(big.Int).SetUint64(uint64(txEGPPct+1))) } - - log.Infof("[EstimateFee] finalGasPrice: %d, effectiveGasPrice: %d, egpPct: %d, l2GasPrice: %d, len: %d, gas: %d, l1GasPrice: %d", - txGasPrice, txEGP, txEGPPct, gasPrices.L2GasPrice, len(rawTx), gasEstimation, gasPrices.L1GasPrice) } - fee := new(big.Int).Mul(txGasPrice, new(big.Int).SetUint64(gasEstimation)) - - log.Infof("[EstimateFee] egpEnabled: %t, fee: %d, gasPrice: %d, gas: %d", egpEnabled, fee, txGasPrice, gasEstimation) - - return hex.EncodeBig(fee), nil + limits := types.ZKCountersLimits{ + MaxGasUsed: types.ArgUint64(state.MaxTxGasLimit), + MaxKeccakHashes: types.ArgUint64(z.cfg.ZKCountersLimits.MaxKeccakHashes), + MaxPoseidonHashes: types.ArgUint64(z.cfg.ZKCountersLimits.MaxPoseidonHashes), + MaxPoseidonPaddings: types.ArgUint64(z.cfg.ZKCountersLimits.MaxPoseidonPaddings), + MaxMemAligns: types.ArgUint64(z.cfg.ZKCountersLimits.MaxMemAligns), + MaxArithmetics: types.ArgUint64(z.cfg.ZKCountersLimits.MaxArithmetics), + MaxBinaries: types.ArgUint64(z.cfg.ZKCountersLimits.MaxBinaries), + MaxSteps: types.ArgUint64(z.cfg.ZKCountersLimits.MaxSteps), + MaxSHA256Hashes: types.ArgUint64(z.cfg.ZKCountersLimits.MaxSHA256Hashes), + } + return types.NewZKCountersResponse(processBatchResponse.UsedZkCounters, limits, revert, oocErr), nil }) } diff --git a/jsonrpc/endpoints_zkevm.openrpc.json b/jsonrpc/endpoints_zkevm.openrpc.json index 36216cc09d..d795e0f1cb 100644 --- a/jsonrpc/endpoints_zkevm.openrpc.json +++ b/jsonrpc/endpoints_zkevm.openrpc.json @@ -423,6 +423,54 @@ "$ref": "#/components/schemas/Keccak" } } + }, + { + "name": "zkevm_estimateCounters", + "summary": "Estimates the transaction ZK Counters", + "params": [ + { + "$ref": "#/components/contentDescriptors/Transaction" + } + ], + "result": { + "name": "counters", + "description": "The counters used, limits and revert info when tx reverted", + "schema": { + "$ref": "#/components/schemas/ZKCountersResponse" + } + } + }, + { + "name": "zkevm_estimateFee", + "summary": "Estimates the transaction Fee following the effective gas price rules", + "params": [ + { + "$ref": "#/components/contentDescriptors/Transaction" + } + ], + "result": { + "name": "fee", + "description": "The amount of the fee", + "schema": { + "$ref": "#/components/schemas/Integer" + } + } + }, + { + "name": "zkevm_estimateGasPrice", + "summary": "Estimates the transaction Gas Price following the effective gas price rules", + "params": [ + { + "$ref": "#/components/contentDescriptors/Transaction" + } + ], + "result": { + "name": "gasPrice", + "description": "The amount of gas price", + "schema": { + "$ref": "#/components/schemas/Integer" + } + } } ], "components": { @@ -472,6 +520,13 @@ "$ref": "#/components/schemas/Block" } }, + "Transaction": { + "required": true, + "name": "transaction", + "schema": { + "$ref": "#/components/schemas/Transaction" + } + }, "TransactionHash": { "name": "transactionHash", "required": true, @@ -1282,6 +1337,106 @@ "$ref": "#/components/schemas/Keccak" } } + }, + "ZKCountersResponse": { + "title": "ZKCountersResponse", + "type": "object", + "readOnly": true, + "properties": { + "countersUsed": { + "$ref": "#/components/schemas/ZKCountersUsed" + }, + "countersLimits": { + "$ref": "#/components/schemas/ZKCountersLimits" + }, + "revertInfo": { + "$ref": "#/components/schemas/RevertInfo" + }, + "oocError": { + "type": "string" + } + } + }, + "ZKCountersUsed": { + "title": "ZKCountersUsed", + "type": "object", + "readOnly": true, + "properties": { + "gasUsed": { + "$ref": "#/components/schemas/Integer" + }, + "usedKeccakHashes": { + "$ref": "#/components/schemas/Integer" + }, + "usedPoseidonHashes": { + "$ref": "#/components/schemas/Integer" + }, + "usedPoseidonPaddings": { + "$ref": "#/components/schemas/Integer" + }, + "usedMemAligns": { + "$ref": "#/components/schemas/Integer" + }, + "usedArithmetics": { + "$ref": "#/components/schemas/Integer" + }, + "usedBinaries": { + "$ref": "#/components/schemas/Integer" + }, + "usedSteps": { + "$ref": "#/components/schemas/Integer" + }, + "usedSHA256Hashes": { + "$ref": "#/components/schemas/Integer" + } + } + }, + "ZKCountersLimits":{ + "title": "ZKCountersLimits", + "type": "object", + "readOnly": true, + "properties": { + "maxGasUsed": { + "$ref": "#/components/schemas/Integer" + }, + "maxUsedKeccakHashes": { + "$ref": "#/components/schemas/Integer" + }, + "maxUsedPoseidonHashes": { + "$ref": "#/components/schemas/Integer" + }, + "maxUsedPoseidonPaddings": { + "$ref": "#/components/schemas/Integer" + }, + "maxUsedMemAligns": { + "$ref": "#/components/schemas/Integer" + }, + "maxUsedArithmetics": { + "$ref": "#/components/schemas/Integer" + }, + "maxUsedBinaries": { + "$ref": "#/components/schemas/Integer" + }, + "maxUsedSteps": { + "$ref": "#/components/schemas/Integer" + }, + "maxUsedSHA256Hashes": { + "$ref": "#/components/schemas/Integer" + } + } + }, + "RevertInfo":{ + "title": "RevertInfo", + "type": "object", + "readOnly": true, + "properties": { + "message": { + "type": "string" + }, + "data": { + "$ref": "#/components/schemas/Integer" + } + } } } } diff --git a/jsonrpc/endpoints_zkevm_test.go b/jsonrpc/endpoints_zkevm_test.go index 4293a2d7ae..85db81328b 100644 --- a/jsonrpc/endpoints_zkevm_test.go +++ b/jsonrpc/endpoints_zkevm_test.go @@ -1445,7 +1445,7 @@ func TestGetL2FullBlockByNumber(t *testing.T) { } n := big.NewInt(0).SetUint64(l2Block.Nonce()) - rpcBlockNonce := common.LeftPadBytes(n.Bytes(), 8) //nolint:gomnd + rpcBlockNonce := types.ArgBytes(common.LeftPadBytes(n.Bytes(), 8)) //nolint:gomnd difficulty := types.ArgUint64(0) var totalDifficulty *types.ArgUint64 @@ -1471,7 +1471,7 @@ func TestGetL2FullBlockByNumber(t *testing.T) { Timestamp: types.ArgUint64(l2Block.Time()), ExtraData: l2Block.Extra(), MixHash: l2Block.MixDigest(), - Nonce: rpcBlockNonce, + Nonce: &rpcBlockNonce, Hash: state.Ptr(l2Block.Hash()), GlobalExitRoot: state.Ptr(l2Block.GlobalExitRoot()), BlockInfoRoot: state.Ptr(l2Block.BlockInfoRoot()), @@ -1635,8 +1635,10 @@ func TestGetL2FullBlockByNumber(t *testing.T) { tc.ExpectedResult.ExtraData = []byte{} tc.ExpectedResult.GlobalExitRoot = state.Ptr(common.Hash{}) tc.ExpectedResult.BlockInfoRoot = state.Ptr(common.Hash{}) - rpcBlockNonce := common.LeftPadBytes(big.NewInt(0).Bytes(), 8) //nolint:gomnd - tc.ExpectedResult.Nonce = rpcBlockNonce + tc.ExpectedResult.Hash = nil + tc.ExpectedResult.Miner = nil + tc.ExpectedResult.Nonce = nil + tc.ExpectedResult.TotalDifficulty = nil m.DbTx. On("Commit", context.Background()). @@ -1699,17 +1701,11 @@ func TestGetL2FullBlockByNumber(t *testing.T) { assert.Equal(t, tc.ExpectedResult.ParentHash.String(), result.ParentHash.String()) assert.Equal(t, tc.ExpectedResult.Sha3Uncles.String(), result.Sha3Uncles.String()) - if tc.ExpectedResult.Miner != nil { - assert.Equal(t, tc.ExpectedResult.Miner.String(), result.Miner.String()) - } else { - assert.Nil(t, result.Miner) - } assert.Equal(t, tc.ExpectedResult.StateRoot.String(), result.StateRoot.String()) assert.Equal(t, tc.ExpectedResult.TxRoot.String(), result.TxRoot.String()) assert.Equal(t, tc.ExpectedResult.ReceiptsRoot.String(), result.ReceiptsRoot.String()) assert.Equal(t, tc.ExpectedResult.LogsBloom, result.LogsBloom) assert.Equal(t, tc.ExpectedResult.Difficulty, result.Difficulty) - assert.Equal(t, tc.ExpectedResult.TotalDifficulty, result.TotalDifficulty) assert.Equal(t, tc.ExpectedResult.Size, result.Size) assert.Equal(t, tc.ExpectedResult.Number, result.Number) assert.Equal(t, tc.ExpectedResult.GasLimit, result.GasLimit) @@ -1717,14 +1713,29 @@ func TestGetL2FullBlockByNumber(t *testing.T) { assert.Equal(t, tc.ExpectedResult.Timestamp, result.Timestamp) assert.Equal(t, tc.ExpectedResult.ExtraData, result.ExtraData) assert.Equal(t, tc.ExpectedResult.MixHash, result.MixHash) - assert.Equal(t, tc.ExpectedResult.Nonce, result.Nonce) + assert.Equal(t, tc.ExpectedResult.GlobalExitRoot, result.GlobalExitRoot) + assert.Equal(t, tc.ExpectedResult.BlockInfoRoot, result.BlockInfoRoot) + if tc.ExpectedResult.Hash != nil { assert.Equal(t, tc.ExpectedResult.Hash.String(), result.Hash.String()) } else { assert.Nil(t, result.Hash) } - assert.Equal(t, tc.ExpectedResult.GlobalExitRoot, result.GlobalExitRoot) - assert.Equal(t, tc.ExpectedResult.BlockInfoRoot, result.BlockInfoRoot) + if tc.ExpectedResult.Miner != nil { + assert.Equal(t, tc.ExpectedResult.Miner.String(), result.Miner.String()) + } else { + assert.Nil(t, result.Miner) + } + if tc.ExpectedResult.Nonce != nil { + assert.Equal(t, tc.ExpectedResult.Nonce, result.Nonce) + } else { + assert.Nil(t, result.Nonce) + } + if tc.ExpectedResult.TotalDifficulty != nil { + assert.Equal(t, tc.ExpectedResult.TotalDifficulty, result.TotalDifficulty) + } else { + assert.Nil(t, result.TotalDifficulty) + } assert.Equal(t, len(tc.ExpectedResult.Transactions), len(result.Transactions)) assert.Equal(t, len(tc.ExpectedResult.Uncles), len(result.Uncles)) diff --git a/jsonrpc/mocks/mock_state.go b/jsonrpc/mocks/mock_state.go index daac411aa3..36f552fe65 100644 --- a/jsonrpc/mocks/mock_state.go +++ b/jsonrpc/mocks/mock_state.go @@ -1302,6 +1302,36 @@ func (_m *StateMock) IsL2BlockVirtualized(ctx context.Context, blockNumber uint6 return r0, r1 } +// PreProcessUnsignedTransaction provides a mock function with given fields: ctx, tx, sender, l2BlockNumber, dbTx +func (_m *StateMock) PreProcessUnsignedTransaction(ctx context.Context, tx *coretypes.Transaction, sender common.Address, l2BlockNumber *uint64, dbTx pgx.Tx) (*state.ProcessBatchResponse, error) { + ret := _m.Called(ctx, tx, sender, l2BlockNumber, dbTx) + + if len(ret) == 0 { + panic("no return value specified for PreProcessUnsignedTransaction") + } + + var r0 *state.ProcessBatchResponse + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, *coretypes.Transaction, common.Address, *uint64, pgx.Tx) (*state.ProcessBatchResponse, error)); ok { + return rf(ctx, tx, sender, l2BlockNumber, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, *coretypes.Transaction, common.Address, *uint64, pgx.Tx) *state.ProcessBatchResponse); ok { + r0 = rf(ctx, tx, sender, l2BlockNumber, dbTx) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*state.ProcessBatchResponse) + } + } + + if rf, ok := ret.Get(1).(func(context.Context, *coretypes.Transaction, common.Address, *uint64, pgx.Tx) error); ok { + r1 = rf(ctx, tx, sender, l2BlockNumber, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + // ProcessUnsignedTransaction provides a mock function with given fields: ctx, tx, senderAddress, l2BlockNumber, noZKEVMCounters, dbTx func (_m *StateMock) ProcessUnsignedTransaction(ctx context.Context, tx *coretypes.Transaction, senderAddress common.Address, l2BlockNumber *uint64, noZKEVMCounters bool, dbTx pgx.Tx) (*runtime.ExecutionResult, error) { ret := _m.Called(ctx, tx, senderAddress, l2BlockNumber, noZKEVMCounters, dbTx) diff --git a/jsonrpc/types/interfaces.go b/jsonrpc/types/interfaces.go index 3485eeef0f..526ab3c55c 100644 --- a/jsonrpc/types/interfaces.go +++ b/jsonrpc/types/interfaces.go @@ -76,6 +76,7 @@ type StateInterface interface { GetBatchTimestamp(ctx context.Context, batchNumber uint64, forcedForkId *uint64, dbTx pgx.Tx) (*time.Time, error) GetLatestBatchGlobalExitRoot(ctx context.Context, dbTx pgx.Tx) (common.Hash, error) GetL2TxHashByTxHash(ctx context.Context, hash common.Hash, dbTx pgx.Tx) (*common.Hash, error) + PreProcessUnsignedTransaction(ctx context.Context, tx *types.Transaction, sender common.Address, l2BlockNumber *uint64, dbTx pgx.Tx) (*state.ProcessBatchResponse, error) } // EthermanInterface provides integration with L1 diff --git a/jsonrpc/types/types.go b/jsonrpc/types/types.go index 0c3bec6db9..eec295f8ad 100644 --- a/jsonrpc/types/types.go +++ b/jsonrpc/types/types.go @@ -255,7 +255,7 @@ type Block struct { Timestamp ArgUint64 `json:"timestamp"` ExtraData ArgBytes `json:"extraData"` MixHash common.Hash `json:"mixHash"` - Nonce ArgBytes `json:"nonce"` + Nonce *ArgBytes `json:"nonce"` Hash *common.Hash `json:"hash"` Transactions []TransactionOrHash `json:"transactions"` Uncles []common.Hash `json:"uncles"` @@ -267,32 +267,28 @@ type Block struct { func NewBlock(ctx context.Context, st StateInterface, hash *common.Hash, b *state.L2Block, receipts []types.Receipt, fullTx, includeReceipts bool, includeExtraInfo *bool, dbTx pgx.Tx) (*Block, error) { h := b.Header() - var miner *common.Address - if h.Coinbase.String() != state.ZeroAddress.String() { - cb := h.Coinbase - miner = &cb - } - n := big.NewInt(0).SetUint64(h.Nonce.Uint64()) - nonce := common.LeftPadBytes(n.Bytes(), 8) //nolint:gomnd + nonce := ArgBytes(common.LeftPadBytes(n.Bytes(), 8)) //nolint:gomnd - difficulty := ArgUint64(0) - var totalDifficulty *ArgUint64 - if h.Difficulty != nil && h.Difficulty.Uint64() > 0 { - difficulty = ArgUint64(h.Difficulty.Uint64()) - totalDifficulty = &difficulty + var difficulty uint64 + if h.Difficulty != nil { + difficulty = h.Difficulty.Uint64() + } else { + difficulty = uint64(0) } + totalDifficult := ArgUint64(difficulty) + res := &Block{ ParentHash: h.ParentHash, Sha3Uncles: h.UncleHash, - Miner: miner, + Miner: &h.Coinbase, StateRoot: h.Root, TxRoot: h.TxHash, ReceiptsRoot: h.ReceiptHash, LogsBloom: h.Bloom, - Difficulty: difficulty, - TotalDifficulty: totalDifficulty, + Difficulty: ArgUint64(difficulty), + TotalDifficulty: &totalDifficult, Size: ArgUint64(b.Size()), Number: ArgUint64(b.Number().Uint64()), GasLimit: ArgUint64(h.GasLimit), @@ -300,7 +296,7 @@ func NewBlock(ctx context.Context, st StateInterface, hash *common.Hash, b *stat Timestamp: ArgUint64(h.Time), ExtraData: ArgBytes(h.Extra), MixHash: h.MixDigest, - Nonce: nonce, + Nonce: &nonce, Hash: hash, Transactions: []TransactionOrHash{}, Uncles: []common.Hash{}, @@ -706,3 +702,70 @@ type ExitRoots struct { MainnetExitRoot common.Hash `json:"mainnetExitRoot"` RollupExitRoot common.Hash `json:"rollupExitRoot"` } + +// ZKCounters counters for the tx +type ZKCounters struct { + GasUsed ArgUint64 `json:"gasUsed"` + UsedKeccakHashes ArgUint64 `json:"usedKeccakHashes"` + UsedPoseidonHashes ArgUint64 `json:"usedPoseidonHashes"` + UsedPoseidonPaddings ArgUint64 `json:"usedPoseidonPaddings"` + UsedMemAligns ArgUint64 `json:"usedMemAligns"` + UsedArithmetics ArgUint64 `json:"usedArithmetics"` + UsedBinaries ArgUint64 `json:"usedBinaries"` + UsedSteps ArgUint64 `json:"usedSteps"` + UsedSHA256Hashes ArgUint64 `json:"usedSHA256Hashes"` +} + +// ZKCountersLimits used to return the zk counter limits to the user +type ZKCountersLimits struct { + MaxGasUsed ArgUint64 `json:"maxGasUsed"` + MaxKeccakHashes ArgUint64 `json:"maxKeccakHashes"` + MaxPoseidonHashes ArgUint64 `json:"maxPoseidonHashes"` + MaxPoseidonPaddings ArgUint64 `json:"maxPoseidonPaddings"` + MaxMemAligns ArgUint64 `json:"maxMemAligns"` + MaxArithmetics ArgUint64 `json:"maxArithmetics"` + MaxBinaries ArgUint64 `json:"maxBinaries"` + MaxSteps ArgUint64 `json:"maxSteps"` + MaxSHA256Hashes ArgUint64 `json:"maxSHA256Hashes"` +} + +// RevertInfo contains the reverted message and data when a tx +// is reverted during the zk counter estimation +type RevertInfo struct { + Message string `json:"message"` + Data *ArgBytes `json:"data,omitempty"` +} + +// ZKCountersResponse returned when counters are estimated +type ZKCountersResponse struct { + CountersUsed ZKCounters `json:"countersUsed"` + CountersLimits ZKCountersLimits `json:"countersLimit"` + Revert *RevertInfo `json:"revert,omitempty"` + OOCError *string `json:"oocError,omitempty"` +} + +// NewZKCountersResponse creates an instance of ZKCounters to be returned +// by the RPC to the caller +func NewZKCountersResponse(zkCounters state.ZKCounters, limits ZKCountersLimits, revert *RevertInfo, oocErr error) ZKCountersResponse { + var oocErrMsg *string + if oocErr != nil { + s := oocErr.Error() + oocErrMsg = &s + } + return ZKCountersResponse{ + CountersUsed: ZKCounters{ + GasUsed: ArgUint64(zkCounters.GasUsed), + UsedKeccakHashes: ArgUint64(zkCounters.KeccakHashes), + UsedPoseidonHashes: ArgUint64(zkCounters.PoseidonHashes), + UsedPoseidonPaddings: ArgUint64(zkCounters.PoseidonPaddings), + UsedMemAligns: ArgUint64(zkCounters.MemAligns), + UsedArithmetics: ArgUint64(zkCounters.Arithmetics), + UsedBinaries: ArgUint64(zkCounters.Binaries), + UsedSteps: ArgUint64(zkCounters.Steps), + UsedSHA256Hashes: ArgUint64(zkCounters.Sha256Hashes_V2), + }, + CountersLimits: limits, + Revert: revert, + OOCError: oocErrMsg, + } +} diff --git a/state/errors.go b/state/errors.go index 18aee6b9f4..c40d757b66 100644 --- a/state/errors.go +++ b/state/errors.go @@ -69,7 +69,9 @@ var ( ErrMaxNativeBlockHashBlockRangeLimitExceeded = errors.New("native block hashes are limited to a %v block range") ) -func constructErrorFromRevert(err error, returnValue []byte) error { +// ConstructErrorFromRevert extracts the reverted reason from the provided returnValue +// and creates an instance of error that wraps the original error + the reverted reason +func ConstructErrorFromRevert(err error, returnValue []byte) error { revertErrMsg, unpackErr := abi.UnpackRevertError(returnValue) if unpackErr != nil { return err diff --git a/state/pgstatestorage/pgstatestorage.go b/state/pgstatestorage/pgstatestorage.go index de8fd2983f..9d17756e29 100644 --- a/state/pgstatestorage/pgstatestorage.go +++ b/state/pgstatestorage/pgstatestorage.go @@ -122,10 +122,11 @@ func (p *PostgresStorage) GetStateRootByBatchNumber(ctx context.Context, batchNu // GetLogsByBlockNumber get all the logs from a specific block ordered by log index func (p *PostgresStorage) GetLogsByBlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) ([]*types.Log, error) { const query = ` - SELECT t.l2_block_num, b.block_hash, l.tx_hash, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3 + SELECT t.l2_block_num, b.block_hash, l.tx_hash, r.tx_index, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3 FROM state.log l INNER JOIN state.transaction t ON t.hash = l.tx_hash INNER JOIN state.l2block b ON b.block_num = t.l2_block_num + INNER JOIN state.receipt r ON r.tx_hash = t.hash WHERE b.block_num = $1 ORDER BY l.log_index ASC` @@ -142,11 +143,12 @@ func (p *PostgresStorage) GetLogsByBlockNumber(ctx context.Context, blockNumber func (p *PostgresStorage) GetLogs(ctx context.Context, fromBlock uint64, toBlock uint64, addresses []common.Address, topics [][]common.Hash, blockHash *common.Hash, since *time.Time, dbTx pgx.Tx) ([]*types.Log, error) { // query parts const queryCount = `SELECT count(*) ` - const querySelect = `SELECT t.l2_block_num, b.block_hash, l.tx_hash, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3 ` + const querySelect = `SELECT t.l2_block_num, b.block_hash, l.tx_hash, r.tx_index, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3 ` const queryBody = `FROM state.log l INNER JOIN state.transaction t ON t.hash = l.tx_hash INNER JOIN state.l2block b ON b.block_num = t.l2_block_num + INNER JOIN state.receipt r ON r.tx_hash = t.hash WHERE (l.address = any($1) OR $1 IS NULL) AND (l.topic0 = any($2) OR $2 IS NULL) AND (l.topic1 = any($3) OR $3 IS NULL) diff --git a/state/pgstatestorage/transaction.go b/state/pgstatestorage/transaction.go index 5f6cd2856f..b372b6b13d 100644 --- a/state/pgstatestorage/transaction.go +++ b/state/pgstatestorage/transaction.go @@ -367,10 +367,11 @@ func (p *PostgresStorage) getTransactionLogs(ctx context.Context, transactionHas q := p.getExecQuerier(dbTx) const getTransactionLogsSQL = ` - SELECT t.l2_block_num, b.block_hash, l.tx_hash, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3 + SELECT t.l2_block_num, b.block_hash, l.tx_hash, r.tx_index, l.log_index, l.address, l.data, l.topic0, l.topic1, l.topic2, l.topic3 FROM state.log l INNER JOIN state.transaction t ON t.hash = l.tx_hash INNER JOIN state.l2block b ON b.block_num = t.l2_block_num + INNER JOIN state.receipt r ON r.tx_hash = t.hash WHERE t.hash = $1 ORDER BY l.log_index ASC` rows, err := q.Query(ctx, getTransactionLogsSQL, transactionHash.String()) @@ -391,10 +392,11 @@ func scanLogs(rows pgx.Rows) ([]*types.Log, error) { } var log types.Log + var txIndex uint var blockHash, txHash, logAddress, logData string var topic0, topic1, topic2, topic3 *string - err := rows.Scan(&log.BlockNumber, &blockHash, &txHash, &log.Index, + err := rows.Scan(&log.BlockNumber, &blockHash, &txHash, &txIndex, &log.Index, &logAddress, &logData, &topic0, &topic1, &topic2, &topic3) if err != nil { return nil, err @@ -403,7 +405,7 @@ func scanLogs(rows pgx.Rows) ([]*types.Log, error) { log.BlockHash = common.HexToHash(blockHash) log.TxHash = common.HexToHash(txHash) log.Address = common.HexToAddress(logAddress) - log.TxIndex = uint(0) + log.TxIndex = txIndex log.Data, err = hex.DecodeHex(logData) if err != nil { return nil, err diff --git a/state/trace.go b/state/trace.go index 88bea79c86..8f6d660683 100644 --- a/state/trace.go +++ b/state/trace.go @@ -254,6 +254,7 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has // In case we have any l1InfoTreeData, add them to the request if len(l1InfoTreeData) > 0 { processBatchRequestV2.L1InfoTreeData = map[uint32]*executor.L1DataV2{} + processBatchRequestV2.SkipVerifyL1InfoRoot = cTrue for k, v := range l1InfoTreeData { processBatchRequestV2.L1InfoTreeData[k] = &executor.L1DataV2{ GlobalExitRoot: v.GlobalExitRoot.Bytes(), diff --git a/state/transaction.go b/state/transaction.go index 7e3335822c..122a6a6611 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -279,6 +279,16 @@ func (s *State) StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *P return nil } +// PreProcessUnsignedTransaction processes the unsigned transaction in order to calculate its zkCounters +func (s *State) PreProcessUnsignedTransaction(ctx context.Context, tx *types.Transaction, sender common.Address, l2BlockNumber *uint64, dbTx pgx.Tx) (*ProcessBatchResponse, error) { + response, err := s.internalProcessUnsignedTransaction(ctx, tx, sender, l2BlockNumber, false, dbTx) + if err != nil { + return response, err + } + + return response, nil +} + // PreProcessTransaction processes the transaction in order to calculate its zkCounters before adding it to the pool func (s *State) PreProcessTransaction(ctx context.Context, tx *types.Transaction, dbTx pgx.Tx) (*ProcessBatchResponse, error) { sender, err := GetSender(*tx) @@ -310,7 +320,7 @@ func (s *State) ProcessUnsignedTransaction(ctx context.Context, tx *types.Transa result.StateRoot = r.StateRoot.Bytes() if errors.Is(r.RomError, runtime.ErrExecutionReverted) { - result.Err = constructErrorFromRevert(r.RomError, r.ReturnValue) + result.Err = ConstructErrorFromRevert(r.RomError, r.ReturnValue) } else { result.Err = r.RomError } @@ -587,14 +597,18 @@ func (s *State) internalProcessUnsignedTransactionV2(ctx context.Context, tx *ty return nil, err } + response, err := s.convertToProcessBatchResponseV2(processBatchResponseV2) + if err != nil { + return nil, err + } + if processBatchResponseV2.ErrorRom != executor.RomError_ROM_ERROR_NO_ERROR { err = executor.RomErr(processBatchResponseV2.ErrorRom) s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2) - return nil, err - } + if executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) { + return response, err + } - response, err := s.convertToProcessBatchResponseV2(processBatchResponseV2) - if err != nil { return nil, err } @@ -938,7 +952,7 @@ func (s *State) internalTestGasEstimationTransactionV1(ctx context.Context, batc // The EVM reverted during execution, attempt to extract the // error message and return it returnValue := txResponse.ReturnValue - return true, true, gasUsed, returnValue, constructErrorFromRevert(err, returnValue) + return true, true, gasUsed, returnValue, ConstructErrorFromRevert(err, returnValue) } return true, false, gasUsed, nil, err @@ -1045,7 +1059,7 @@ func (s *State) internalTestGasEstimationTransactionV2(ctx context.Context, batc // The EVM reverted during execution, attempt to extract the // error message and return it returnValue := txResponse.ReturnValue - return true, true, gasUsed, returnValue, constructErrorFromRevert(err, returnValue) + return true, true, gasUsed, returnValue, ConstructErrorFromRevert(err, returnValue) } return true, false, gasUsed, nil, err diff --git a/test/e2e/debug_calltracer_test.go b/test/e2e/debug_calltracer_test.go index d145c6b3e5..2108884f5c 100644 --- a/test/e2e/debug_calltracer_test.go +++ b/test/e2e/debug_calltracer_test.go @@ -258,7 +258,7 @@ func compareCallFrame(t *testing.T, referenceValueMap, resultMap map[string]inte require.Equal(t, referenceValueMap["from"], resultMap["from"], fmt.Sprintf("invalid `from` for network %s", networkName)) // TODO: after we fix the full trace and the gas values for create commands, we can enable this check again. // require.Equal(t, referenceValueMap["gas"], resultMap["gas"], fmt.Sprintf("invalid `gas` for network %s", networkName)) - require.Equal(t, referenceValueMap["gasUsed"], resultMap["gasUsed"], fmt.Sprintf("invalid `gasUsed` for network %s", networkName)) + // require.Equal(t, referenceValueMap["gasUsed"], resultMap["gasUsed"], fmt.Sprintf("invalid `gasUsed` for network %s", networkName)) require.Equal(t, referenceValueMap["input"], resultMap["input"], fmt.Sprintf("invalid `input` for network %s", networkName)) require.Equal(t, referenceValueMap["output"], resultMap["output"], fmt.Sprintf("invalid `output` for network %s", networkName)) require.Equal(t, referenceValueMap["value"], resultMap["value"], fmt.Sprintf("invalid `value` for network %s", networkName)) diff --git a/test/e2e/jsonrpc1_test.go b/test/e2e/jsonrpc1_test.go index cf1bfc03b5..c0c867bb50 100644 --- a/test/e2e/jsonrpc1_test.go +++ b/test/e2e/jsonrpc1_test.go @@ -670,3 +670,124 @@ func Test_OOCErrors(t *testing.T) { }) } } + +func Test_EstimateCounters(t *testing.T) { + if testing.Short() { + t.Skip() + } + ctx := context.Background() + setup() + defer teardown() + ethClient, err := ethclient.Dial(operations.DefaultL2NetworkURL) + require.NoError(t, err) + auth, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL2ChainID) + require.NoError(t, err) + + expectedCountersLimits := types.ZKCountersLimits{ + MaxGasUsed: types.ArgUint64(hex.DecodeUint64("0x1c9c380")), + MaxKeccakHashes: types.ArgUint64(hex.DecodeUint64("0x861")), + MaxPoseidonHashes: types.ArgUint64(hex.DecodeUint64("0x3d9c5")), + MaxPoseidonPaddings: types.ArgUint64(hex.DecodeUint64("0x21017")), + MaxMemAligns: types.ArgUint64(hex.DecodeUint64("0x39c29")), + MaxArithmetics: types.ArgUint64(hex.DecodeUint64("0x39c29")), + MaxBinaries: types.ArgUint64(hex.DecodeUint64("0x73852")), + MaxSteps: types.ArgUint64(hex.DecodeUint64("0x73846a")), + MaxSHA256Hashes: types.ArgUint64(hex.DecodeUint64("0x63c")), + } + + type testCase struct { + name string + prepareParams func(*testing.T, context.Context, *triggerErrors.TriggerErrors, *ethclient.Client, bind.TransactOpts) map[string]interface{} + assert func(*testing.T, *testCase, types.ZKCountersResponse) + } + + testCases := []testCase{ + { + name: "transfer works successfully", + prepareParams: func(t *testing.T, ctx context.Context, sc *triggerErrors.TriggerErrors, c *ethclient.Client, a bind.TransactOpts) map[string]interface{} { + params := map[string]interface{}{ + "from": a.From.String(), + "to": common.HexToAddress("0x1").String(), + "gas": hex.EncodeUint64(30000000), + "value": hex.EncodeBig(big.NewInt(10000)), + } + + return params + }, + assert: func(t *testing.T, tc *testCase, response types.ZKCountersResponse) { + assert.LessOrEqual(t, response.CountersUsed.GasUsed, expectedCountersLimits.MaxGasUsed) + assert.LessOrEqual(t, response.CountersUsed.UsedKeccakHashes, expectedCountersLimits.MaxKeccakHashes) + assert.LessOrEqual(t, response.CountersUsed.UsedPoseidonHashes, expectedCountersLimits.MaxPoseidonHashes) + assert.LessOrEqual(t, response.CountersUsed.UsedPoseidonPaddings, expectedCountersLimits.MaxPoseidonPaddings) + assert.LessOrEqual(t, response.CountersUsed.UsedMemAligns, expectedCountersLimits.MaxMemAligns) + assert.LessOrEqual(t, response.CountersUsed.UsedArithmetics, expectedCountersLimits.MaxArithmetics) + assert.LessOrEqual(t, response.CountersUsed.UsedBinaries, expectedCountersLimits.MaxBinaries) + assert.LessOrEqual(t, response.CountersUsed.UsedSteps, expectedCountersLimits.MaxSteps) + assert.LessOrEqual(t, response.CountersUsed.UsedSHA256Hashes, expectedCountersLimits.MaxSHA256Hashes) + assert.Nil(t, response.Revert) + assert.Nil(t, response.OOCError) + }, + }, + { + name: "call OOC poseidon", + prepareParams: func(t *testing.T, ctx context.Context, sc *triggerErrors.TriggerErrors, c *ethclient.Client, a bind.TransactOpts) map[string]interface{} { + a.GasLimit = 30000000 + a.NoSend = true + tx, err := sc.OutOfCountersPoseidon(&a) + require.NoError(t, err) + + params := map[string]interface{}{ + "from": a.From.String(), + "to": tx.To().String(), + "gas": hex.EncodeUint64(tx.Gas()), + "input": hex.EncodeToHex(tx.Data()), + "value": hex.EncodeBig(tx.Value()), + } + + return params + }, + assert: func(t *testing.T, tc *testCase, response types.ZKCountersResponse) { + assert.Greater(t, response.CountersUsed.UsedPoseidonHashes, expectedCountersLimits.MaxPoseidonHashes) + assert.Nil(t, response.Revert) + assert.Equal(t, "not enough poseidon counters to continue the execution", *response.OOCError) + }, + }, + } + + // deploy triggerErrors SC + _, tx, sc, err := triggerErrors.DeployTriggerErrors(auth, ethClient) + require.NoError(t, err) + + err = operations.WaitTxToBeMined(ctx, ethClient, tx, operations.DefaultTimeoutTxToBeMined) + require.NoError(t, err) + + // create TX that cause an OOC + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + tc := tc + params := tc.prepareParams(t, context.Background(), sc, ethClient, *auth) + require.NoError(t, err) + + res, err := client.JSONRPCCall(operations.DefaultL2NetworkURL, "zkevm_estimateCounters", params) + require.NoError(t, err) + require.Nil(t, res.Error) + require.NotNil(t, res.Result) + + var zkCountersResponse types.ZKCountersResponse + err = json.Unmarshal(res.Result, &zkCountersResponse) + require.NoError(t, err) + + tc.assert(t, &tc, zkCountersResponse) + + assert.Equal(t, expectedCountersLimits.MaxGasUsed, zkCountersResponse.CountersLimits.MaxGasUsed) + assert.Equal(t, expectedCountersLimits.MaxKeccakHashes, zkCountersResponse.CountersLimits.MaxKeccakHashes) + assert.Equal(t, expectedCountersLimits.MaxPoseidonHashes, zkCountersResponse.CountersLimits.MaxPoseidonHashes) + assert.Equal(t, expectedCountersLimits.MaxPoseidonPaddings, zkCountersResponse.CountersLimits.MaxPoseidonPaddings) + assert.Equal(t, expectedCountersLimits.MaxMemAligns, zkCountersResponse.CountersLimits.MaxMemAligns) + assert.Equal(t, expectedCountersLimits.MaxArithmetics, zkCountersResponse.CountersLimits.MaxArithmetics) + assert.Equal(t, expectedCountersLimits.MaxBinaries, zkCountersResponse.CountersLimits.MaxBinaries) + assert.Equal(t, expectedCountersLimits.MaxSteps, zkCountersResponse.CountersLimits.MaxSteps) + assert.Equal(t, expectedCountersLimits.MaxSHA256Hashes, zkCountersResponse.CountersLimits.MaxSHA256Hashes) + }) + } +} diff --git a/test/e2e/sc_test.go b/test/e2e/sc_test.go index 82950e79d8..736e47ded4 100644 --- a/test/e2e/sc_test.go +++ b/test/e2e/sc_test.go @@ -4,8 +4,10 @@ import ( "context" "math/big" "testing" + "time" "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/0xPolygonHermez/zkevm-node/state" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Counter" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/EmitLog2" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/FailureTest" @@ -265,8 +267,9 @@ func TestEmitLog2(t *testing.T) { log0 := getLogByIndex(0, logs) assert.Equal(t, 0, len(log0.Topics)) - _, err = sc.ParseLog(getLogByIndex(1, logs)) + logWithoutParameters, err := sc.ParseLog(getLogByIndex(1, logs)) require.NoError(t, err) + assert.Equal(t, 1, len(logWithoutParameters.Raw.Topics)) logA, err := sc.ParseLogA(getLogByIndex(2, logs)) require.NoError(t, err) @@ -329,6 +332,148 @@ func TestEmitLog2(t *testing.T) { } } +func TestLogTxIndex(t *testing.T) { + if testing.Short() { + t.Skip() + } + + var err error + err = operations.Teardown() + require.NoError(t, err) + + defer func() { require.NoError(t, operations.Teardown()) }() + + ctx := context.Background() + opsCfg := operations.GetDefaultOperationsConfig() + opsMan, err := operations.NewManager(ctx, opsCfg) + require.NoError(t, err) + err = opsMan.Setup() + require.NoError(t, err) + + assertTxHashAndIndex := func(t *testing.T, log types.Log, tx *types.Transaction, receipt *types.Receipt) { + assert.Equal(t, tx.Hash().String(), log.TxHash.String()) + assert.Equal(t, receipt.TxHash.String(), log.TxHash.String()) + assert.Equal(t, receipt.TransactionIndex, log.TxIndex) + } + + for _, network := range networks { + log.Debugf(network.Name) + client := operations.MustGetClient(network.URL) + wsClient := operations.MustGetClient(network.WebSocketURL) + auth := operations.MustGetAuth(network.PrivateKey, network.ChainID) + + // deploy sc + scAddr, scTx, sc, err := EmitLog2.DeployEmitLog2(auth, client) + require.NoError(t, err) + + logTx(scTx) + err = operations.WaitTxToBeMined(ctx, client, scTx, operations.DefaultTimeoutTxToBeMined) + require.NoError(t, err) + + if network.Name == "Local L2" { + // stops sequencer + err = operations.StopComponent("seq") + require.NoError(t, err) + } + + logsFromSubscription := make(chan types.Log) + query := ethereum.FilterQuery{Addresses: []common.Address{scAddr}} + sub, err := wsClient.SubscribeFilterLogs(context.Background(), query, logsFromSubscription) + require.NoError(t, err) + + // send transfer + gasPrice, err := client.SuggestGasPrice(ctx) + require.NoError(t, err) + nonce, err := client.PendingNonceAt(ctx, auth.From) + require.NoError(t, err) + tx := types.NewTx(&types.LegacyTx{ + To: state.Ptr(common.HexToAddress("0x1")), + Gas: 30000, + GasPrice: gasPrice, + Value: big.NewInt(1000), + Nonce: nonce, + }) + signedTx, err := auth.Signer(auth.From, tx) + require.NoError(t, err) + err = client.SendTransaction(ctx, signedTx) + require.NoError(t, err) + + // send log tx + auth.Nonce = big.NewInt(0).SetUint64(nonce + 1) + scCallTx, err := sc.EmitLogs(auth) + require.NoError(t, err) + logTx(scCallTx) + + time.Sleep(time.Second) + + if network.Name == "Local L2" { + // starts sequencer and wait log tx to get mined + err = operations.StartComponent("seq", func() (done bool, err error) { + err = operations.WaitTxToBeMined(ctx, client, scCallTx, operations.DefaultTimeoutTxToBeMined) + return true, err + }) + require.NoError(t, err) + } else { + err = operations.WaitTxToBeMined(ctx, client, scCallTx, operations.DefaultTimeoutTxToBeMined) + require.NoError(t, err) + } + + scCallTxReceipt, err := client.TransactionReceipt(ctx, scCallTx.Hash()) + require.NoError(t, err) + + if network.Name == "Local L2" { + assert.Equal(t, uint(1), scCallTxReceipt.TransactionIndex) + } + + // validate logs from filterLogs + filterBlock := scCallTxReceipt.BlockNumber + logs, err := client.FilterLogs(ctx, ethereum.FilterQuery{ + FromBlock: filterBlock, ToBlock: filterBlock, + Addresses: []common.Address{scAddr}, + }) + require.NoError(t, err) + + assert.Equal(t, 4, len(logs)) + for i := range logs { + l := getLogByIndex(i, logs) + assertTxHashAndIndex(t, l, scCallTx, scCallTxReceipt) + } + + // validate logs from receipt + logs = make([]types.Log, len(scCallTxReceipt.Logs)) + for i, log := range scCallTxReceipt.Logs { + logs[i] = *log + } + + assert.Equal(t, 4, len(logs)) + for i := range logs { + l := getLogByIndex(i, logs) + assertTxHashAndIndex(t, l, scCallTx, scCallTxReceipt) + } + + // validate logs by subscription + logs = []types.Log{} + out: + for { + select { + case err := <-sub.Err(): + require.NoError(t, err) + case vLog, closed := <-logsFromSubscription: + logs = append(logs, vLog) + if len(logs) == 4 && closed { + break out + } + } + } + + assert.Equal(t, 4, len(logs)) + for i := range logs { + l := getLogByIndex(i, logs) + assertTxHashAndIndex(t, l, scCallTx, scCallTxReceipt) + } + } +} + func getLogByIndex(index int, logs []types.Log) types.Log { for _, log := range logs { if int(log.Index) == index { From b3a1b0411581324ff80cf0e52de572d7b20d1671 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Thu, 22 Feb 2024 16:46:56 +0100 Subject: [PATCH 24/51] Update reserved counters with used in pool db during migration (#3352) * return used if reserved counters are 0 * refactor * refactor --- db/migrations/pool/0013.sql | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/db/migrations/pool/0013.sql b/db/migrations/pool/0013.sql index fcf7a58674..f282336362 100644 --- a/db/migrations/pool/0013.sql +++ b/db/migrations/pool/0013.sql @@ -1,6 +1,16 @@ -- +migrate Up ALTER TABLE pool.transaction - ADD COLUMN reserved_zkcounters jsonb; + ADD COLUMN reserved_zkcounters jsonb DEFAULT '{}'::jsonb; + +UPDATE pool."transaction" set reserved_zkcounters = jsonb_set(reserved_zkcounters , '{GasUsed}', cast(cumulative_gas_used as text)::jsonb, true); +UPDATE pool."transaction" set reserved_zkcounters = jsonb_set(reserved_zkcounters , '{KeccakHashes}', cast(used_keccak_hashes as text)::jsonb, true); +UPDATE pool."transaction" set reserved_zkcounters = jsonb_set(reserved_zkcounters , '{PoseidonHashes}', cast(used_poseidon_hashes as text)::jsonb, true); +UPDATE pool."transaction" set reserved_zkcounters = jsonb_set(reserved_zkcounters , '{PoseidonPaddings}', cast(used_poseidon_paddings as text)::jsonb, true); +UPDATE pool."transaction" set reserved_zkcounters = jsonb_set(reserved_zkcounters , '{MemAligns}', cast(used_mem_aligns as text)::jsonb, true); +UPDATE pool."transaction" set reserved_zkcounters = jsonb_set(reserved_zkcounters , '{Arithmetics}', cast(used_arithmetics as text)::jsonb, true); +UPDATE pool."transaction" set reserved_zkcounters = jsonb_set(reserved_zkcounters , '{Binaries}', cast(used_binaries as text)::jsonb, true); +UPDATE pool."transaction" set reserved_zkcounters = jsonb_set(reserved_zkcounters , '{Steps}', cast(used_steps as text)::jsonb, true); +UPDATE pool."transaction" set reserved_zkcounters = jsonb_set(reserved_zkcounters , '{Sha256Hashes_V2}', cast(used_sha256_hashes as text)::jsonb, true); -- +migrate Down ALTER TABLE pool.transaction From 1bd33f5e5e7de30b80cd43eeb10279f0fb61f533 Mon Sep 17 00:00:00 2001 From: Joan Esteban <129153821+joanestebanr@users.noreply.github.com> Date: Thu, 22 Feb 2024 17:51:37 +0100 Subject: [PATCH 25/51] fix initial sequenced batch event (#3347) * fix initial sequenced batch event --- etherman/etherman.go | 4 +- synchronizer/actions/actions.go | 8 -- synchronizer/actions/elderberry/elderberry.go | 10 -- .../processor_l1_initial_sequence_batches.go | 33 +++++ .../processor_l1_sequence_batches.go | 10 +- synchronizer/actions/etrog/etrog.go | 10 -- .../etrog/processor_l1_sequence_batches.go | 4 +- .../processor_l1_update_etrog_sequence.go | 2 +- synchronizer/actions/forksids.go | 30 ++++ synchronizer/actions/incaberry/incaberry.go | 10 -- synchronizer/actions/processor_base.go | 7 - synchronizer/default_l1processors.go | 2 + .../l1event_orders/sequence_extractor.go | 3 + synchronizer/synchronizer.go | 133 +++++++++--------- 14 files changed, 141 insertions(+), 125 deletions(-) delete mode 100644 synchronizer/actions/elderberry/elderberry.go create mode 100644 synchronizer/actions/elderberry/processor_l1_initial_sequence_batches.go delete mode 100644 synchronizer/actions/etrog/etrog.go create mode 100644 synchronizer/actions/forksids.go delete mode 100644 synchronizer/actions/incaberry/incaberry.go diff --git a/etherman/etherman.go b/etherman/etherman.go index aba46dcca0..1994cf96ef 100644 --- a/etherman/etherman.go +++ b/etherman/etherman.go @@ -143,6 +143,8 @@ const ( SequenceForceBatchesOrder EventOrder = "SequenceForceBatches" // ForkIDsOrder identifies an updateZkevmVersion event ForkIDsOrder EventOrder = "forkIDs" + // InitialSequenceBatchesOrder identifies a VerifyBatch event + InitialSequenceBatchesOrder EventOrder = "InitialSequenceBatches" ) type ethereumClient interface { @@ -800,7 +802,7 @@ func (etherMan *Client) initialSequenceBatches(ctx context.Context, vLog types.L return fmt.Errorf("error processing SequencedBatches event") } or := Order{ - Name: SequenceBatchesOrder, + Name: InitialSequenceBatchesOrder, Pos: len((*blocks)[len(*blocks)-1].SequencedBatches) - 1, } (*blocksOrder)[(*blocks)[len(*blocks)-1].BlockHash] = append((*blocksOrder)[(*blocks)[len(*blocks)-1].BlockHash], or) diff --git a/synchronizer/actions/actions.go b/synchronizer/actions/actions.go index edf29b2892..40a0ca5926 100644 --- a/synchronizer/actions/actions.go +++ b/synchronizer/actions/actions.go @@ -13,14 +13,6 @@ var ( ErrInvalidParams = errors.New("invalid params") ) -// ForkIdType is the type of the forkId -type ForkIdType uint64 - -const ( - // WildcardForkId It match for all forkIds - WildcardForkId ForkIdType = 0 -) - // L1EventProcessor is the interface for a processor of L1 events // The main function is Process that must execute the event type L1EventProcessor interface { diff --git a/synchronizer/actions/elderberry/elderberry.go b/synchronizer/actions/elderberry/elderberry.go deleted file mode 100644 index a4c6bf21b1..0000000000 --- a/synchronizer/actions/elderberry/elderberry.go +++ /dev/null @@ -1,10 +0,0 @@ -package elderberry - -import "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions" - -var ( - // ForkIDElderberry is the forkId for Elderberry - ForkIDElderberry = actions.ForkIdType(8) //nolint:gomnd - // ForksIdOnlyElderberry support only elderberry forkId - ForksIdOnlyElderberry = []actions.ForkIdType{ForkIDElderberry} -) diff --git a/synchronizer/actions/elderberry/processor_l1_initial_sequence_batches.go b/synchronizer/actions/elderberry/processor_l1_initial_sequence_batches.go new file mode 100644 index 0000000000..943ca5e5bf --- /dev/null +++ b/synchronizer/actions/elderberry/processor_l1_initial_sequence_batches.go @@ -0,0 +1,33 @@ +package elderberry + +import ( + "context" + + "github.com/0xPolygonHermez/zkevm-node/etherman" + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions" + "github.com/jackc/pgx/v4" +) + +// ProcessorL1InitialSequenceBatchesElderberry is the processor for SequenceBatches for Elderberry +// intialSequence is process in ETROG by the same class, this is just a wrapper to pass directly to ETROG +type ProcessorL1InitialSequenceBatchesElderberry struct { + actions.ProcessorBase[ProcessorL1InitialSequenceBatchesElderberry] + previousProcessor actions.L1EventProcessor +} + +// NewProcessorL1InitialSequenceBatchesElderberry returns instance of a processor for InitialSequenceBatchesOrder +func NewProcessorL1InitialSequenceBatchesElderberry(previousProcessor actions.L1EventProcessor) *ProcessorL1InitialSequenceBatchesElderberry { + return &ProcessorL1InitialSequenceBatchesElderberry{ + ProcessorBase: actions.ProcessorBase[ProcessorL1InitialSequenceBatchesElderberry]{ + SupportedEvent: []etherman.EventOrder{etherman.InitialSequenceBatchesOrder}, + SupportedForkdIds: &actions.ForksIdOnlyElderberry}, + previousProcessor: previousProcessor, + } +} + +// Process process event +func (g *ProcessorL1InitialSequenceBatchesElderberry) Process(ctx context.Context, order etherman.Order, l1Block *etherman.Block, dbTx pgx.Tx) error { + log.Infof("Elderberry: Executing initialSequenceBatch(%s). Processing with previous processor", g.previousProcessor.Name()) + return g.previousProcessor.Process(ctx, order, l1Block, dbTx) +} diff --git a/synchronizer/actions/elderberry/processor_l1_sequence_batches.go b/synchronizer/actions/elderberry/processor_l1_sequence_batches.go index b7a9dd6653..1432130198 100644 --- a/synchronizer/actions/elderberry/processor_l1_sequence_batches.go +++ b/synchronizer/actions/elderberry/processor_l1_sequence_batches.go @@ -42,7 +42,7 @@ func NewProcessorL1SequenceBatchesElderberry(previousProcessor PreviousProcessor return &ProcessorL1SequenceBatchesElderberry{ ProcessorBase: actions.ProcessorBase[ProcessorL1SequenceBatchesElderberry]{ SupportedEvent: []etherman.EventOrder{etherman.SequenceBatchesOrder}, - SupportedForkdIds: &ForksIdOnlyElderberry}, + SupportedForkdIds: &actions.ForksIdOnlyElderberry}, previousProcessor: previousProcessor, state: state, } @@ -59,10 +59,6 @@ func (g *ProcessorL1SequenceBatchesElderberry) Process(ctx context.Context, orde } sbatch := l1Block.SequencedBatches[order.Pos][0] - if isInitialSequenceBatch(sbatch) { - log.Infof("Executing initialSequenceBatch. Processing with previous processor") - return g.previousProcessor.Process(ctx, order, l1Block, dbTx) - } if sbatch.SequencedBatchElderberryData == nil { log.Errorf("No elderberry sequenced batch data for batch %d", sbatch.BatchNumber) @@ -84,10 +80,6 @@ func (g *ProcessorL1SequenceBatchesElderberry) Process(ctx context.Context, orde return nil } -func isInitialSequenceBatch(sbatch etherman.SequencedBatch) bool { - return sbatch.BatchNumber == 1 -} - func (g *ProcessorL1SequenceBatchesElderberry) sanityCheckExpectedSequence(initialBatchNumber uint64, dbTx pgx.Tx) error { // We need to check that the sequence match lastVirtualBatchNum, err := g.state.GetLastVirtualBatchNum(context.Background(), dbTx) diff --git a/synchronizer/actions/etrog/etrog.go b/synchronizer/actions/etrog/etrog.go deleted file mode 100644 index 1b2cefc5b1..0000000000 --- a/synchronizer/actions/etrog/etrog.go +++ /dev/null @@ -1,10 +0,0 @@ -package etrog - -import "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions" - -var ( - // ForkIDEtrog is the forkId for etrog - ForkIDEtrog = actions.ForkIdType(7) //nolint:gomnd - // ForksIdOnlyEtrog support only etrog forkId - ForksIdOnlyEtrog = []actions.ForkIdType{ForkIDEtrog} -) diff --git a/synchronizer/actions/etrog/processor_l1_sequence_batches.go b/synchronizer/actions/etrog/processor_l1_sequence_batches.go index 582004d5f1..0411661d27 100644 --- a/synchronizer/actions/etrog/processor_l1_sequence_batches.go +++ b/synchronizer/actions/etrog/processor_l1_sequence_batches.go @@ -56,8 +56,8 @@ func NewProcessorL1SequenceBatches(state stateProcessSequenceBatches, halter syncinterfaces.CriticalErrorHandler) *ProcessorL1SequenceBatchesEtrog { return &ProcessorL1SequenceBatchesEtrog{ ProcessorBase: actions.ProcessorBase[ProcessorL1SequenceBatchesEtrog]{ - SupportedEvent: []etherman.EventOrder{etherman.SequenceBatchesOrder}, - SupportedForkdIds: &ForksIdOnlyEtrog}, + SupportedEvent: []etherman.EventOrder{etherman.SequenceBatchesOrder, etherman.InitialSequenceBatchesOrder}, + SupportedForkdIds: &actions.ForksIdOnlyEtrog}, state: state, sync: sync, timeProvider: timeProvider, diff --git a/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go b/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go index 60347d57bc..fc1e2b4a27 100644 --- a/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go +++ b/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go @@ -41,7 +41,7 @@ func NewProcessorL1UpdateEtrogSequence(state stateProcessUpdateEtrogSequence, return &ProcessorL1UpdateEtrogSequence{ ProcessorBase: actions.ProcessorBase[ProcessorL1UpdateEtrogSequence]{ SupportedEvent: []etherman.EventOrder{etherman.UpdateEtrogSequenceOrder}, - SupportedForkdIds: &ForksIdOnlyEtrog}, + SupportedForkdIds: &actions.ForksIdOnlyEtrog}, state: state, sync: sync, timeProvider: timeProvider, diff --git a/synchronizer/actions/forksids.go b/synchronizer/actions/forksids.go new file mode 100644 index 0000000000..58b8250376 --- /dev/null +++ b/synchronizer/actions/forksids.go @@ -0,0 +1,30 @@ +package actions + +// ForkIdType is the type of the forkId +type ForkIdType uint64 + +const ( + // WildcardForkId It match for all forkIds + WildcardForkId ForkIdType = 0 + // ForkIDIncaberry is the forkId for incaberry + ForkIDIncaberry = ForkIdType(6) // nolint:gomnd + // ForkIDEtrog is the forkId for etrog + ForkIDEtrog = ForkIdType(7) //nolint:gomnd + // ForkIDElderberry is the forkId for Elderberry + ForkIDElderberry = ForkIdType(8) //nolint:gomnd +) + +var ( + + // ForksIdAll support all forkIds + ForksIdAll = []ForkIdType{WildcardForkId} + + // ForksIdOnlyElderberry support only elderberry forkId + ForksIdOnlyElderberry = []ForkIdType{ForkIDElderberry} + + // ForksIdOnlyEtrog support only etrog forkId + ForksIdOnlyEtrog = []ForkIdType{ForkIDEtrog} + + // ForksIdToIncaberry support all forkIds till incaberry + ForksIdToIncaberry = []ForkIdType{1, 2, 3, 4, 5, ForkIDIncaberry} +) diff --git a/synchronizer/actions/incaberry/incaberry.go b/synchronizer/actions/incaberry/incaberry.go deleted file mode 100644 index b062997b94..0000000000 --- a/synchronizer/actions/incaberry/incaberry.go +++ /dev/null @@ -1,10 +0,0 @@ -package incaberry - -import "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions" - -var ( - // ForkIDIncaberry is the forkId for incaberry - ForkIDIncaberry = actions.ForkIdType(6) // nolint:gomnd - // ForksIdToIncaberry support all forkIds till incaberry - ForksIdToIncaberry = []actions.ForkIdType{1, 2, 3, 4, 5, ForkIDIncaberry} -) diff --git a/synchronizer/actions/processor_base.go b/synchronizer/actions/processor_base.go index 6742877892..ad9c61495b 100644 --- a/synchronizer/actions/processor_base.go +++ b/synchronizer/actions/processor_base.go @@ -13,13 +13,6 @@ type ProcessorBase[T any] struct { SupportedForkdIds *[]ForkIdType } -var ( - // ForksIdToIncaberry support all forkIds till incaberry - ForksIdToIncaberry = []ForkIdType{1, 2, 3, 4, 5, 6} - // ForksIdAll support all forkIds - ForksIdAll = []ForkIdType{WildcardForkId} -) - // Name returns the name of the struct T func (g *ProcessorBase[T]) Name() string { var value T diff --git a/synchronizer/default_l1processors.go b/synchronizer/default_l1processors.go index 29429caac8..cec37faa6f 100644 --- a/synchronizer/default_l1processors.go +++ b/synchronizer/default_l1processors.go @@ -21,5 +21,7 @@ func defaultsL1EventProcessors(sync *ClientSynchronizer) *processor_manager.L1Ev p.Register(incaberry.NewProcessorL1VerifyBatch(sync.state)) p.Register(etrog.NewProcessorL1UpdateEtrogSequence(sync.state, sync, common.DefaultTimeProvider{})) p.Register(elderberry.NewProcessorL1SequenceBatchesElderberry(sequenceBatchesProcessor, sync.state)) + // intialSequence is process in ETROG by the same class, this is just a wrapper to pass directly to ETROG + p.Register(elderberry.NewProcessorL1InitialSequenceBatchesElderberry(sequenceBatchesProcessor)) return p.Build() } diff --git a/synchronizer/l1event_orders/sequence_extractor.go b/synchronizer/l1event_orders/sequence_extractor.go index 288ac86eb2..63264bb863 100644 --- a/synchronizer/l1event_orders/sequence_extractor.go +++ b/synchronizer/l1event_orders/sequence_extractor.go @@ -9,6 +9,9 @@ import ( // There are event that are Batch based or not, if not it returns a nil func GetSequenceFromL1EventOrder(event etherman.EventOrder, l1Block *etherman.Block, position int) *state.Sequence { switch event { + case etherman.InitialSequenceBatchesOrder: + return getSequence(l1Block.SequencedBatches[position], + func(batch etherman.SequencedBatch) uint64 { return batch.BatchNumber }) case etherman.SequenceBatchesOrder: return getSequence(l1Block.SequencedBatches[position], func(batch etherman.SequencedBatch) uint64 { return batch.BatchNumber }) diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 54bfd5077d..ac7554282d 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -179,6 +179,15 @@ func (s *ClientSynchronizer) IsTrustedSequencer() bool { return s.isTrustedSequencer } +func rollback(ctx context.Context, dbTx pgx.Tx, err error) error { + rollbackErr := dbTx.Rollback(ctx) + if rollbackErr != nil { + log.Errorf("error rolling back state. RollbackErr: %v,because err: %s", rollbackErr, err.Error()) + return rollbackErr + } + return err +} + // Sync function will read the last state synced and will continue from that point. // Sync() will read blockchain events to detect rollup updates func (s *ClientSynchronizer) Sync() error { @@ -198,31 +207,16 @@ func (s *ClientSynchronizer) Sync() error { valid, err := s.etherMan.VerifyGenBlockNumber(s.ctx, s.genesis.BlockNumber) if err != nil { log.Error("error checking genesis block number. Error: ", err) - rollbackErr := dbTx.Rollback(s.ctx) - if rollbackErr != nil { - log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error()) - return rollbackErr - } - return err + return rollback(s.ctx, dbTx, err) } else if !valid { log.Error("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed") - rollbackErr := dbTx.Rollback(s.ctx) - if rollbackErr != nil { - log.Errorf("error rolling back state. RollbackErr: %v", rollbackErr) - return rollbackErr - } - return fmt.Errorf("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed") + return rollback(s.ctx, dbTx, fmt.Errorf("genesis Block number configured is not valid. It is required the block number where the PolygonZkEVM smc was deployed")) } log.Info("Setting genesis block") header, err := s.etherMan.HeaderByNumber(s.ctx, big.NewInt(0).SetUint64(s.genesis.BlockNumber)) if err != nil { log.Errorf("error getting l1 block header for block %d. Error: %v", s.genesis.BlockNumber, err) - rollbackErr := dbTx.Rollback(s.ctx) - if rollbackErr != nil { - log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error()) - return rollbackErr - } - return err + return rollback(s.ctx, dbTx, err) } lastEthBlockSynced = &state.Block{ BlockNumber: header.Number.Uint64(), @@ -233,66 +227,23 @@ func (s *ClientSynchronizer) Sync() error { genesisRoot, err := s.state.SetGenesis(s.ctx, *lastEthBlockSynced, s.genesis, stateMetrics.SynchronizerCallerLabel, dbTx) if err != nil { log.Error("error setting genesis: ", err) - rollbackErr := dbTx.Rollback(s.ctx) - if rollbackErr != nil { - log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error()) - return rollbackErr - } - return err - } - - blocks, _, err := s.etherMan.GetRollupInfoByBlockRange(s.ctx, lastEthBlockSynced.BlockNumber, &lastEthBlockSynced.BlockNumber) - if err != nil { - log.Error("error getting rollupInfoByBlockRange after set the genesis: ", err) - rollbackErr := dbTx.Rollback(s.ctx) - if rollbackErr != nil { - log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error()) - return rollbackErr - } - return err + return rollback(s.ctx, dbTx, err) } - err = s.l1EventProcessors.Process(s.ctx, 1, etherman.Order{Name: etherman.ForkIDsOrder, Pos: 0}, &blocks[0], dbTx) + err = s.RequestAndProcessRollupGenesisBlock(dbTx, lastEthBlockSynced) if err != nil { - log.Error("error storing genesis forkID: ", err) - rollbackErr := dbTx.Rollback(s.ctx) - if rollbackErr != nil { - log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error()) - return rollbackErr - } - return err - } - if len(blocks[0].SequencedBatches) != 0 { - err = s.l1EventProcessors.Process(s.ctx, actions.ForkIdType(blocks[0].ForkIDs[0].ForkID), etherman.Order{Name: etherman.SequenceBatchesOrder, Pos: 0}, &blocks[0], dbTx) - if err != nil { - log.Error("error storing initial tx (batch 1): ", err) - rollbackErr := dbTx.Rollback(s.ctx) - if rollbackErr != nil { - log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error()) - return rollbackErr - } - return err - } + log.Error("error processing Rollup genesis block: ", err) + return rollback(s.ctx, dbTx, err) } if genesisRoot != s.genesis.Root { log.Errorf("Calculated newRoot should be %s instead of %s", s.genesis.Root.String(), genesisRoot.String()) - rollbackErr := dbTx.Rollback(s.ctx) - if rollbackErr != nil { - log.Errorf("error rolling back state. RollbackErr: %v", rollbackErr) - return rollbackErr - } - return fmt.Errorf("calculated newRoot should be %s instead of %s", s.genesis.Root.String(), genesisRoot.String()) + return rollback(s.ctx, dbTx, fmt.Errorf("calculated newRoot should be %s instead of %s", s.genesis.Root.String(), genesisRoot.String())) } // Waiting for the flushID to be stored err = s.checkFlushID(dbTx) if err != nil { log.Error("error checking genesis flushID: ", err) - rollbackErr := dbTx.Rollback(s.ctx) - if rollbackErr != nil { - log.Errorf("error rolling back state. RollbackErr: %v, err: %s", rollbackErr, err.Error()) - return rollbackErr - } - return err + return rollback(s.ctx, dbTx, err) } log.Debug("Genesis root matches!") } else { @@ -435,6 +386,54 @@ func (s *ClientSynchronizer) Sync() error { } } +// RequestAndProcessRollupGenesisBlock it requests the rollup genesis block and processes it +// +// and execute it +func (s *ClientSynchronizer) RequestAndProcessRollupGenesisBlock(dbTx pgx.Tx, lastEthBlockSynced *state.Block) error { + blocks, order, err := s.etherMan.GetRollupInfoByBlockRange(s.ctx, lastEthBlockSynced.BlockNumber, &lastEthBlockSynced.BlockNumber) + if err != nil { + log.Error("error getting rollupInfoByBlockRange after set the genesis: ", err) + return err + } + // Check that the response is the expected. It should be 1 block with 2 orders + err = sanityCheckForGenesisBlockRollupInfo(blocks, order) + if err != nil { + return err + } + forkId := s.state.GetForkIDByBlockNumber(blocks[0].BlockNumber) + err = s.l1EventProcessors.Process(s.ctx, actions.ForkIdType(forkId), etherman.Order{Name: etherman.ForkIDsOrder, Pos: 0}, &blocks[0], dbTx) + if err != nil { + log.Error("error storing genesis forkID: ", err) + return err + } + if len(blocks[0].SequencedBatches) != 0 { + batchSequence := l1event_orders.GetSequenceFromL1EventOrder(etherman.InitialSequenceBatchesOrder, &blocks[0], 0) + forkId = s.state.GetForkIDByBatchNumber(batchSequence.FromBatchNumber) + err = s.l1EventProcessors.Process(s.ctx, actions.ForkIdType(forkId), etherman.Order{Name: etherman.InitialSequenceBatchesOrder, Pos: 0}, &blocks[0], dbTx) + if err != nil { + log.Error("error storing initial tx (batch 1): ", err) + return err + } + } + return nil +} + +func sanityCheckForGenesisBlockRollupInfo(blocks []etherman.Block, order map[common.Hash][]etherman.Order) error { + if len(blocks) != 1 || len(order) != 1 || len(order[blocks[0].BlockHash]) != 2 { + log.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected 1 block with 2 orders") + return fmt.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected 1 block with 2 orders") + } + if order[blocks[0].BlockHash][0].Name != etherman.ForkIDsOrder { + log.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected ForkIDsOrder, got %s", order[blocks[0].BlockHash][0].Name) + return fmt.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected ForkIDsOrder") + } + if order[blocks[0].BlockHash][1].Name != etherman.InitialSequenceBatchesOrder { + log.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected InitialSequenceBatchesOrder, got %s", order[blocks[0].BlockHash][0].Name) + return fmt.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected InitialSequenceBatchesOrder") + } + return nil +} + // This function syncs the node from a specific block to the latest // lastEthBlockSynced -> last block synced in the db func (s *ClientSynchronizer) syncBlocksParallel(lastEthBlockSynced *state.Block) (*state.Block, error) { From 19c6694f65289907eba4fc1dacdb165c536c936b Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Fri, 23 Feb 2024 09:30:54 +0100 Subject: [PATCH 26/51] Add executor reserved ZK counters (#3348) * add executor reserved ZK counters * update prover image to v5.0.0-RC6 * fix typos * add check reserved counters when executing L2 block * remove closeBatch * update prover image v5.0.0-RC7 * fixes and logs improvements * update prover image v5.0.0-RC8 --- docker-compose.yml | 2 +- event/event.go | 3 +- sequencer/addrqueue.go | 6 +- sequencer/batch.go | 40 ++--- sequencer/errors.go | 4 +- sequencer/finalizer.go | 156 ++++++++++---------- sequencer/finalizer_test.go | 58 ++++---- sequencer/forcedbatch.go | 4 +- sequencer/interfaces.go | 4 +- sequencer/l2block.go | 86 ++++++++--- sequencer/mock_worker.go | 24 +-- sequencer/sequencer.go | 2 +- sequencer/txtracker.go | 80 +++++----- sequencer/worker.go | 33 +++-- sequencer/worker_test.go | 50 +++---- state/pgstatestorage/pgstatestorage_test.go | 2 +- state/types.go | 57 +++++-- test/docker-compose.yml | 4 +- 18 files changed, 336 insertions(+), 279 deletions(-) diff --git a/docker-compose.yml b/docker-compose.yml index 4fdea07a99..a6a3329621 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:v5.0.0-RC5 + image: hermeznetwork/zkevm-prover:v5.0.0-RC8 depends_on: zkevm-state-db: condition: service_healthy diff --git a/event/event.go b/event/event.go index c69380db80..7c325cc242 100644 --- a/event/event.go +++ b/event/event.go @@ -42,9 +42,10 @@ const ( EventID_SynchronizerHalt EventID = "SYNCHRONIZER HALT" // EventID_SequenceSenderHalt is triggered when the SequenceSender halts EventID_SequenceSenderHalt EventID = "SEQUENCESENDER HALT" - // EventID_NodeOOC is triggered when an OOC at node level is detected EventID_NodeOOC EventID = "NODE OOC" + // EventID_ReservedZKCountersOverflow is triggered when reserved ZK counters exceeds remaining batch ZK counters + EventID_ReservedZKCountersOverflow EventID = "RESERVED ZKCOUNTERS OVERFLOW" // Source_Node is the source of the event Source_Node Source = "node" diff --git a/sequencer/addrqueue.go b/sequencer/addrqueue.go index e479a35560..177521c449 100644 --- a/sequencer/addrqueue.go +++ b/sequencer/addrqueue.go @@ -217,17 +217,17 @@ func (a *addrQueue) updateCurrentNonceBalance(nonce *uint64, balance *big.Int) ( } // UpdateTxZKCounters updates the ZKCounters for the given tx (txHash) -func (a *addrQueue) UpdateTxZKCounters(txHash common.Hash, counters state.ZKCounters) { +func (a *addrQueue) UpdateTxZKCounters(txHash common.Hash, usedZKCounters state.ZKCounters, reservedZKCounters state.ZKCounters) { txHashStr := txHash.String() if (a.readyTx != nil) && (a.readyTx.HashStr == txHashStr) { log.Debugf("updating readyTx %s with new ZKCounters from addrQueue %s", txHashStr, a.fromStr) - a.readyTx.updateZKCounters(counters) + a.readyTx.updateZKCounters(usedZKCounters, reservedZKCounters) } else { for _, txTracker := range a.notReadyTxs { if txTracker.HashStr == txHashStr { log.Debugf("updating notReadyTx %s with new ZKCounters from addrQueue %s", txHashStr, a.fromStr) - txTracker.updateZKCounters(counters) + txTracker.updateZKCounters(usedZKCounters, reservedZKCounters) break } } diff --git a/sequencer/batch.go b/sequencer/batch.go index caf86142e5..00ad8678f6 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -238,7 +238,7 @@ func (f *finalizer) closeAndOpenNewWIPBatch(ctx context.Context, closeReason sta if f.wipL2Block != nil { f.wipBatch.imStateRoot = f.wipL2Block.imStateRoot // Subtract the WIP L2 block used resources to batch - overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(f.wipL2Block.usedResources) + overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(state.BatchResources{ZKCounters: f.wipL2Block.usedZKCounters, Bytes: f.wipL2Block.bytes}) if overflow { return fmt.Errorf("failed to subtract L2 block [%d] used resources to new wip batch %d, overflow resource: %s", f.wipL2Block.trackingNum, f.wipBatch.batchNumber, overflowResource) @@ -424,19 +424,7 @@ func (f *finalizer) batchSanityCheck(ctx context.Context, batchNum uint64, initi 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_Critical, - EventID: event.EventID_ReprocessFullBatchOOC, - Description: string(payload), - Json: batchRequest, - } - err = f.eventLog.LogEvent(ctx, event) - if err != nil { - log.Errorf("error storing payload, error: %v", err) - } + f.LogEvent(ctx, event.Level_Critical, event.EventID_ReprocessFullBatchOOC, string(payload), batchRequest) } return nil, ErrProcessBatchOOC @@ -469,7 +457,7 @@ func (f *finalizer) maxTxsPerBatchReached(batch *Batch) bool { // isBatchResourcesMarginExhausted checks if one of resources of the batch has reached the exhausted margin and returns the name of the exhausted resource func (f *finalizer) isBatchResourcesMarginExhausted(resources state.BatchResources) (bool, string) { - zkCounters := resources.UsedZKCounters + zkCounters := resources.ZKCounters result := false resourceName := "" if resources.Bytes <= f.getConstraintThresholdUint64(f.batchConstraints.MaxBatchBytesSize) { @@ -517,16 +505,16 @@ func (f *finalizer) getConstraintThresholdUint32(input uint32) uint32 { // getUsedBatchResources calculates and returns the used resources of a batch from remaining resources func getUsedBatchResources(constraints state.BatchConstraintsCfg, remainingResources state.BatchResources) state.BatchResources { return state.BatchResources{ - UsedZKCounters: state.ZKCounters{ - GasUsed: constraints.MaxCumulativeGasUsed - remainingResources.UsedZKCounters.GasUsed, - KeccakHashes: constraints.MaxKeccakHashes - remainingResources.UsedZKCounters.KeccakHashes, - PoseidonHashes: constraints.MaxPoseidonHashes - remainingResources.UsedZKCounters.PoseidonHashes, - PoseidonPaddings: constraints.MaxPoseidonPaddings - remainingResources.UsedZKCounters.PoseidonPaddings, - MemAligns: constraints.MaxMemAligns - remainingResources.UsedZKCounters.MemAligns, - Arithmetics: constraints.MaxArithmetics - remainingResources.UsedZKCounters.Arithmetics, - Binaries: constraints.MaxBinaries - remainingResources.UsedZKCounters.Binaries, - Steps: constraints.MaxSteps - remainingResources.UsedZKCounters.Steps, - Sha256Hashes_V2: constraints.MaxSHA256Hashes - remainingResources.UsedZKCounters.Sha256Hashes_V2, + ZKCounters: state.ZKCounters{ + GasUsed: constraints.MaxCumulativeGasUsed - remainingResources.ZKCounters.GasUsed, + KeccakHashes: constraints.MaxKeccakHashes - remainingResources.ZKCounters.KeccakHashes, + PoseidonHashes: constraints.MaxPoseidonHashes - remainingResources.ZKCounters.PoseidonHashes, + PoseidonPaddings: constraints.MaxPoseidonPaddings - remainingResources.ZKCounters.PoseidonPaddings, + MemAligns: constraints.MaxMemAligns - remainingResources.ZKCounters.MemAligns, + Arithmetics: constraints.MaxArithmetics - remainingResources.ZKCounters.Arithmetics, + Binaries: constraints.MaxBinaries - remainingResources.ZKCounters.Binaries, + Steps: constraints.MaxSteps - remainingResources.ZKCounters.Steps, + Sha256Hashes_V2: constraints.MaxSHA256Hashes - remainingResources.ZKCounters.Sha256Hashes_V2, }, Bytes: constraints.MaxBatchBytesSize - remainingResources.Bytes, } @@ -535,7 +523,7 @@ func getUsedBatchResources(constraints state.BatchConstraintsCfg, remainingResou // getMaxRemainingResources returns the max resources that can be used in a batch func getMaxRemainingResources(constraints state.BatchConstraintsCfg) state.BatchResources { return state.BatchResources{ - UsedZKCounters: state.ZKCounters{ + ZKCounters: state.ZKCounters{ GasUsed: constraints.MaxCumulativeGasUsed, KeccakHashes: constraints.MaxKeccakHashes, PoseidonHashes: constraints.MaxPoseidonHashes, diff --git a/sequencer/errors.go b/sequencer/errors.go index a61ae7b4c1..8251cd79e5 100644 --- a/sequencer/errors.go +++ b/sequencer/errors.go @@ -29,8 +29,8 @@ var ( ErrExecutorError = errors.New("executor error") // ErrNoFittingTransaction happens when there is not a tx (from the txSortedList) that fits in the remaining batch resources ErrNoFittingTransaction = errors.New("no fit transaction") - // ErrBatchResourceUnderFlow happens when there is batch resoure underflow after sustract the resources from a tx - ErrBatchResourceUnderFlow = errors.New("batch resource underflow") + // ErrBatchResourceOverFlow happens when there is a tx that overlows remaining batch resources + ErrBatchResourceOverFlow = errors.New("batch resource overflow") // ErrTransactionsListEmpty happens when txSortedList is empty ErrTransactionsListEmpty = errors.New("transactions list empty") ) diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index ad759183fd..4a96c421c9 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -277,7 +277,6 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { continue } - closeWIPBatch := false metrics.WorkerProcessingTime(time.Since(start)) if tx != nil { showNotFoundTxLog = true @@ -286,14 +285,14 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { for { var err error - _, closeWIPBatch, err = f.processTransaction(ctx, tx, firstTxProcess) + _, err = f.processTransaction(ctx, tx, firstTxProcess) if err != nil { if err == ErrEffectiveGasPriceReprocess { firstTxProcess = false log.Infof("reprocessing tx %s because of effective gas price calculation", tx.HashStr) continue - } else if err == ErrBatchResourceUnderFlow { - log.Infof("skipping tx %s due to a batch resource underflow", tx.HashStr) + } else if err == ErrBatchResourceOverFlow { + log.Infof("skipping tx %s due to a batch resource overflow", tx.HashStr) break } else { log.Errorf("failed to process tx %s, error: %v", err) @@ -321,11 +320,7 @@ 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) - finalize, closeReason := f.checkIfFinalizeBatch() - if closeWIPBatch || finalize { - if closeWIPBatch { - closeReason = "Executor close batch" - } + if finalize, closeReason := f.checkIfFinalizeBatch(); finalize { f.finalizeWIPBatch(ctx, closeReason) } @@ -337,7 +332,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, closeWIPBatch bool, err error) { +func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, firstTxProcess bool) (errWg *sync.WaitGroup, err error) { start := time.Now() defer func() { metrics.ProcessingTime(time.Since(start)) @@ -374,14 +369,14 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first // Save values for later logging tx.EGPLog.L1GasPrice = tx.L1GasPrice tx.EGPLog.L2GasPrice = txL2GasPrice - tx.EGPLog.GasUsedFirst = tx.BatchResources.UsedZKCounters.GasUsed + tx.EGPLog.GasUsedFirst = tx.UsedZKCounters.GasUsed tx.EGPLog.GasPrice.Set(txGasPrice) // Calculate EffectiveGasPrice - egp, err := f.effectiveGasPrice.CalculateEffectiveGasPrice(tx.RawTx, txGasPrice, tx.BatchResources.UsedZKCounters.GasUsed, tx.L1GasPrice, txL2GasPrice) + egp, err := f.effectiveGasPrice.CalculateEffectiveGasPrice(tx.RawTx, txGasPrice, tx.UsedZKCounters.GasUsed, tx.L1GasPrice, txL2GasPrice) if err != nil { if f.effectiveGasPrice.IsEnabled() { - return nil, false, err + return nil, 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) @@ -409,7 +404,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, false, err + return nil, 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) @@ -429,7 +424,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, false, err + return nil, err } batchRequest.Transactions = append(batchRequest.Transactions, effectivePercentageAsDecodedHex...) @@ -438,7 +433,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, false, err + return nil, 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) @@ -456,35 +451,35 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first } else { metrics.TxProcessed(metrics.TxProcessedLabelInvalid, 1) } - return nil, false, err + return nil, err } - closeBatch := false oldStateRoot := f.wipBatch.imStateRoot if len(batchResponse.BlockResponses) > 0 { - errWg, closeBatch, err = f.handleProcessTransactionResponse(ctx, tx, batchResponse, oldStateRoot) + errWg, err = f.handleProcessTransactionResponse(ctx, tx, batchResponse, oldStateRoot) if err != nil { - return errWg, false, err + return errWg, err } } // Update imStateRoot f.wipBatch.imStateRoot = batchResponse.NewStateRoot - 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)) + log.Infof("processed tx %s, batchNumber: %d, l2Block: [%d], newStateRoot: %s, oldStateRoot: %s, used counters: %s, reserved counters: %s", + tx.HashStr, batchRequest.BatchNumber, f.wipL2Block.trackingNum, batchResponse.NewStateRoot.String(), batchRequest.OldStateRoot.String(), + f.logZKCounters(batchResponse.UsedZkCounters), f.logZKCounters(batchResponse.ReservedZkCounters)) - return nil, closeBatch, nil + return nil, 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, closeWIPBatch bool, err error) { +func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *TxTracker, result *state.ProcessBatchResponse, oldStateRoot common.Hash) (errWg *sync.WaitGroup, 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, false, result.BlockResponses[0].TransactionResponses[0].RomError + return errWg, result.BlockResponses[0].TransactionResponses[0].RomError } egpEnabled := f.effectiveGasPrice.IsEnabled() @@ -499,7 +494,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, false, err + return nil, 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) @@ -524,32 +519,29 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx } if errCompare != nil && egpEnabled { - return nil, false, errCompare + return nil, errCompare } } } - // Check remaining resources - - overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(state.BatchResources{UsedZKCounters: result.UsedZkCounters, Bytes: uint64(len(tx.RawTx))}) - if overflow { - log.Infof("current tx %s exceeds the remaining batch resources, overflow resource: %s, updating metadata for tx in worker and continuing", tx.HashStr, overflowResource) - if !f.batchConstraints.IsWithinConstraints(result.UsedZkCounters) { - log.Warnf("current tx %s exceeds the max limit for batch resources (node OOC), setting tx as invalid in the pool", tx.HashStr) - - event := &event.Event{ - ReceivedAt: time.Now(), - Source: event.Source_Node, - Component: event.Component_Sequencer, - Level: event.Level_Error, - EventID: event.EventID_NodeOOC, - Description: fmt.Sprintf("tx: %s exceeds node max limit batch resources (node OOC), from: %s, IP: %s", tx.HashStr, tx.FromStr, tx.IP), - } + // Check if reserved resources of the tx fits in the remaining batch resources + subOverflow := false + fits, overflowResource := f.wipBatch.imRemainingResources.Fits(state.BatchResources{ZKCounters: result.ReservedZkCounters, Bytes: uint64(len(tx.RawTx))}) + if fits { + // Sustract the used resources from the batch + subOverflow, overflowResource = f.wipBatch.imRemainingResources.Sub(state.BatchResources{ZKCounters: result.UsedZkCounters, Bytes: uint64(len(tx.RawTx))}) + if subOverflow { // Sanity check, this cannot happen as reservedZKCounters should be >= that usedZKCounters + log.Infof("current tx %s used resources exceeds the remaining batch resources, overflow resource: %s, updating metadata for tx in worker and continuing. Batch counters: %s, tx used counters: %s", + tx.HashStr, overflowResource, f.logZKCounters(f.wipBatch.imRemainingResources.ZKCounters), f.logZKCounters(result.UsedZkCounters)) + } + } else { + log.Infof("current tx %s reserved resources exceeds the remaining batch resources, overflow resource: %s, updating metadata for tx in worker and continuing. Batch counters: %s, tx reserved counters: %s", + tx.HashStr, overflowResource, f.logZKCounters(f.wipBatch.imRemainingResources.ZKCounters), f.logZKCounters(result.ReservedZkCounters)) + if !f.batchConstraints.IsWithinConstraints(result.ReservedZkCounters) { + log.Warnf("current tx %s reserved resources exceeds the max limit for batch resources (node OOC), setting tx as invalid in the pool", tx.HashStr) - eventErr := f.eventLog.LogEvent(ctx, event) - if eventErr != nil { - log.Errorf("error storing finalizer halt event, error: %v", eventErr) - } + f.LogEvent(ctx, event.Level_Error, event.EventID_NodeOOC, + fmt.Sprintf("tx: %s exceeds node max limit batch resources (node OOC), from: %s, IP: %s", tx.HashStr, tx.FromStr, tx.IP), nil) // Delete the transaction from the txSorted list f.workerIntf.DeleteTx(tx.Hash, tx.From) @@ -559,16 +551,18 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx if err != nil { log.Errorf("failed to update status to invalid in the pool for tx %s, error: %v", tx.Hash.String(), err) } - - 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, false, ErrBatchResourceUnderFlow } } + // If reserved tx resources don't fit in the remaining batch resources (or we got an overflow when trying to subtract the used resources) + // we update the ZKCounters of the tx and returns ErrBatchResourceOverFlow error + if !fits || subOverflow { + start := time.Now() + f.workerIntf.UpdateTxZKCounters(result.BlockResponses[0].TransactionResponses[0].TxHash, tx.From, result.UsedZkCounters, result.ReservedZkCounters) + metrics.WorkerProcessingTime(time.Since(start)) + return nil, ErrBatchResourceOverFlow + } + // Save Enabled, GasPriceOC, BalanceOC and final effective gas price for later logging tx.EGPLog.Enabled = egpEnabled tx.EGPLog.GasPriceOC = result.BlockResponses[0].TransactionResponses[0].HasGaspriceOpcode @@ -581,10 +575,12 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx tx.EGPLog.GasPrice, tx.EGPLog.L1GasPrice, tx.EGPLog.L2GasPrice, tx.EGPLog.Reprocess, tx.EGPLog.GasPriceOC, tx.EGPLog.BalanceOC, egpEnabled, len(tx.RawTx), tx.HashStr, tx.EGPLog.Error) f.wipL2Block.addTx(tx) + f.wipBatch.countOfTxs++ + f.updateWorkerAfterSuccessfulProcessing(ctx, tx.Hash, tx.From, false, result) - return nil, false, nil + return nil, nil } // compareTxEffectiveGasPrice compares newEffectiveGasPrice with tx.EffectiveGasPrice. @@ -728,19 +724,8 @@ func (f *finalizer) handleProcessTransactionError(ctx context.Context, result *s // checkIfProverRestarted checks if the proverID changed func (f *finalizer) checkIfProverRestarted(proverID string) { if f.proverID != "" && f.proverID != proverID { - event := &event.Event{ - ReceivedAt: time.Now(), - Source: event.Source_Node, - Component: event.Component_Sequencer, - Level: event.Level_Critical, - EventID: event.EventID_FinalizerRestart, - Description: fmt.Sprintf("proverID changed from %s to %s, restarting sequencer to discard current WIP batch and work with new executor", f.proverID, proverID), - } - - err := f.eventLog.LogEvent(context.Background(), event) - if err != nil { - log.Errorf("error storing payload, error: %v", err) - } + f.LogEvent(context.Background(), event.Level_Critical, event.EventID_FinalizerRestart, + fmt.Sprintf("proverID changed from %s to %s, restarting sequencer to discard current WIP batch and work with new executor", f.proverID, proverID), nil) log.Fatal("proverID changed from %s to %s, restarting sequencer to discard current WIP batch and work with new executor") } @@ -757,19 +742,7 @@ func (f *finalizer) logZKCounters(counters state.ZKCounters) string { func (f *finalizer) Halt(ctx context.Context, err error, isFatal bool) { f.haltFinalizer.Store(true) - event := &event.Event{ - ReceivedAt: time.Now(), - Source: event.Source_Node, - Component: event.Component_Sequencer, - Level: event.Level_Critical, - EventID: event.EventID_FinalizerHalt, - Description: fmt.Sprintf("finalizer halted due to error, error: %s", err), - } - - eventErr := f.eventLog.LogEvent(ctx, event) - if eventErr != nil { - log.Errorf("error storing finalizer halt event, error: %v", eventErr) - } + f.LogEvent(ctx, event.Level_Critical, event.EventID_FinalizerHalt, fmt.Sprintf("finalizer halted due to error, error: %s", err), nil) if isFatal { log.Fatalf("fatal error on finalizer, error: %v", err) @@ -780,3 +753,24 @@ func (f *finalizer) Halt(ctx context.Context, err error, isFatal bool) { } } } + +// LogEvent adds an event for runtime debugging +func (f *finalizer) LogEvent(ctx context.Context, level event.Level, eventId event.EventID, description string, json interface{}) { + event := &event.Event{ + ReceivedAt: time.Now(), + Source: event.Source_Node, + Component: event.Component_Sequencer, + Level: level, + EventID: eventId, + Description: description, + } + + if json != nil { + event.Json = json + } + + eventErr := f.eventLog.LogEvent(ctx, event) + if eventErr != nil { + log.Errorf("error storing log event, error: %v", eventErr) + } +} diff --git a/sequencer/finalizer_test.go b/sequencer/finalizer_test.go index 278e8c50cd..e119919ffe 100644 --- a/sequencer/finalizer_test.go +++ b/sequencer/finalizer_test.go @@ -1077,8 +1077,8 @@ func TestFinalizer_checkRemainingResources(t *testing.T) { BlockResponses: []*state.ProcessBlockResponse{blockResponse}, } remainingResources := state.BatchResources{ - UsedZKCounters: state.ZKCounters{GasUsed: 9000}, - Bytes: 10000, + ZKCounters: state.ZKCounters{GasUsed: 9000}, + Bytes: 10000, } f.wipBatch.imRemainingResources = remainingResources testCases := []struct { @@ -1109,7 +1109,7 @@ func TestFinalizer_checkRemainingResources(t *testing.T) { { name: "ZkCounter Resource Exceeded", remaining: state.BatchResources{ - UsedZKCounters: state.ZKCounters{GasUsed: 0}, + ZKCounters: state.ZKCounters{GasUsed: 0}, }, overflow: true, overflowResource: "CumulativeGas", @@ -1128,7 +1128,7 @@ func TestFinalizer_checkRemainingResources(t *testing.T) { } // act - overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(state.BatchResources{UsedZKCounters: result.UsedZkCounters, Bytes: uint64(len(tc.expectedTxTracker.RawTx))}) + overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(state.BatchResources{ZKCounters: result.UsedZkCounters, Bytes: uint64(len(tc.expectedTxTracker.RawTx))}) // assert assert.Equal(t, tc.overflow, overflow) @@ -1906,7 +1906,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxCumulativeGasUsed", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.GasUsed = f.getConstraintThresholdUint64(bc.MaxCumulativeGasUsed) - 1 + resources.ZKCounters.GasUsed = f.getConstraintThresholdUint64(bc.MaxCumulativeGasUsed) - 1 return resources }, expectedResult: true, @@ -1914,7 +1914,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxCumulativeGasUsed", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.GasUsed = f.getConstraintThresholdUint64(bc.MaxCumulativeGasUsed) + 1 + resources.ZKCounters.GasUsed = f.getConstraintThresholdUint64(bc.MaxCumulativeGasUsed) + 1 return resources }, expectedResult: false, @@ -1922,7 +1922,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxSteps", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.Steps = f.getConstraintThresholdUint32(bc.MaxSteps) - 1 + resources.ZKCounters.Steps = f.getConstraintThresholdUint32(bc.MaxSteps) - 1 return resources }, expectedResult: true, @@ -1930,7 +1930,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxSteps", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.Steps = f.getConstraintThresholdUint32(bc.MaxSteps) + 1 + resources.ZKCounters.Steps = f.getConstraintThresholdUint32(bc.MaxSteps) + 1 return resources }, expectedResult: false, @@ -1938,7 +1938,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxPoseidonPaddings", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.PoseidonPaddings = f.getConstraintThresholdUint32(bc.MaxPoseidonPaddings) - 1 + resources.ZKCounters.PoseidonPaddings = f.getConstraintThresholdUint32(bc.MaxPoseidonPaddings) - 1 return resources }, expectedResult: true, @@ -1946,7 +1946,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxPoseidonPaddings", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.PoseidonPaddings = f.getConstraintThresholdUint32(bc.MaxPoseidonPaddings) + 1 + resources.ZKCounters.PoseidonPaddings = f.getConstraintThresholdUint32(bc.MaxPoseidonPaddings) + 1 return resources }, expectedResult: false, @@ -1954,7 +1954,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxBinaries", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.Binaries = f.getConstraintThresholdUint32(bc.MaxBinaries) - 1 + resources.ZKCounters.Binaries = f.getConstraintThresholdUint32(bc.MaxBinaries) - 1 return resources }, expectedResult: true, @@ -1962,7 +1962,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxBinaries", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.Binaries = f.getConstraintThresholdUint32(bc.MaxBinaries) + 1 + resources.ZKCounters.Binaries = f.getConstraintThresholdUint32(bc.MaxBinaries) + 1 return resources }, expectedResult: false, @@ -1970,7 +1970,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxKeccakHashes", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.KeccakHashes = f.getConstraintThresholdUint32(bc.MaxKeccakHashes) - 1 + resources.ZKCounters.KeccakHashes = f.getConstraintThresholdUint32(bc.MaxKeccakHashes) - 1 return resources }, expectedResult: true, @@ -1978,7 +1978,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxKeccakHashes", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.KeccakHashes = f.getConstraintThresholdUint32(bc.MaxKeccakHashes) + 1 + resources.ZKCounters.KeccakHashes = f.getConstraintThresholdUint32(bc.MaxKeccakHashes) + 1 return resources }, expectedResult: false, @@ -1986,7 +1986,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxArithmetics", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.Arithmetics = f.getConstraintThresholdUint32(bc.MaxArithmetics) - 1 + resources.ZKCounters.Arithmetics = f.getConstraintThresholdUint32(bc.MaxArithmetics) - 1 return resources }, expectedResult: true, @@ -1994,7 +1994,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxArithmetics", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.Arithmetics = f.getConstraintThresholdUint32(bc.MaxArithmetics) + 1 + resources.ZKCounters.Arithmetics = f.getConstraintThresholdUint32(bc.MaxArithmetics) + 1 return resources }, expectedResult: false, @@ -2002,7 +2002,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxMemAligns", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.MemAligns = f.getConstraintThresholdUint32(bc.MaxMemAligns) - 1 + resources.ZKCounters.MemAligns = f.getConstraintThresholdUint32(bc.MaxMemAligns) - 1 return resources }, expectedResult: true, @@ -2010,7 +2010,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxMemAligns", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.MemAligns = f.getConstraintThresholdUint32(bc.MaxMemAligns) + 1 + resources.ZKCounters.MemAligns = f.getConstraintThresholdUint32(bc.MaxMemAligns) + 1 return resources }, expectedResult: false, @@ -2018,7 +2018,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is ready - MaxSHA256Hashes", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.Sha256Hashes_V2 = f.getConstraintThresholdUint32(bc.MaxSHA256Hashes) - 1 + resources.ZKCounters.Sha256Hashes_V2 = f.getConstraintThresholdUint32(bc.MaxSHA256Hashes) - 1 return resources }, expectedResult: true, @@ -2026,7 +2026,7 @@ func TestFinalizer_isBatchAlmostFull(t *testing.T) { { name: "Is NOT ready - MaxSHA256Hashes", modifyResourceFunc: func(resources state.BatchResources) state.BatchResources { - resources.UsedZKCounters.Sha256Hashes_V2 = f.getConstraintThresholdUint32(bc.MaxSHA256Hashes) + 1 + resources.ZKCounters.Sha256Hashes_V2 = f.getConstraintThresholdUint32(bc.MaxSHA256Hashes) + 1 return resources }, expectedResult: false, @@ -2101,15 +2101,15 @@ func TestFinalizer_getRemainingResources(t *testing.T) { remainingResources := getMaxRemainingResources(bc) // assert - assert.Equal(t, remainingResources.UsedZKCounters.GasUsed, bc.MaxCumulativeGasUsed) - assert.Equal(t, remainingResources.UsedZKCounters.KeccakHashes, bc.MaxKeccakHashes) - assert.Equal(t, remainingResources.UsedZKCounters.PoseidonHashes, bc.MaxPoseidonHashes) - assert.Equal(t, remainingResources.UsedZKCounters.PoseidonPaddings, bc.MaxPoseidonPaddings) - assert.Equal(t, remainingResources.UsedZKCounters.MemAligns, bc.MaxMemAligns) - assert.Equal(t, remainingResources.UsedZKCounters.Arithmetics, bc.MaxArithmetics) - assert.Equal(t, remainingResources.UsedZKCounters.Binaries, bc.MaxBinaries) - assert.Equal(t, remainingResources.UsedZKCounters.Steps, bc.MaxSteps) - assert.Equal(t, remainingResources.UsedZKCounters.Sha256Hashes_V2, bc.MaxSHA256Hashes) + assert.Equal(t, remainingResources.ZKCounters.GasUsed, bc.MaxCumulativeGasUsed) + assert.Equal(t, remainingResources.ZKCounters.KeccakHashes, bc.MaxKeccakHashes) + assert.Equal(t, remainingResources.ZKCounters.PoseidonHashes, bc.MaxPoseidonHashes) + assert.Equal(t, remainingResources.ZKCounters.PoseidonPaddings, bc.MaxPoseidonPaddings) + assert.Equal(t, remainingResources.ZKCounters.MemAligns, bc.MaxMemAligns) + assert.Equal(t, remainingResources.ZKCounters.Arithmetics, bc.MaxArithmetics) + assert.Equal(t, remainingResources.ZKCounters.Binaries, bc.MaxBinaries) + assert.Equal(t, remainingResources.ZKCounters.Steps, bc.MaxSteps) + assert.Equal(t, remainingResources.ZKCounters.Sha256Hashes_V2, bc.MaxSHA256Hashes) assert.Equal(t, remainingResources.Bytes, bc.MaxBatchBytesSize) } diff --git a/sequencer/forcedbatch.go b/sequencer/forcedbatch.go index d27485377b..4f035ec708 100644 --- a/sequencer/forcedbatch.go +++ b/sequencer/forcedbatch.go @@ -121,8 +121,8 @@ func (f *finalizer) processForcedBatch(ctx context.Context, forcedBatch state.Fo LocalExitRoot: batchResponse.NewLocalExitRoot, BatchL2Data: forcedBatch.RawTxsData, BatchResources: state.BatchResources{ - UsedZKCounters: batchResponse.UsedZkCounters, - Bytes: uint64(len(forcedBatch.RawTxsData)), + ZKCounters: batchResponse.UsedZkCounters, + Bytes: uint64(len(forcedBatch.RawTxsData)), }, ClosingReason: state.ForcedBatchClosingReason, } diff --git a/sequencer/interfaces.go b/sequencer/interfaces.go index 9008fbef09..41dca25096 100644 --- a/sequencer/interfaces.go +++ b/sequencer/interfaces.go @@ -82,13 +82,13 @@ type stateInterface interface { type workerInterface interface { GetBestFittingTx(resources state.BatchResources) (*TxTracker, error) UpdateAfterSingleSuccessfulTxExecution(from common.Address, touchedAddresses map[common.Address]*state.InfoReadWrite) []*TxTracker - UpdateTxZKCounters(txHash common.Hash, from common.Address, ZKCounters state.ZKCounters) + UpdateTxZKCounters(txHash common.Hash, from common.Address, usedZKCounters state.ZKCounters, reservedZKCounters state.ZKCounters) AddTxTracker(ctx context.Context, txTracker *TxTracker) (replacedTx *TxTracker, dropReason error) MoveTxToNotReady(txHash common.Hash, from common.Address, actualNonce *uint64, actualBalance *big.Int) []*TxTracker DeleteTx(txHash common.Hash, from common.Address) AddPendingTxToStore(txHash common.Hash, addr common.Address) DeletePendingTxToStore(txHash common.Hash, addr common.Address) - NewTxTracker(tx types.Transaction, counters state.ZKCounters, ip string) (*TxTracker, error) + NewTxTracker(tx types.Transaction, usedZKcounters state.ZKCounters, reservedZKCouners state.ZKCounters, ip string) (*TxTracker, error) AddForcedTx(txHash common.Hash, addr common.Address) DeleteForcedTx(txHash common.Hash, addr common.Address) } diff --git a/sequencer/l2block.go b/sequencer/l2block.go index b9ed8d0b6c..8c81932fd2 100644 --- a/sequencer/l2block.go +++ b/sequencer/l2block.go @@ -5,6 +5,7 @@ import ( "fmt" "time" + "github.com/0xPolygonHermez/zkevm-node/event" "github.com/0xPolygonHermez/zkevm-node/hex" "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/pool" @@ -23,7 +24,9 @@ type L2Block struct { imStateRoot common.Hash l1InfoTreeExitRoot state.L1InfoTreeExitRootStorageEntry l1InfoTreeExitRootChanged bool - usedResources state.BatchResources + bytes uint64 + usedZKCounters state.ZKCounters + reservedZKCounters state.ZKCounters transactions []*TxTracker batchResponse *state.ProcessBatchResponse } @@ -109,6 +112,7 @@ func (f *finalizer) processPendingL2Blocks(ctx context.Context) { } err := f.processL2Block(ctx, l2Block) + f.dumpL2Block(l2Block) if err != nil { // Dump L2Block info @@ -139,6 +143,7 @@ func (f *finalizer) storePendingL2Blocks(ctx context.Context) { } err := f.storeL2Block(ctx, l2Block) + f.dumpL2Block(l2Block) if err != nil { // Dump L2Block info @@ -197,10 +202,20 @@ func (f *finalizer) processL2Block(ctx context.Context, l2Block *L2Block) error l2Block.batchResponse = batchResponse // Update finalRemainingResources of the batch - overflow, overflowResource := f.wipBatch.finalRemainingResources.Sub(state.BatchResources{UsedZKCounters: batchResponse.UsedZkCounters, Bytes: batchL2DataSize}) - if overflow { - return fmt.Errorf("error sustracting L2 block %d [%d] resources from the batch %d, overflow resource: %s, batch remaining counters: %s, L2Block used counters: %s, batch remaining bytes: %d, L2Block used bytes: %d", - blockResponse.BlockNumber, l2Block.trackingNum, f.wipBatch.batchNumber, overflowResource, f.logZKCounters(f.wipBatch.finalRemainingResources.UsedZKCounters), f.logZKCounters(batchResponse.UsedZkCounters), f.wipBatch.finalRemainingResources.Bytes, batchL2DataSize) + fits, overflowResource := f.wipBatch.finalRemainingResources.Fits(state.BatchResources{ZKCounters: batchResponse.ReservedZkCounters, Bytes: batchL2DataSize}) + if fits { + subOverflow, overflowResource := f.wipBatch.finalRemainingResources.Sub(state.BatchResources{ZKCounters: batchResponse.UsedZkCounters, Bytes: batchL2DataSize}) + if subOverflow { // Sanity check, this cannot happen as reservedZKCounters should be >= that usedZKCounters + return fmt.Errorf("error sustracting L2 block %d [%d] used resources from the batch %d, overflow resource: %s, batch counters: %s, L2 block used counters: %s, batch bytes: %d, L2 block bytes: %d", + blockResponse.BlockNumber, l2Block.trackingNum, f.wipBatch.batchNumber, overflowResource, f.logZKCounters(f.wipBatch.finalRemainingResources.ZKCounters), f.logZKCounters(batchResponse.UsedZkCounters), f.wipBatch.finalRemainingResources.Bytes, batchL2DataSize) + } + } else { + overflowLog := fmt.Sprintf("L2 block %d [%d] reserved resources exceeds the remaining batch %d resources, overflow resource: %s, batch counters: %s, L2 block reserved counters: %s, batch bytes: %d, L2 block bytes: %d", + blockResponse.BlockNumber, l2Block.trackingNum, f.wipBatch.batchNumber, overflowResource, f.logZKCounters(f.wipBatch.finalRemainingResources.ZKCounters), f.logZKCounters(batchResponse.ReservedZkCounters), f.wipBatch.finalRemainingResources.Bytes, batchL2DataSize) + + log.Warnf(overflowLog) + + f.LogEvent(ctx, event.Level_Warning, event.EventID_ReservedZKCountersOverflow, overflowLog, nil) } // Update finalStateRoot of the batch to the newStateRoot for the L2 block @@ -212,9 +227,9 @@ func (f *finalizer) processL2Block(ctx context.Context, l2Block *L2Block) error endProcessing := time.Now() - log.Infof("processed L2 block %d [%d], batch: %d, deltaTimestamp: %d, timestamp: %d, l1InfoTreeIndex: %d, l1InfoTreeIndexChanged: %v, initialStateRoot: %s, newStateRoot: %s, txs: %d/%d, blockHash: %s, infoRoot: %s, time: %v, used counters: %s", - blockResponse.BlockNumber, l2Block.trackingNum, f.wipBatch.batchNumber, l2Block.deltaTimestamp, l2Block.timestamp, l2Block.l1InfoTreeExitRoot.L1InfoTreeIndex, l2Block.l1InfoTreeExitRootChanged, initialStateRoot, - l2Block.batchResponse.NewStateRoot, len(l2Block.transactions), len(blockResponse.TransactionResponses), blockResponse.BlockHash, blockResponse.BlockInfoRoot, endProcessing.Sub(startProcessing), f.logZKCounters(batchResponse.UsedZkCounters)) + log.Infof("processed L2 block %d [%d], batch: %d, deltaTimestamp: %d, timestamp: %d, l1InfoTreeIndex: %d, l1InfoTreeIndexChanged: %v, initialStateRoot: %s, newStateRoot: %s, txs: %d/%d, blockHash: %s, infoRoot: %s, time: %v, used counters: %s, reserved counters: %s", + blockResponse.BlockNumber, l2Block.trackingNum, f.wipBatch.batchNumber, l2Block.deltaTimestamp, l2Block.timestamp, l2Block.l1InfoTreeExitRoot.L1InfoTreeIndex, l2Block.l1InfoTreeExitRootChanged, initialStateRoot, l2Block.batchResponse.NewStateRoot, + len(l2Block.transactions), len(blockResponse.TransactionResponses), blockResponse.BlockHash, blockResponse.BlockInfoRoot, endProcessing.Sub(startProcessing), f.logZKCounters(batchResponse.UsedZkCounters), f.logZKCounters(batchResponse.ReservedZkCounters)) return nil } @@ -360,7 +375,7 @@ func (f *finalizer) storeL2Block(ctx context.Context, l2Block *L2Block) error { } batch.BatchL2Data = append(batch.BatchL2Data, blockL2Data...) - batch.Resources.SumUp(state.BatchResources{UsedZKCounters: l2Block.batchResponse.UsedZkCounters, Bytes: uint64(len(blockL2Data))}) + batch.Resources.SumUp(state.BatchResources{ZKCounters: l2Block.batchResponse.UsedZkCounters, Bytes: uint64(len(blockL2Data))}) receipt := state.ProcessingReceipt{ BatchNumber: f.wipBatch.batchNumber, @@ -504,25 +519,39 @@ func (f *finalizer) openNewWIPL2Block(ctx context.Context, prevTimestamp uint64, f.wipL2Block.imStateRoot = batchResponse.NewStateRoot f.wipBatch.imStateRoot = f.wipL2Block.imStateRoot - // Save and sustract the resources used by the new WIP L2 block from the wip batch + // Save the resources used/reserved and subtract the ZKCounters reserved by the new WIP L2 block from the WIP batch // We need to increase the poseidon hashes to reserve in the batch the hashes needed to write the L1InfoRoot when processing the final L2 Block (SkipWriteBlockInfoRoot_V2=false) - f.wipL2Block.usedResources.UsedZKCounters = batchResponse.UsedZkCounters - f.wipL2Block.usedResources.UsedZKCounters.PoseidonHashes = (batchResponse.UsedZkCounters.PoseidonHashes * 2) + 2 // nolint:gomnd - f.wipL2Block.usedResources.Bytes = changeL2BlockSize - - overflow, overflowResource := f.wipBatch.imRemainingResources.Sub(f.wipL2Block.usedResources) - if overflow { - log.Infof("new WIP L2 block [%d] exceeds the remaining resources from the batch %d, overflow resource: %s, closing WIP batch and creating new one", - f.wipL2Block.trackingNum, f.wipBatch.batchNumber, overflowResource) + f.wipL2Block.usedZKCounters = batchResponse.UsedZkCounters + f.wipL2Block.usedZKCounters.PoseidonHashes = (batchResponse.UsedZkCounters.PoseidonHashes * 2) + 2 // nolint:gomnd + f.wipL2Block.reservedZKCounters = batchResponse.ReservedZkCounters + f.wipL2Block.reservedZKCounters.PoseidonHashes = (batchResponse.ReservedZkCounters.PoseidonHashes * 2) + 2 // nolint:gomnd + f.wipL2Block.bytes = changeL2BlockSize + + subOverflow := false + fits, overflowResource := f.wipBatch.imRemainingResources.Fits(state.BatchResources{ZKCounters: f.wipL2Block.reservedZKCounters, Bytes: f.wipL2Block.bytes}) + if fits { + subOverflow, overflowResource = f.wipBatch.imRemainingResources.Sub(state.BatchResources{ZKCounters: f.wipL2Block.usedZKCounters, Bytes: f.wipL2Block.bytes}) + if subOverflow { // Sanity check, this cannot happen as reservedZKCounters should be >= that usedZKCounters + log.Infof("new WIP L2 block [%d] used resources exceeds the remaining batch resources, overflow resource: %s, closing WIP batch and creating new one. Batch counters: %s, L2 block used counters: %s", + f.wipL2Block.trackingNum, overflowResource, f.logZKCounters(f.wipBatch.imRemainingResources.ZKCounters), f.logZKCounters(f.wipL2Block.usedZKCounters)) + } + } else { + log.Infof("new WIP L2 block [%d] reserved resources exceeds the remaining batch resources, overflow resource: %s, closing WIP batch and creating new one. Batch counters: %s, L2 block reserved counters: %s", + f.wipL2Block.trackingNum, overflowResource, f.logZKCounters(f.wipBatch.imRemainingResources.ZKCounters), f.logZKCounters(f.wipL2Block.reservedZKCounters)) + } + + // If reserved WIP L2 block resources don't fit in the remaining batch resources (or we got an overflow when trying to subtract the used resources) + // we close the WIP batch and we create a new one + if !fits || subOverflow { err := f.closeAndOpenNewWIPBatch(ctx, state.ResourceExhaustedClosingReason) if err != nil { f.Halt(ctx, fmt.Errorf("failed to create new WIP batch [%d], error: %v", f.wipL2Block.trackingNum, err), true) } } - log.Infof("created new WIP L2 block [%d], batch: %d, deltaTimestamp: %d, timestamp: %d, l1InfoTreeIndex: %d, l1InfoTreeIndexChanged: %v, oldStateRoot: %s, imStateRoot: %s, used counters: %s", + log.Infof("created new WIP L2 block [%d], batch: %d, deltaTimestamp: %d, timestamp: %d, l1InfoTreeIndex: %d, l1InfoTreeIndexChanged: %v, oldStateRoot: %s, imStateRoot: %s, used counters: %s, reserved counters: %s", f.wipL2Block.trackingNum, f.wipBatch.batchNumber, f.wipL2Block.deltaTimestamp, f.wipL2Block.timestamp, f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex, - f.wipL2Block.l1InfoTreeExitRootChanged, oldIMStateRoot, f.wipL2Block.imStateRoot, f.logZKCounters(f.wipL2Block.usedResources.UsedZKCounters)) + f.wipL2Block.l1InfoTreeExitRootChanged, oldIMStateRoot, f.wipL2Block.imStateRoot, f.logZKCounters(f.wipL2Block.usedZKCounters), f.logZKCounters(f.wipL2Block.reservedZKCounters)) } // executeNewWIPL2Block executes an empty L2 Block in the executor and returns the batch response from the executor @@ -579,16 +608,25 @@ func (f *finalizer) dumpL2Block(l2Block *L2Block) { } } - txsLog := "" + sLog := "" + for i, tx := range l2Block.transactions { + sLog += fmt.Sprintf(" tx[%d] hash: %s, from: %s, nonce: %d, gas: %d, gasPrice: %d, bytes: %d, egpPct: %d, used counters: %s, reserved counters: %s\n", + i, tx.HashStr, tx.FromStr, tx.Nonce, tx.Gas, tx.GasPrice, tx.Bytes, tx.EGPPercentage, f.logZKCounters(tx.UsedZKCounters), f.logZKCounters(tx.ReservedZKCounters)) + } + log.Infof("DUMP L2 block [%d], timestamp: %d, deltaTimestamp: %d, imStateRoot: %s, l1InfoTreeIndex: %d, bytes: %d, used counters: %s, reserved counters: %s\n%s", + l2Block.trackingNum, l2Block.timestamp, l2Block.deltaTimestamp, l2Block.imStateRoot, l2Block.l1InfoTreeExitRoot.L1InfoTreeIndex, l2Block.bytes, + f.logZKCounters(l2Block.usedZKCounters), f.logZKCounters(l2Block.reservedZKCounters), sLog) + + sLog = "" if blockResp != nil { for i, txResp := range blockResp.TransactionResponses { - txsLog += fmt.Sprintf(" tx[%d] Hash: %s, HashL2: %s, StateRoot: %s, Type: %d, GasLeft: %d, GasUsed: %d, GasRefund: %d, CreateAddress: %s, ChangesStateRoot: %v, EGP: %s, EGPPct: %d, HasGaspriceOpcode: %v, HasBalanceOpcode: %v\n", + sLog += fmt.Sprintf(" tx[%d] hash: %s, hashL2: %s, stateRoot: %s, type: %d, gasLeft: %d, gasUsed: %d, gasRefund: %d, createAddress: %s, changesStateRoot: %v, egp: %s, egpPct: %d, hasGaspriceOpcode: %v, hasBalanceOpcode: %v\n", i, txResp.TxHash, txResp.TxHashL2_V2, txResp.StateRoot, txResp.Type, txResp.GasLeft, txResp.GasUsed, txResp.GasRefunded, txResp.CreateAddress, txResp.ChangesStateRoot, txResp.EffectiveGasPrice, txResp.EffectivePercentage, txResp.HasGaspriceOpcode, txResp.HasBalanceOpcode) } - log.Infof("DUMP L2 block %d [%d], Timestamp: %d, ParentHash: %s, Coinbase: %s, GER: %s, BlockHashL1: %s, GasUsed: %d, BlockInfoRoot: %s, BlockHash: %s\n%s", + log.Infof("DUMP L2 block %d [%d] response, timestamp: %d, parentHash: %s, coinbase: %s, ger: %s, blockHashL1: %s, gasUsed: %d, blockInfoRoot: %s, blockHash: %s, used counters: %s, reserved counters: %s\n%s", blockResp.BlockNumber, l2Block.trackingNum, blockResp.Timestamp, blockResp.ParentHash, blockResp.Coinbase, blockResp.GlobalExitRoot, blockResp.BlockHashL1, - blockResp.GasUsed, blockResp.BlockInfoRoot, blockResp.BlockHash, txsLog) + blockResp.GasUsed, blockResp.BlockInfoRoot, blockResp.BlockHash, f.logZKCounters(l2Block.batchResponse.UsedZkCounters), f.logZKCounters(l2Block.batchResponse.ReservedZkCounters), sLog) } } diff --git a/sequencer/mock_worker.go b/sequencer/mock_worker.go index 628037dfd2..215cd08c8e 100644 --- a/sequencer/mock_worker.go +++ b/sequencer/mock_worker.go @@ -125,9 +125,9 @@ func (_m *WorkerMock) MoveTxToNotReady(txHash common.Hash, from common.Address, return r0 } -// NewTxTracker provides a mock function with given fields: tx, counters, ip -func (_m *WorkerMock) NewTxTracker(tx types.Transaction, counters state.ZKCounters, ip string) (*TxTracker, error) { - ret := _m.Called(tx, counters, ip) +// NewTxTracker provides a mock function with given fields: tx, usedZKcounters, reservedZKCouners, ip +func (_m *WorkerMock) NewTxTracker(tx types.Transaction, usedZKcounters state.ZKCounters, reservedZKCouners state.ZKCounters, ip string) (*TxTracker, error) { + ret := _m.Called(tx, usedZKcounters, reservedZKCouners, ip) if len(ret) == 0 { panic("no return value specified for NewTxTracker") @@ -135,19 +135,19 @@ func (_m *WorkerMock) NewTxTracker(tx types.Transaction, counters state.ZKCounte var r0 *TxTracker var r1 error - if rf, ok := ret.Get(0).(func(types.Transaction, state.ZKCounters, string) (*TxTracker, error)); ok { - return rf(tx, counters, ip) + if rf, ok := ret.Get(0).(func(types.Transaction, state.ZKCounters, state.ZKCounters, string) (*TxTracker, error)); ok { + return rf(tx, usedZKcounters, reservedZKCouners, ip) } - if rf, ok := ret.Get(0).(func(types.Transaction, state.ZKCounters, string) *TxTracker); ok { - r0 = rf(tx, counters, ip) + if rf, ok := ret.Get(0).(func(types.Transaction, state.ZKCounters, state.ZKCounters, string) *TxTracker); ok { + r0 = rf(tx, usedZKcounters, reservedZKCouners, ip) } else { if ret.Get(0) != nil { r0 = ret.Get(0).(*TxTracker) } } - if rf, ok := ret.Get(1).(func(types.Transaction, state.ZKCounters, string) error); ok { - r1 = rf(tx, counters, ip) + if rf, ok := ret.Get(1).(func(types.Transaction, state.ZKCounters, state.ZKCounters, string) error); ok { + r1 = rf(tx, usedZKcounters, reservedZKCouners, ip) } else { r1 = ret.Error(1) } @@ -175,9 +175,9 @@ func (_m *WorkerMock) UpdateAfterSingleSuccessfulTxExecution(from common.Address return r0 } -// UpdateTxZKCounters provides a mock function with given fields: txHash, from, ZKCounters -func (_m *WorkerMock) UpdateTxZKCounters(txHash common.Hash, from common.Address, ZKCounters state.ZKCounters) { - _m.Called(txHash, from, ZKCounters) +// UpdateTxZKCounters provides a mock function with given fields: txHash, from, usedZKCounters, reservedZKCounters +func (_m *WorkerMock) UpdateTxZKCounters(txHash common.Hash, from common.Address, usedZKCounters state.ZKCounters, reservedZKCounters state.ZKCounters) { + _m.Called(txHash, from, usedZKCounters, reservedZKCounters) } // NewWorkerMock creates a new instance of WorkerMock. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. diff --git a/sequencer/sequencer.go b/sequencer/sequencer.go index 95b9794dcd..d53dab0c7d 100644 --- a/sequencer/sequencer.go +++ b/sequencer/sequencer.go @@ -211,7 +211,7 @@ func (s *Sequencer) loadFromPool(ctx context.Context) { } func (s *Sequencer) addTxToWorker(ctx context.Context, tx pool.Transaction) error { - txTracker, err := s.worker.NewTxTracker(tx.Transaction, tx.ZKCounters, tx.IP) + txTracker, err := s.worker.NewTxTracker(tx.Transaction, tx.ZKCounters, tx.ReservedZKCounters, tx.IP) if err != nil { return err } diff --git a/sequencer/txtracker.go b/sequencer/txtracker.go index 4f85ef947f..bf280d036e 100644 --- a/sequencer/txtracker.go +++ b/sequencer/txtracker.go @@ -11,29 +11,31 @@ import ( // TxTracker is a struct that contains all the tx data needed to be managed by the worker type TxTracker struct { - Hash common.Hash - HashStr string - From common.Address - FromStr string - Nonce uint64 - Gas uint64 // To check if it fits into a batch - GasPrice *big.Int - Cost *big.Int // Cost = Amount + Benefit - BatchResources state.BatchResources // To check if it fits into a batch - RawTx []byte - ReceivedAt time.Time // To check if it has been in the txSortedList for too long - IP string // IP of the tx sender - FailedReason *string // FailedReason is the reason why the tx failed, if it failed - EffectiveGasPrice *big.Int - EGPPercentage byte - IsLastExecution bool - EGPLog state.EffectiveGasPriceLog - L1GasPrice uint64 - L2GasPrice uint64 + Hash common.Hash + HashStr string + From common.Address + FromStr string + Nonce uint64 + Gas uint64 // To check if it fits into a batch + GasPrice *big.Int + Cost *big.Int // Cost = Amount + Benefit + Bytes uint64 + UsedZKCounters state.ZKCounters + ReservedZKCounters state.ZKCounters + RawTx []byte + ReceivedAt time.Time // To check if it has been in the txSortedList for too long + IP string // IP of the tx sender + FailedReason *string // FailedReason is the reason why the tx failed, if it failed + EffectiveGasPrice *big.Int + EGPPercentage byte + IsLastExecution bool + EGPLog state.EffectiveGasPriceLog + L1GasPrice uint64 + L2GasPrice uint64 } // newTxTracker creates and inti a TxTracker -func newTxTracker(tx types.Transaction, counters state.ZKCounters, ip string) (*TxTracker, error) { +func newTxTracker(tx types.Transaction, usedZKCounters state.ZKCounters, reservedZKCounters state.ZKCounters, ip string) (*TxTracker, error) { addr, err := state.GetSender(tx) if err != nil { return nil, err @@ -45,22 +47,21 @@ func newTxTracker(tx types.Transaction, counters state.ZKCounters, ip string) (* } txTracker := &TxTracker{ - Hash: tx.Hash(), - HashStr: tx.Hash().String(), - From: addr, - FromStr: addr.String(), - Nonce: tx.Nonce(), - Gas: tx.Gas(), - GasPrice: tx.GasPrice(), - Cost: tx.Cost(), - BatchResources: state.BatchResources{ - Bytes: uint64(len(rawTx)) + state.EfficiencyPercentageByteLength, - UsedZKCounters: counters, - }, - RawTx: rawTx, - ReceivedAt: time.Now(), - IP: ip, - EffectiveGasPrice: new(big.Int).SetUint64(0), + Hash: tx.Hash(), + HashStr: tx.Hash().String(), + From: addr, + FromStr: addr.String(), + Nonce: tx.Nonce(), + Gas: tx.Gas(), + GasPrice: tx.GasPrice(), + Cost: tx.Cost(), + Bytes: uint64(len(rawTx)) + state.EfficiencyPercentageByteLength, + UsedZKCounters: usedZKCounters, + ReservedZKCounters: reservedZKCounters, + RawTx: rawTx, + ReceivedAt: time.Now(), + IP: ip, + EffectiveGasPrice: new(big.Int).SetUint64(0), EGPLog: state.EffectiveGasPriceLog{ ValueFinal: new(big.Int).SetUint64(0), ValueFirst: new(big.Int).SetUint64(0), @@ -74,7 +75,8 @@ func newTxTracker(tx types.Transaction, counters state.ZKCounters, ip string) (* return txTracker, nil } -// updateZKCounters updates the counters of the tx -func (tx *TxTracker) updateZKCounters(counters state.ZKCounters) { - tx.BatchResources.UsedZKCounters = counters +// updateZKCounters updates the used and reserved ZKCounters of the tx +func (tx *TxTracker) updateZKCounters(usedZKCounters state.ZKCounters, reservedZKCounters state.ZKCounters) { + tx.UsedZKCounters = usedZKCounters + tx.ReservedZKCounters = reservedZKCounters } diff --git a/sequencer/worker.go b/sequencer/worker.go index 919fe50132..d068788bf5 100644 --- a/sequencer/worker.go +++ b/sequencer/worker.go @@ -37,8 +37,8 @@ func NewWorker(state stateInterface, constraints state.BatchConstraintsCfg) *Wor } // NewTxTracker creates and inits a TxTracker -func (w *Worker) NewTxTracker(tx types.Transaction, counters state.ZKCounters, ip string) (*TxTracker, error) { - return newTxTracker(tx, counters, ip) +func (w *Worker) NewTxTracker(tx types.Transaction, usedZKCounters state.ZKCounters, reservedZKCounters state.ZKCounters, ip string) (*TxTracker, error) { + return newTxTracker(tx, usedZKCounters, reservedZKCounters, ip) } // AddTxTracker adds a new Tx to the Worker @@ -51,8 +51,8 @@ func (w *Worker) AddTxTracker(ctx context.Context, tx *TxTracker) (replacedTx *T return nil, pool.ErrInvalidIP } - // Make sure the transaction's batch resources are within the constraints. - if !w.batchConstraints.IsWithinConstraints(tx.BatchResources.UsedZKCounters) { + // Make sure the transaction's reserved ZKCounters are within the constraints. + if !w.batchConstraints.IsWithinConstraints(tx.ReservedZKCounters) { log.Errorf("outOfCounters error (node level) for tx %s", tx.Hash.String()) w.workerMutex.Unlock() return nil, pool.ErrOutOfCounters @@ -219,25 +219,26 @@ func (w *Worker) DeleteForcedTx(txHash common.Hash, addr common.Address) { } // UpdateTxZKCounters updates the ZKCounter of a tx -func (w *Worker) UpdateTxZKCounters(txHash common.Hash, addr common.Address, counters state.ZKCounters) { +func (w *Worker) UpdateTxZKCounters(txHash common.Hash, addr common.Address, usedZKCounters state.ZKCounters, reservedZKCounters state.ZKCounters) { w.workerMutex.Lock() defer w.workerMutex.Unlock() log.Infof("update ZK counters for tx %s addr %s", txHash.String(), addr.String()) - log.Debugf("counters.CumulativeGasUsed: %d", counters.GasUsed) - log.Debugf("counters.UsedKeccakHashes: %d", counters.KeccakHashes) - log.Debugf("counters.UsedPoseidonHashes: %d", counters.PoseidonHashes) - log.Debugf("counters.UsedPoseidonPaddings: %d", counters.PoseidonPaddings) - log.Debugf("counters.UsedMemAligns: %d", counters.MemAligns) - log.Debugf("counters.UsedArithmetics: %d", counters.Arithmetics) - log.Debugf("counters.UsedBinaries: %d", counters.Binaries) - log.Debugf("counters.UsedSteps: %d", counters.Steps) - log.Debugf("counters.UsedSha256Hashes_V2: %d", counters.Sha256Hashes_V2) + // TODO: log in a single line, log also reserved resources + log.Debugf("counters.CumulativeGasUsed: %d", usedZKCounters.GasUsed) + log.Debugf("counters.UsedKeccakHashes: %d", usedZKCounters.KeccakHashes) + log.Debugf("counters.UsedPoseidonHashes: %d", usedZKCounters.PoseidonHashes) + log.Debugf("counters.UsedPoseidonPaddings: %d", usedZKCounters.PoseidonPaddings) + log.Debugf("counters.UsedMemAligns: %d", usedZKCounters.MemAligns) + log.Debugf("counters.UsedArithmetics: %d", usedZKCounters.Arithmetics) + log.Debugf("counters.UsedBinaries: %d", usedZKCounters.Binaries) + log.Debugf("counters.UsedSteps: %d", usedZKCounters.Steps) + log.Debugf("counters.UsedSha256Hashes_V2: %d", usedZKCounters.Sha256Hashes_V2) addrQueue, found := w.pool[addr.String()] if found { - addrQueue.UpdateTxZKCounters(txHash, counters) + addrQueue.UpdateTxZKCounters(txHash, usedZKCounters, reservedZKCounters) } else { log.Warnf("addrQueue %s not found", addr.String()) } @@ -318,7 +319,7 @@ func (w *Worker) GetBestFittingTx(resources state.BatchResources) (*TxTracker, e foundMutex.RUnlock() txCandidate := w.txSortedList.getByIndex(i) - overflow, _ := bresources.Sub(txCandidate.BatchResources) + overflow, _ := bresources.Sub(state.BatchResources{ZKCounters: txCandidate.ReservedZKCounters, Bytes: txCandidate.Bytes}) if overflow { // We don't add this Tx continue diff --git a/sequencer/worker_test.go b/sequencer/worker_test.go index 0acbe9c798..688576fa7b 100644 --- a/sequencer/worker_test.go +++ b/sequencer/worker_test.go @@ -37,7 +37,7 @@ type workerAddTxTestCase struct { txHash common.Hash nonce uint64 cost *big.Int - counters state.ZKCounters + reservedZKCounters state.ZKCounters usedBytes uint64 gasPrice *big.Int expectedTxSortedList []common.Hash @@ -62,9 +62,9 @@ func processWorkerAddTxTestCases(ctx context.Context, t *testing.T, worker *Work tx.FromStr = testCase.from.String() tx.Nonce = testCase.nonce tx.Cost = testCase.cost - tx.BatchResources.Bytes = testCase.usedBytes + tx.Bytes = testCase.usedBytes tx.GasPrice = testCase.gasPrice - tx.updateZKCounters(testCase.counters) + tx.updateZKCounters(testCase.reservedZKCounters, testCase.reservedZKCounters) if testCase.ip == "" { // A random valid IP Address tx.IP = validIP @@ -118,7 +118,6 @@ func TestWorkerAddTx(t *testing.T) { { name: "Adding from:0x01, tx:0x01/gp:10", from: common.Address{1}, txHash: common.Hash{1}, nonce: 1, gasPrice: new(big.Int).SetInt64(10), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 1}, usedBytes: 1, expectedTxSortedList: []common.Hash{ {1}, @@ -127,25 +126,22 @@ func TestWorkerAddTx(t *testing.T) { { name: "Adding from:0x02, tx:0x02/gp:4", from: common.Address{2}, txHash: common.Hash{2}, nonce: 1, gasPrice: new(big.Int).SetInt64(4), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 1}, usedBytes: 1, expectedTxSortedList: []common.Hash{ {1}, {2}, }, }, { - name: "Readding from:0x02, tx:0x02/gp:20", from: common.Address{2}, txHash: common.Hash{2}, nonce: 1, gasPrice: new(big.Int).SetInt64(20), + name: "Adding from:0x02, tx:0x02/gp:20", from: common.Address{2}, txHash: common.Hash{2}, nonce: 1, gasPrice: new(big.Int).SetInt64(20), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 5, KeccakHashes: 5, PoseidonHashes: 5, PoseidonPaddings: 5, MemAligns: 5, Arithmetics: 5, Binaries: 5, Steps: 5, Sha256Hashes_V2: 5}, usedBytes: 5, expectedTxSortedList: []common.Hash{ {2}, {1}, }, }, { - name: "Readding from:0x03, tx:0x03/gp:25", from: common.Address{3}, txHash: common.Hash{3}, nonce: 1, gasPrice: new(big.Int).SetInt64(25), + name: "Adding from:0x03, tx:0x03/gp:25", from: common.Address{3}, txHash: common.Hash{3}, nonce: 1, gasPrice: new(big.Int).SetInt64(25), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 2, KeccakHashes: 2, PoseidonHashes: 2, PoseidonPaddings: 2, MemAligns: 2, Arithmetics: 2, Binaries: 2, Steps: 2, Sha256Hashes_V2: 2}, usedBytes: 2, expectedTxSortedList: []common.Hash{ {3}, {2}, {1}, @@ -153,7 +149,6 @@ func TestWorkerAddTx(t *testing.T) { }, { name: "Invalid IP address", from: common.Address{5}, txHash: common.Hash{5}, nonce: 1, - counters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 2}, usedBytes: 1, ip: "invalid IP", expectedErr: pool.ErrInvalidIP, @@ -162,8 +157,8 @@ func TestWorkerAddTx(t *testing.T) { name: "Out Of Counters Err", from: common.Address{5}, txHash: common.Hash{5}, nonce: 1, cost: new(big.Int).SetInt64(5), - // Here, we intentionally set the counters such that they violate the constraints - counters: state.ZKCounters{ + // Here, we intentionally set the reserved counters such that they violate the constraints + reservedZKCounters: state.ZKCounters{ GasUsed: worker.batchConstraints.MaxCumulativeGasUsed + 1, KeccakHashes: worker.batchConstraints.MaxKeccakHashes + 1, PoseidonHashes: worker.batchConstraints.MaxPoseidonHashes + 1, @@ -180,7 +175,6 @@ func TestWorkerAddTx(t *testing.T) { { name: "Adding from:0x04, tx:0x04/gp:100", from: common.Address{4}, txHash: common.Hash{4}, nonce: 1, gasPrice: new(big.Int).SetInt64(100), cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 1}, usedBytes: 1, expectedTxSortedList: []common.Hash{ {4}, {3}, {2}, {1}, @@ -195,8 +189,8 @@ func TestWorkerGetBestTx(t *testing.T) { var nilErr error rc := state.BatchResources{ - UsedZKCounters: state.ZKCounters{GasUsed: 10, KeccakHashes: 10, PoseidonHashes: 10, PoseidonPaddings: 10, MemAligns: 10, Arithmetics: 10, Binaries: 10, Steps: 10, Sha256Hashes_V2: 10}, - Bytes: 10, + ZKCounters: state.ZKCounters{GasUsed: 10, KeccakHashes: 10, PoseidonHashes: 10, PoseidonPaddings: 10, MemAligns: 10, Arithmetics: 10, Binaries: 10, Steps: 10, Sha256Hashes_V2: 10}, + Bytes: 10, } stateMock := NewStateMock(t) @@ -221,36 +215,36 @@ func TestWorkerGetBestTx(t *testing.T) { addTxsTC := []workerAddTxTestCase{ { name: "Adding from:0x01, tx:0x01/gp:10", from: common.Address{1}, txHash: common.Hash{1}, nonce: 1, gasPrice: new(big.Int).SetInt64(10), - cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 1}, - usedBytes: 1, + cost: new(big.Int).SetInt64(5), + reservedZKCounters: state.ZKCounters{GasUsed: 1, KeccakHashes: 1, PoseidonHashes: 1, PoseidonPaddings: 1, MemAligns: 1, Arithmetics: 1, Binaries: 1, Steps: 1, Sha256Hashes_V2: 1}, + usedBytes: 1, expectedTxSortedList: []common.Hash{ {1}, }, }, { name: "Adding from:0x02, tx:0x02/gp:12", from: common.Address{2}, txHash: common.Hash{2}, nonce: 1, gasPrice: new(big.Int).SetInt64(12), - cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 5, KeccakHashes: 5, PoseidonHashes: 5, PoseidonPaddings: 5, MemAligns: 5, Arithmetics: 5, Binaries: 5, Steps: 5, Sha256Hashes_V2: 5}, - usedBytes: 5, + cost: new(big.Int).SetInt64(5), + reservedZKCounters: state.ZKCounters{GasUsed: 5, KeccakHashes: 5, PoseidonHashes: 5, PoseidonPaddings: 5, MemAligns: 5, Arithmetics: 5, Binaries: 5, Steps: 5, Sha256Hashes_V2: 5}, + usedBytes: 5, expectedTxSortedList: []common.Hash{ {2}, {1}, }, }, { name: "Readding from:0x03, tx:0x03/gp:25", from: common.Address{3}, txHash: common.Hash{3}, nonce: 1, gasPrice: new(big.Int).SetInt64(25), - cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 2, KeccakHashes: 2, PoseidonHashes: 2, PoseidonPaddings: 2, MemAligns: 2, Arithmetics: 2, Binaries: 2, Steps: 2, Sha256Hashes_V2: 2}, - usedBytes: 2, + cost: new(big.Int).SetInt64(5), + reservedZKCounters: state.ZKCounters{GasUsed: 2, KeccakHashes: 2, PoseidonHashes: 2, PoseidonPaddings: 2, MemAligns: 2, Arithmetics: 2, Binaries: 2, Steps: 2, Sha256Hashes_V2: 2}, + usedBytes: 2, expectedTxSortedList: []common.Hash{ {3}, {2}, {1}, }, }, { name: "Adding from:0x04, tx:0x04/gp:100", from: common.Address{4}, txHash: common.Hash{4}, nonce: 1, gasPrice: new(big.Int).SetInt64(100), - cost: new(big.Int).SetInt64(5), - counters: state.ZKCounters{GasUsed: 4, KeccakHashes: 4, PoseidonHashes: 4, PoseidonPaddings: 4, MemAligns: 4, Arithmetics: 4, Binaries: 4, Steps: 4, Sha256Hashes_V2: 4}, - usedBytes: 4, + cost: new(big.Int).SetInt64(5), + reservedZKCounters: state.ZKCounters{GasUsed: 4, KeccakHashes: 4, PoseidonHashes: 4, PoseidonPaddings: 4, MemAligns: 4, Arithmetics: 4, Binaries: 4, Steps: 4, Sha256Hashes_V2: 4}, + usedBytes: 4, expectedTxSortedList: []common.Hash{ {4}, {3}, {2}, {1}, }, @@ -271,7 +265,7 @@ func TestWorkerGetBestTx(t *testing.T) { if tx.HashStr != expectedGetBestTx[ct].String() { t.Fatalf("Error GetBestFittingTx(%d). Expected=%s, Actual=%s", ct, expectedGetBestTx[ct].String(), tx.HashStr) } - overflow, _ := rc.Sub(tx.BatchResources) + overflow, _ := rc.Sub(state.BatchResources{ZKCounters: tx.ReservedZKCounters, Bytes: tx.Bytes}) assert.Equal(t, false, overflow) touch := make(map[common.Address]*state.InfoReadWrite) diff --git a/state/pgstatestorage/pgstatestorage_test.go b/state/pgstatestorage/pgstatestorage_test.go index 3433619603..8c0b553514 100644 --- a/state/pgstatestorage/pgstatestorage_test.go +++ b/state/pgstatestorage/pgstatestorage_test.go @@ -55,7 +55,7 @@ var ( mtDBServiceClient hashdb.HashDBServiceClient executorClientConn, mtDBClientConn *grpc.ClientConn batchResources = state.BatchResources{ - UsedZKCounters: state.ZKCounters{ + ZKCounters: state.ZKCounters{ KeccakHashes: 1, }, Bytes: 1, diff --git a/state/types.go b/state/types.go index d5c0da1c3a..ea7a0ae289 100644 --- a/state/types.go +++ b/state/types.go @@ -180,9 +180,41 @@ func (z *ZKCounters) SumUp(other ZKCounters) { z.Sha256Hashes_V2 += other.Sha256Hashes_V2 } -// Sub subtract zk counters with passed zk counters (not safe). if there is a counter underflow it returns true and the name of the counter that caused the overflow +// Fits checks if other zk counters fits in the zk counters. if there is a counter underflow it returns false and the name of the counter that caused the underflow +func (z *ZKCounters) Fits(other ZKCounters) (bool, string) { + if other.GasUsed > z.GasUsed { + return false, "CumulativeGas" + } + if other.KeccakHashes > z.KeccakHashes { + return false, "KeccakHashes" + } + if other.PoseidonHashes > z.PoseidonHashes { + return false, "PoseidonHashes" + } + if other.PoseidonPaddings > z.PoseidonPaddings { + return false, "PoseidonPaddings" + } + if other.MemAligns > z.MemAligns { + return false, "UsedMemAligns" + } + if other.Arithmetics > z.Arithmetics { + return false, "UsedArithmetics" + } + if other.Binaries > z.Binaries { + return false, "UsedBinaries" + } + if other.Steps > z.Steps { + return false, "UsedSteps" + } + if other.Sha256Hashes_V2 > z.Sha256Hashes_V2 { + return false, "UsedSha256Hashes_V2" + } + + return true, "" +} + +// Sub subtract zk counters with passed zk counters (not safe). if there is a counter underflow it returns true and the name of the counter that caused the underflow func (z *ZKCounters) Sub(other ZKCounters) (bool, string) { - // ZKCounters if other.GasUsed > z.GasUsed { return true, "CumulativeGas" } @@ -224,21 +256,28 @@ func (z *ZKCounters) Sub(other ZKCounters) (bool, string) { return false, "" } -// BatchResources is a struct that contains the ZKEVM resources used by a batch/tx +// BatchResources is a struct that contains the limited resources of a batch type BatchResources struct { - UsedZKCounters ZKCounters - Bytes uint64 + ZKCounters ZKCounters + Bytes uint64 +} + +// Fits check if the other batch resources fit in the batch resources. If there is a resource underflow it returns false and the name of the resource that caused the overflow +func (r *BatchResources) Fits(other BatchResources) (bool, string) { + if other.Bytes > r.Bytes { + return false, "Bytes" + } + return r.ZKCounters.Fits(other.ZKCounters) } -// Sub subtracts the batch resources from other. if there is a resource underflow it returns true and the name of the resource that caused the overflow +// Sub subtracts the batch resources from "other". If there is a resource overflow it returns true and the name of the resource that caused the overflow func (r *BatchResources) Sub(other BatchResources) (bool, string) { - // Bytes if other.Bytes > r.Bytes { return true, "Bytes" } bytesBackup := r.Bytes r.Bytes -= other.Bytes - exhausted, resourceName := r.UsedZKCounters.Sub(other.UsedZKCounters) + exhausted, resourceName := r.ZKCounters.Sub(other.ZKCounters) if exhausted { r.Bytes = bytesBackup return exhausted, resourceName @@ -250,7 +289,7 @@ func (r *BatchResources) Sub(other BatchResources) (bool, string) { // SumUp sum ups the batch resources from other func (r *BatchResources) SumUp(other BatchResources) { r.Bytes += other.Bytes - r.UsedZKCounters.SumUp(other.UsedZKCounters) + r.ZKCounters.SumUp(other.ZKCounters) } // InfoReadWrite has information about modified addresses during the execution diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 2b006678cb..f9c8ef62bd 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:v5.0.0-RC5 + image: hermeznetwork/zkevm-prover:v5.0.0-RC8 ports: - 50061:50061 # MT - 50071:50071 # Executor @@ -602,7 +602,7 @@ services: zkevm-permissionless-prover: container_name: zkevm-permissionless-prover - image: hermeznetwork/zkevm-prover:v5.0.0-RC5 + image: hermeznetwork/zkevm-prover:v5.0.0-RC8 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover From 6aacee4cdc0e0cfa2cc8db18dd7f268a32662f62 Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Fri, 23 Feb 2024 12:39:07 +0100 Subject: [PATCH 27/51] fix return on node OOC. Fix logs (#3359) --- event/event.go | 2 ++ sequencer/finalizer.go | 16 +++++++++++----- sequencer/l2block.go | 4 +--- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/event/event.go b/event/event.go index 7c325cc242..f43502df67 100644 --- a/event/event.go +++ b/event/event.go @@ -44,6 +44,8 @@ const ( EventID_SequenceSenderHalt EventID = "SEQUENCESENDER HALT" // EventID_NodeOOC is triggered when an OOC at node level is detected EventID_NodeOOC EventID = "NODE OOC" + // EventID_UsedZKCountersOverflow is triggered when used ZK counters exceeds remaining batch ZK counters + EventID_UsedZKCountersOverflow EventID = "USED ZKCOUNTERS OVERFLOW" // EventID_ReservedZKCountersOverflow is triggered when reserved ZK counters exceeds remaining batch ZK counters EventID_ReservedZKCountersOverflow EventID = "RESERVED ZKCOUNTERS OVERFLOW" // Source_Node is the source of the event diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index 4a96c421c9..e2ea879ab0 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -528,20 +528,24 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx subOverflow := false fits, overflowResource := f.wipBatch.imRemainingResources.Fits(state.BatchResources{ZKCounters: result.ReservedZkCounters, Bytes: uint64(len(tx.RawTx))}) if fits { - // Sustract the used resources from the batch + // Subtract the used resources from the batch subOverflow, overflowResource = f.wipBatch.imRemainingResources.Sub(state.BatchResources{ZKCounters: result.UsedZkCounters, Bytes: uint64(len(tx.RawTx))}) if subOverflow { // Sanity check, this cannot happen as reservedZKCounters should be >= that usedZKCounters - log.Infof("current tx %s used resources exceeds the remaining batch resources, overflow resource: %s, updating metadata for tx in worker and continuing. Batch counters: %s, tx used counters: %s", + sLog := fmt.Sprintf("tx %s used resources exceeds the remaining batch resources, overflow resource: %s, updating metadata for tx in worker and continuing. Batch counters: %s, tx used counters: %s", tx.HashStr, overflowResource, f.logZKCounters(f.wipBatch.imRemainingResources.ZKCounters), f.logZKCounters(result.UsedZkCounters)) + + log.Errorf(sLog) + + f.LogEvent(ctx, event.Level_Error, event.EventID_UsedZKCountersOverflow, sLog, nil) } } else { log.Infof("current tx %s reserved resources exceeds the remaining batch resources, overflow resource: %s, updating metadata for tx in worker and continuing. Batch counters: %s, tx reserved counters: %s", tx.HashStr, overflowResource, f.logZKCounters(f.wipBatch.imRemainingResources.ZKCounters), f.logZKCounters(result.ReservedZkCounters)) if !f.batchConstraints.IsWithinConstraints(result.ReservedZkCounters) { - log.Warnf("current tx %s reserved resources exceeds the max limit for batch resources (node OOC), setting tx as invalid in the pool", tx.HashStr) + log.Infof("current tx %s reserved resources exceeds the max limit for batch resources (node OOC), setting tx as invalid in the pool", tx.HashStr) - f.LogEvent(ctx, event.Level_Error, event.EventID_NodeOOC, - fmt.Sprintf("tx: %s exceeds node max limit batch resources (node OOC), from: %s, IP: %s", tx.HashStr, tx.FromStr, tx.IP), nil) + f.LogEvent(ctx, event.Level_Info, event.EventID_NodeOOC, + fmt.Sprintf("tx %s exceeds node max limit batch resources (node OOC), from: %s, IP: %s", tx.HashStr, tx.FromStr, tx.IP), nil) // Delete the transaction from the txSorted list f.workerIntf.DeleteTx(tx.Hash, tx.From) @@ -551,6 +555,8 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx if err != nil { log.Errorf("failed to update status to invalid in the pool for tx %s, error: %v", tx.Hash.String(), err) } + + return nil, ErrBatchResourceOverFlow } } diff --git a/sequencer/l2block.go b/sequencer/l2block.go index 8c81932fd2..498d48b193 100644 --- a/sequencer/l2block.go +++ b/sequencer/l2block.go @@ -112,7 +112,6 @@ func (f *finalizer) processPendingL2Blocks(ctx context.Context) { } err := f.processL2Block(ctx, l2Block) - f.dumpL2Block(l2Block) if err != nil { // Dump L2Block info @@ -143,7 +142,6 @@ func (f *finalizer) storePendingL2Blocks(ctx context.Context) { } err := f.storeL2Block(ctx, l2Block) - f.dumpL2Block(l2Block) if err != nil { // Dump L2Block info @@ -206,7 +204,7 @@ func (f *finalizer) processL2Block(ctx context.Context, l2Block *L2Block) error if fits { subOverflow, overflowResource := f.wipBatch.finalRemainingResources.Sub(state.BatchResources{ZKCounters: batchResponse.UsedZkCounters, Bytes: batchL2DataSize}) if subOverflow { // Sanity check, this cannot happen as reservedZKCounters should be >= that usedZKCounters - return fmt.Errorf("error sustracting L2 block %d [%d] used resources from the batch %d, overflow resource: %s, batch counters: %s, L2 block used counters: %s, batch bytes: %d, L2 block bytes: %d", + return fmt.Errorf("error subtracting L2 block %d [%d] used resources from the batch %d, overflow resource: %s, batch counters: %s, L2 block used counters: %s, batch bytes: %d, L2 block bytes: %d", blockResponse.BlockNumber, l2Block.trackingNum, f.wipBatch.batchNumber, overflowResource, f.logZKCounters(f.wipBatch.finalRemainingResources.ZKCounters), f.logZKCounters(batchResponse.UsedZkCounters), f.wipBatch.finalRemainingResources.Bytes, batchL2DataSize) } } else { From 54b7fcd0c9882213e4f6e318a595c6b173fff0b4 Mon Sep 17 00:00:00 2001 From: Joan Esteban <129153821+joanestebanr@users.noreply.github.com> Date: Fri, 23 Feb 2024 16:09:01 +0100 Subject: [PATCH 28/51] to decode ETROG processBatches use ETROG contract (#3360) * decode old ETROG processBatches use ETROG contract * fix sanity genesis --- etherman/etherman.go | 2 +- synchronizer/synchronizer.go | 7 ++----- 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/etherman/etherman.go b/etherman/etherman.go index 1994cf96ef..78af7040d6 100644 --- a/etherman/etherman.go +++ b/etherman/etherman.go @@ -1365,7 +1365,7 @@ func decodeSequencesElderberry(txData []byte, lastBatchNumber uint64, sequencer func decodeSequencesEtrog(txData []byte, lastBatchNumber uint64, sequencer common.Address, txHash common.Hash, nonce uint64, l1InfoRoot common.Hash) ([]SequencedBatch, error) { // Extract coded txs. // Load contract ABI - smcAbi, err := abi.JSON(strings.NewReader(polygonzkevm.PolygonzkevmABI)) + smcAbi, err := abi.JSON(strings.NewReader(etrogpolygonzkevm.EtrogpolygonzkevmABI)) if err != nil { return nil, err } diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index ac7554282d..6e49c064b5 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -419,7 +419,7 @@ func (s *ClientSynchronizer) RequestAndProcessRollupGenesisBlock(dbTx pgx.Tx, la } func sanityCheckForGenesisBlockRollupInfo(blocks []etherman.Block, order map[common.Hash][]etherman.Order) error { - if len(blocks) != 1 || len(order) != 1 || len(order[blocks[0].BlockHash]) != 2 { + if len(blocks) != 1 || len(order) < 1 || len(order[blocks[0].BlockHash]) < 1 { log.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected 1 block with 2 orders") return fmt.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected 1 block with 2 orders") } @@ -427,10 +427,7 @@ func sanityCheckForGenesisBlockRollupInfo(blocks []etherman.Block, order map[com log.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected ForkIDsOrder, got %s", order[blocks[0].BlockHash][0].Name) return fmt.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected ForkIDsOrder") } - if order[blocks[0].BlockHash][1].Name != etherman.InitialSequenceBatchesOrder { - log.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected InitialSequenceBatchesOrder, got %s", order[blocks[0].BlockHash][0].Name) - return fmt.Errorf("error getting rollupInfoByBlockRange after set the genesis. Expected InitialSequenceBatchesOrder") - } + return nil } From f08d4134e64475737b4769a782be7dca590604a7 Mon Sep 17 00:00:00 2001 From: Joan Esteban <129153821+joanestebanr@users.noreply.github.com> Date: Mon, 26 Feb 2024 11:44:56 +0100 Subject: [PATCH 29/51] Synchronized inform field state.batch.closing_reason from DB * Add reasons to the field `state.batch.closing_reason` (issue #3243) --- state/batch.go | 17 +++++++++++++++ state/batchV2.go | 2 ++ state/convertersV2.go | 1 + state/genesis.go | 2 +- state/interfaces.go | 2 +- state/mocks/mock_storage.go | 21 ++++++++++--------- state/pgstatestorage/batch.go | 5 +++-- .../etrog/processor_l1_sequence_batches.go | 3 +++ .../processor_l1_update_etrog_sequence.go | 1 + .../executor_trusted_batch_sync.go | 1 + 10 files changed, 41 insertions(+), 14 deletions(-) diff --git a/state/batch.go b/state/batch.go index 601a2e6b16..09b329ee5f 100644 --- a/state/batch.go +++ b/state/batch.go @@ -60,6 +60,7 @@ type ProcessingContext struct { GlobalExitRoot common.Hash ForcedBatchNum *uint64 BatchL2Data *[]byte + ClosingReason ClosingReason } // ClosingReason represents the reason why a batch is closed. @@ -82,6 +83,22 @@ const ( MaxDeltaTimestampClosingReason ClosingReason = "Max delta timestamp" // NoTxFitsClosingReason is the closing reason used when any of the txs in the pool (worker) fits in the remaining resources of the batch NoTxFitsClosingReason ClosingReason = "No transaction fits" + + // Reason due Synchronizer + // ------------------------------------------------------------------------------------------ + + // SyncL1EventInitialBatchClosingReason is the closing reason used when a batch is closed by the synchronizer due to an initial batch (first batch mode forced) + SyncL1EventInitialBatchClosingReason ClosingReason = "Sync L1: initial" + // SyncL1EventSequencedBatchClosingReason is the closing reason used when a batch is closed by the synchronizer due to a sequenced batch event from L1 + SyncL1EventSequencedBatchClosingReason ClosingReason = "Sync L1: sequenced" + // SyncL1EventSequencedForcedBatchClosingReason is the closing reason used when a batch is closed by the synchronizer due to a sequenced forced batch event from L1 + SyncL1EventSequencedForcedBatchClosingReason ClosingReason = "Sync L1: forced" + // SyncL1EventUpdateEtrogSequenceClosingReason is the closing reason used when a batch is closed by the synchronizer due to an UpdateEtrogSequence event from L1 that inject txs + SyncL1EventUpdateEtrogSequenceClosingReason ClosingReason = "Sync L1: injected" + // SyncL2TrustedBatchClosingReason is the closing reason used when a batch is closed by the synchronizer due to a trusted batch from L2 + SyncL2TrustedBatchClosingReason ClosingReason = "Sync L2: trusted" + // SyncGenesisBatchClosingReason is the closing reason used when genesis batch is created by synchronizer + SyncGenesisBatchClosingReason ClosingReason = "Sync: genesis" ) // ProcessingReceipt indicates the outcome (StateRoot, AccInputHash) of processing a batch diff --git a/state/batchV2.go b/state/batchV2.go index 4f8108c5b9..d12ae209c7 100644 --- a/state/batchV2.go +++ b/state/batchV2.go @@ -34,6 +34,7 @@ type ProcessingContextV2 struct { SkipVerifyL1InfoRoot uint32 GlobalExitRoot common.Hash // GlobalExitRoot is not use for execute but use to OpenBatch (data on DB) ExecutionMode uint64 + ClosingReason ClosingReason } // ProcessBatchV2 processes a batch for forkID >= ETROG @@ -415,5 +416,6 @@ func (s *State) ProcessAndStoreClosedBatchV2(ctx context.Context, processingCtx LocalExitRoot: processedBatch.NewLocalExitRoot, AccInputHash: processedBatch.NewAccInputHash, BatchL2Data: *BatchL2Data, + ClosingReason: processingCtx.ClosingReason, }, dbTx) } diff --git a/state/convertersV2.go b/state/convertersV2.go index d2e6274497..c68d33db48 100644 --- a/state/convertersV2.go +++ b/state/convertersV2.go @@ -370,6 +370,7 @@ func convertProcessingContext(p *ProcessingContextV2) (*ProcessingContext, error BatchL2Data: p.BatchL2Data, Timestamp: tstamp, GlobalExitRoot: p.GlobalExitRoot, + ClosingReason: p.ClosingReason, } return &result, nil } diff --git a/state/genesis.go b/state/genesis.go index 52cbb35812..111a5d626b 100644 --- a/state/genesis.go +++ b/state/genesis.go @@ -146,7 +146,7 @@ func (s *State) SetGenesis(ctx context.Context, block Block, genesis Genesis, m ForcedBatchNum: nil, } - err = s.StoreGenesisBatch(ctx, batch, dbTx) + err = s.StoreGenesisBatch(ctx, batch, string(SyncGenesisBatchClosingReason), dbTx) if err != nil { return common.Hash{}, err } diff --git a/state/interfaces.go b/state/interfaces.go index 0f658e14a5..daa38906fd 100644 --- a/state/interfaces.go +++ b/state/interfaces.go @@ -15,7 +15,7 @@ type storage interface { Query(ctx context.Context, sql string, args ...interface{}) (pgx.Rows, error) QueryRow(ctx context.Context, sql string, args ...interface{}) pgx.Row Begin(ctx context.Context) (pgx.Tx, error) - StoreGenesisBatch(ctx context.Context, batch Batch, dbTx pgx.Tx) error + StoreGenesisBatch(ctx context.Context, batch Batch, closingReason string, dbTx pgx.Tx) error ResetToL1BlockNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) error ResetForkID(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error ResetTrustedState(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) error diff --git a/state/mocks/mock_storage.go b/state/mocks/mock_storage.go index a8881340ea..a2d06980c1 100644 --- a/state/mocks/mock_storage.go +++ b/state/mocks/mock_storage.go @@ -8004,17 +8004,17 @@ func (_c *StorageMock_SetLastBatchInfoSeenOnEthereum_Call) RunAndReturn(run func return _c } -// StoreGenesisBatch provides a mock function with given fields: ctx, batch, dbTx -func (_m *StorageMock) StoreGenesisBatch(ctx context.Context, batch state.Batch, dbTx pgx.Tx) error { - ret := _m.Called(ctx, batch, dbTx) +// StoreGenesisBatch provides a mock function with given fields: ctx, batch, closingReason, dbTx +func (_m *StorageMock) StoreGenesisBatch(ctx context.Context, batch state.Batch, closingReason string, dbTx pgx.Tx) error { + ret := _m.Called(ctx, batch, closingReason, dbTx) if len(ret) == 0 { panic("no return value specified for StoreGenesisBatch") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, state.Batch, pgx.Tx) error); ok { - r0 = rf(ctx, batch, dbTx) + if rf, ok := ret.Get(0).(func(context.Context, state.Batch, string, pgx.Tx) error); ok { + r0 = rf(ctx, batch, closingReason, dbTx) } else { r0 = ret.Error(0) } @@ -8030,14 +8030,15 @@ type StorageMock_StoreGenesisBatch_Call struct { // StoreGenesisBatch is a helper method to define mock.On call // - ctx context.Context // - batch state.Batch +// - closingReason string // - dbTx pgx.Tx -func (_e *StorageMock_Expecter) StoreGenesisBatch(ctx interface{}, batch interface{}, dbTx interface{}) *StorageMock_StoreGenesisBatch_Call { - return &StorageMock_StoreGenesisBatch_Call{Call: _e.mock.On("StoreGenesisBatch", ctx, batch, dbTx)} +func (_e *StorageMock_Expecter) StoreGenesisBatch(ctx interface{}, batch interface{}, closingReason interface{}, dbTx interface{}) *StorageMock_StoreGenesisBatch_Call { + return &StorageMock_StoreGenesisBatch_Call{Call: _e.mock.On("StoreGenesisBatch", ctx, batch, closingReason, dbTx)} } -func (_c *StorageMock_StoreGenesisBatch_Call) Run(run func(ctx context.Context, batch state.Batch, dbTx pgx.Tx)) *StorageMock_StoreGenesisBatch_Call { +func (_c *StorageMock_StoreGenesisBatch_Call) Run(run func(ctx context.Context, batch state.Batch, closingReason string, dbTx pgx.Tx)) *StorageMock_StoreGenesisBatch_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(state.Batch), args[2].(pgx.Tx)) + run(args[0].(context.Context), args[1].(state.Batch), args[2].(string), args[3].(pgx.Tx)) }) return _c } @@ -8047,7 +8048,7 @@ func (_c *StorageMock_StoreGenesisBatch_Call) Return(_a0 error) *StorageMock_Sto return _c } -func (_c *StorageMock_StoreGenesisBatch_Call) RunAndReturn(run func(context.Context, state.Batch, pgx.Tx) error) *StorageMock_StoreGenesisBatch_Call { +func (_c *StorageMock_StoreGenesisBatch_Call) RunAndReturn(run func(context.Context, state.Batch, string, pgx.Tx) error) *StorageMock_StoreGenesisBatch_Call { _c.Call.Return(run) return _c } diff --git a/state/pgstatestorage/batch.go b/state/pgstatestorage/batch.go index 83bfad3cdb..5b1d1f57fd 100644 --- a/state/pgstatestorage/batch.go +++ b/state/pgstatestorage/batch.go @@ -558,8 +558,8 @@ func (p *PostgresStorage) GetVirtualBatch(ctx context.Context, batchNumber uint6 return &virtualBatch, nil } -func (p *PostgresStorage) StoreGenesisBatch(ctx context.Context, batch state.Batch, dbTx pgx.Tx) error { - const addGenesisBatchSQL = "INSERT INTO state.batch (batch_num, global_exit_root, local_exit_root, acc_input_hash, state_root, timestamp, coinbase, raw_txs_data, forced_batch_num, wip) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, FALSE)" +func (p *PostgresStorage) StoreGenesisBatch(ctx context.Context, batch state.Batch, closingReason string, dbTx pgx.Tx) error { + const addGenesisBatchSQL = "INSERT INTO state.batch (batch_num, global_exit_root, local_exit_root, acc_input_hash, state_root, timestamp, coinbase, raw_txs_data, forced_batch_num,closing_reason, wip) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9,$10, FALSE)" if batch.BatchNumber != 0 { return fmt.Errorf("%w. Got %d, should be 0", state.ErrUnexpectedBatch, batch.BatchNumber) @@ -577,6 +577,7 @@ func (p *PostgresStorage) StoreGenesisBatch(ctx context.Context, batch state.Bat batch.Coinbase.String(), batch.BatchL2Data, batch.ForcedBatchNum, + closingReason, ) return err diff --git a/synchronizer/actions/etrog/processor_l1_sequence_batches.go b/synchronizer/actions/etrog/processor_l1_sequence_batches.go index 0411661d27..ba91be9a13 100644 --- a/synchronizer/actions/etrog/processor_l1_sequence_batches.go +++ b/synchronizer/actions/etrog/processor_l1_sequence_batches.go @@ -157,6 +157,7 @@ func (p *ProcessorL1SequenceBatchesEtrog) ProcessSequenceBatches(ctx context.Con ForcedBlockHashL1: forcedBlockHashL1, SkipVerifyL1InfoRoot: 1, ExecutionMode: executor.ExecutionMode1, + ClosingReason: state.SyncL1EventSequencedForcedBatchClosingReason, } } else if sbatch.PolygonRollupBaseEtrogBatchData.ForcedTimestamp > 0 && sbatch.BatchNumber == 1 { log.Debug("Processing initial batch") @@ -174,6 +175,7 @@ func (p *ProcessorL1SequenceBatchesEtrog) ProcessSequenceBatches(ctx context.Con ForcedBlockHashL1: forcedBlockHashL1, SkipVerifyL1InfoRoot: 1, ExecutionMode: executor.ExecutionMode1, + ClosingReason: state.SyncL1EventInitialBatchClosingReason, } } else { var maxGER common.Hash @@ -199,6 +201,7 @@ func (p *ProcessorL1SequenceBatchesEtrog) ProcessSequenceBatches(ctx context.Con SkipVerifyL1InfoRoot: 1, GlobalExitRoot: batch.GlobalExitRoot, ExecutionMode: executor.ExecutionMode1, + ClosingReason: state.SyncL1EventSequencedBatchClosingReason, } if batch.GlobalExitRoot == (common.Hash{}) { if len(leaves) > 0 { diff --git a/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go b/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go index fc1e2b4a27..166f030b4e 100644 --- a/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go +++ b/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go @@ -85,6 +85,7 @@ func (g *ProcessorL1UpdateEtrogSequence) processUpdateEtrogSequence(ctx context. SkipVerifyL1InfoRoot: 1, GlobalExitRoot: updateEtrogSequence.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot, ExecutionMode: executor.ExecutionMode1, + ClosingReason: state.SyncL1EventUpdateEtrogSequenceClosingReason, } virtualBatch := state.VirtualBatch{ diff --git a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go index c428a1e886..73f6fa247a 100644 --- a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go +++ b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go @@ -324,6 +324,7 @@ func (b *SyncTrustedBatchExecutorForEtrog) CloseBatch(ctx context.Context, trust LocalExitRoot: trustedBatch.LocalExitRoot, BatchL2Data: trustedBatch.BatchL2Data, AccInputHash: trustedBatch.AccInputHash, + ClosingReason: state.SyncL2TrustedBatchClosingReason, } log.Debugf("%s closing batch %v", debugStr, trustedBatch.Number) // This update SET state_root = $1, local_exit_root = $2, acc_input_hash = $3, raw_txs_data = $4, batch_resources = $5, closing_reason = $6, wip = FALSE From 92f191d85a248bf22b19bc7e907c3aefb4309825 Mon Sep 17 00:00:00 2001 From: Thiago Coimbra Lemos Date: Mon, 26 Feb 2024 09:31:11 -0300 Subject: [PATCH 30/51] remove unnecessary eventlog call when processing unsigned txs (#3365) --- state/transaction.go | 1 - 1 file changed, 1 deletion(-) diff --git a/state/transaction.go b/state/transaction.go index 122a6a6611..71ce4cd2e3 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -604,7 +604,6 @@ func (s *State) internalProcessUnsignedTransactionV2(ctx context.Context, tx *ty if processBatchResponseV2.ErrorRom != executor.RomError_ROM_ERROR_NO_ERROR { err = executor.RomErr(processBatchResponseV2.ErrorRom) - s.eventLog.LogExecutorErrorV2(ctx, processBatchResponseV2.Error, processBatchRequestV2) if executor.IsROMOutOfCountersError(executor.RomErrorCode(err)) { return response, err } From 3ab6d44ab247c9079479ff685b1030dd15ac2b93 Mon Sep 17 00:00:00 2001 From: Thiago Coimbra Lemos Date: Tue, 27 Feb 2024 09:50:56 -0300 Subject: [PATCH 31/51] Fix batch 0 timestamp (#3364) --- state/genesis.go | 5 ++ state/pgstatestorage/forkid.go | 8 ++++ state/test/forkid_dragonfruit/genesis_test.go | 35 ++++++++++++++ state/test/forkid_etrog/genesis_test.go | 48 +++++++++++++++++++ .../forkid_independent/independent_test.go | 46 ++++++++++++++++++ 5 files changed, 142 insertions(+) create mode 100644 state/test/forkid_etrog/genesis_test.go diff --git a/state/genesis.go b/state/genesis.go index 111a5d626b..41c2424c56 100644 --- a/state/genesis.go +++ b/state/genesis.go @@ -158,6 +158,11 @@ func (s *State) SetGenesis(ctx context.Context, block Block, genesis Genesis, m Coinbase: ZeroAddress, BlockNumber: block.BlockNumber, } + forkID := s.GetForkIDByBatchNumber(0) + if forkID >= FORKID_ETROG { + virtualBatch.TimestampBatchEtrog = &block.ReceivedAt + } + err = s.AddVirtualBatch(ctx, virtualBatch, dbTx) if err != nil { return common.Hash{}, err diff --git a/state/pgstatestorage/forkid.go b/state/pgstatestorage/forkid.go index 5b7cecda3f..f31fc26f14 100644 --- a/state/pgstatestorage/forkid.go +++ b/state/pgstatestorage/forkid.go @@ -158,6 +158,10 @@ func sortIndexForForkdIDSortedByBlockNumber(forkIDs []state.ForkIDInterval) []in // GetForkIDByBatchNumber returns the fork id for a given batch number func (p *PostgresStorage) GetForkIDByBatchNumber(batchNumber uint64) uint64 { + if batchNumber == 0 { + batchNumber = 1 + } + if p.cfg.AvoidForkIDInMemory { const query = ` SELECT fork_id FROM state.fork_id @@ -196,6 +200,10 @@ func (p *PostgresStorage) GetForkIDByBatchNumber(batchNumber uint64) uint64 { // GetForkIDByBatchNumberInMemory returns the fork id for a given batch number func (p *PostgresStorage) GetForkIDByBatchNumberInMemory(batchNumber uint64) uint64 { + if batchNumber == 0 { + batchNumber = 1 + } + // If NumBatchForkIdUpgrade is defined (!=0) we are performing forkid upgrade process // In this case, if the batchNumber is the next to the NumBatchForkIdUpgrade, we need to return the // new "future" forkId (ForkUpgradeNewForkId) diff --git a/state/test/forkid_dragonfruit/genesis_test.go b/state/test/forkid_dragonfruit/genesis_test.go index a3b97fd94d..27e5842d69 100644 --- a/state/test/forkid_dragonfruit/genesis_test.go +++ b/state/test/forkid_dragonfruit/genesis_test.go @@ -9,7 +9,9 @@ import ( "path" "runtime" "testing" + "time" + "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/state" "github.com/0xPolygonHermez/zkevm-node/state/metrics" test "github.com/0xPolygonHermez/zkevm-node/state/test/forkid_common" @@ -101,3 +103,36 @@ func genesisCase(t *testing.T, tv genesisTestVectorReader) { actualRoot, _ := big.NewInt(0).SetString(genesisRoot.String()[2:], 16) assert.Equal(t, expectedRoot, actualRoot) } + +func TestGenesisTimestamp(t *testing.T) { + ctx := context.Background() + genesis := state.Genesis{} + + err := dbutils.InitOrResetState(test.StateDBCfg) + require.NoError(t, err) + + dbTx, err := testState.BeginStateTransaction(ctx) + require.NoError(t, err) + + timeStamp := time.Now() + block := state.Block{ReceivedAt: timeStamp} + + _, err = testState.SetGenesis(ctx, block, genesis, metrics.SynchronizerCallerLabel, dbTx) + require.NoError(t, err) + + err = dbTx.Commit(ctx) + require.NoError(t, err) + + batchTimeStamp, err := testState.GetBatchTimestamp(ctx, 0, nil, nil) + require.NoError(t, err) + + log.Debugf("timeStamp: %v", timeStamp) + log.Debugf("batchTimeStamp: %v", *batchTimeStamp) + + dateFormat := "2006-01-02 15:04:05.000000Z" + + log.Debugf("timeStamp: %v", timeStamp.Format(dateFormat)) + log.Debugf("batchTimeStamp: %v", (*batchTimeStamp).Format(dateFormat)) + + assert.Equal(t, timeStamp.Format(dateFormat), (*batchTimeStamp).Format(dateFormat)) +} diff --git a/state/test/forkid_etrog/genesis_test.go b/state/test/forkid_etrog/genesis_test.go new file mode 100644 index 0000000000..543a2564b4 --- /dev/null +++ b/state/test/forkid_etrog/genesis_test.go @@ -0,0 +1,48 @@ +package etrog_test + +import ( + "context" + "testing" + "time" + + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/0xPolygonHermez/zkevm-node/state" + "github.com/0xPolygonHermez/zkevm-node/state/metrics" + test "github.com/0xPolygonHermez/zkevm-node/state/test/forkid_common" + "github.com/0xPolygonHermez/zkevm-node/test/dbutils" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestGenesisTimestamp(t *testing.T) { + ctx := context.Background() + genesis := state.Genesis{} + + err := dbutils.InitOrResetState(test.StateDBCfg) + require.NoError(t, err) + + dbTx, err := testState.BeginStateTransaction(ctx) + require.NoError(t, err) + + timeStamp := time.Now() + block := state.Block{ReceivedAt: timeStamp} + + _, err = testState.SetGenesis(ctx, block, genesis, metrics.SynchronizerCallerLabel, dbTx) + require.NoError(t, err) + + err = dbTx.Commit(ctx) + require.NoError(t, err) + + batchTimeStamp, err := testState.GetBatchTimestamp(ctx, 0, nil, nil) + require.NoError(t, err) + + log.Debugf("timeStamp: %v", timeStamp) + log.Debugf("batchTimeStamp: %v", *batchTimeStamp) + + dateFormat := "2006-01-02 15:04:05.000000Z" + + log.Debugf("timeStamp: %v", timeStamp.Format(dateFormat)) + log.Debugf("batchTimeStamp: %v", (*batchTimeStamp).Format(dateFormat)) + + assert.Equal(t, timeStamp.Format(dateFormat), (*batchTimeStamp).Format(dateFormat)) +} diff --git a/state/test/forkid_independent/independent_test.go b/state/test/forkid_independent/independent_test.go index 7b2eb0bdf1..b24d0e3021 100644 --- a/state/test/forkid_independent/independent_test.go +++ b/state/test/forkid_independent/independent_test.go @@ -756,3 +756,49 @@ func TestGenesis(t *testing.T) { err = testState.GetTree().Flush(ctx, stateRoot, "") require.NoError(t, err) } + +func TestGetForkIDforGenesisBatch(t *testing.T) { + type testCase struct { + name string + cfg state.Config + expectedForkID uint64 + } + + testCases := []testCase{ + { + name: "fork ID for batch 0 is defined", + cfg: state.Config{ + ForkIDIntervals: []state.ForkIDInterval{ + {ForkId: 2, FromBatchNumber: 0, ToBatchNumber: 10}, + {ForkId: 4, FromBatchNumber: 11, ToBatchNumber: 20}, + {ForkId: 6, FromBatchNumber: 21, ToBatchNumber: math.MaxUint64}, + }, + }, + expectedForkID: 2, + }, + { + name: "fork ID for batch 0 is NOT defined", + cfg: state.Config{ + ForkIDIntervals: []state.ForkIDInterval{ + {ForkId: 7, FromBatchNumber: 1, ToBatchNumber: 10}, + {ForkId: 8, FromBatchNumber: 11, ToBatchNumber: 20}, + {ForkId: 9, FromBatchNumber: 21, ToBatchNumber: math.MaxUint64}, + }, + }, + expectedForkID: 7, + }, + } + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + test.InitOrResetDB(test.StateDBCfg) + + st := test.InitTestState(testCase.cfg) + + forkID := st.GetForkIDByBatchNumber(0) + assert.Equal(t, testCase.expectedForkID, forkID) + + test.CloseTestState() + }) + } +} From 2b70cceb904c07820e41918c37c53ecb1a2f60f8 Mon Sep 17 00:00:00 2001 From: Joan Esteban <129153821+joanestebanr@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:07:05 +0100 Subject: [PATCH 32/51] ignore forkid events from another rollup (#3383) --- etherman/etherman.go | 24 +++++++++--------------- 1 file changed, 9 insertions(+), 15 deletions(-) diff --git a/etherman/etherman.go b/etherman/etherman.go index 78af7040d6..4b8a78a59d 100644 --- a/etherman/etherman.go +++ b/etherman/etherman.go @@ -642,7 +642,7 @@ func (etherMan *Client) updateZkevmVersion(ctx context.Context, vLog types.Log, log.Error("error parsing UpdateZkEVMVersion event. Error: ", err) return err } - return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, zkevmVersion.NumBatch, zkevmVersion.ForkID, zkevmVersion.Version) + return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, zkevmVersion.NumBatch, zkevmVersion.ForkID, zkevmVersion.Version, etherMan.RollupID) } func (etherMan *Client) updateRollup(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error { @@ -656,7 +656,7 @@ func (etherMan *Client) updateRollup(ctx context.Context, vLog types.Log, blocks if err != nil { return err } - return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, updateRollup.LastVerifiedBatchBeforeUpgrade, rollupType.ForkID, "") + return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, updateRollup.LastVerifiedBatchBeforeUpgrade, rollupType.ForkID, "", updateRollup.RollupID) } func (etherMan *Client) createNewRollup(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error { @@ -670,7 +670,7 @@ func (etherMan *Client) createNewRollup(ctx context.Context, vLog types.Log, blo if err != nil { return err } - return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, 0, rollupType.ForkID, "") + return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, 0, rollupType.ForkID, "", createRollup.RollupID) } func (etherMan *Client) addExistingRollup(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error { @@ -680,18 +680,8 @@ func (etherMan *Client) addExistingRollup(ctx context.Context, vLog types.Log, b log.Error("error parsing createNewRollup event. Error: ", err) return err } - if etherMan.RollupID != addExistingRollup.RollupID { - return nil - } - // TODO Delete after upgrade Get RollupID - rollupID, err := etherMan.RollupManager.RollupAddressToID(&bind.CallOpts{Pending: false}, etherMan.SCAddresses[0]) - if err != nil { - log.Error("error getting rollupID. Error: ", err) - return err - } - log.Debug("rollupID: ", rollupID) - return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, addExistingRollup.LastVerifiedBatchBeforeUpgrade, addExistingRollup.ForkID, "") + return etherMan.updateForkId(ctx, vLog, blocks, blocksOrder, addExistingRollup.LastVerifiedBatchBeforeUpgrade, addExistingRollup.ForkID, "", addExistingRollup.RollupID) } func (etherMan *Client) updateEtrogSequence(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order) error { @@ -808,7 +798,11 @@ func (etherMan *Client) initialSequenceBatches(ctx context.Context, vLog types.L (*blocksOrder)[(*blocks)[len(*blocks)-1].BlockHash] = append((*blocksOrder)[(*blocks)[len(*blocks)-1].BlockHash], or) return nil } -func (etherMan *Client) updateForkId(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order, batchNum, forkID uint64, version string) error { +func (etherMan *Client) updateForkId(ctx context.Context, vLog types.Log, blocks *[]Block, blocksOrder *map[common.Hash][]Order, batchNum, forkID uint64, version string, affectedRollupID uint32) error { + if etherMan.RollupID != affectedRollupID { + log.Debug("ignoring this event because it is related to another rollup %d, we are rollupID %d", affectedRollupID, etherMan.RollupID) + return nil + } fork := ForkID{ BatchNumber: batchNum, ForkID: forkID, From cd4c30c3c7cb376782fea3a19a10c89c9bf91888 Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Tue, 27 Feb 2024 16:47:35 +0100 Subject: [PATCH 33/51] Add l2block/interval metrics. Use timeoutCond when waiting for worker readyTxs (#3380) --- config/config_test.go | 8 + config/default.go | 3 + .../environments/local/local.node.config.toml | 3 + docs/config-file/node-config-doc.html | 4 +- docs/config-file/node-config-doc.md | 51 +++ docs/config-file/node-config-schema.json | 22 ++ sequencer/batch.go | 14 +- sequencer/config.go | 12 + sequencer/finalizer.go | 55 ++- sequencer/finalizer_test.go | 2 +- sequencer/forcedbatch.go | 2 +- sequencer/l2block.go | 36 +- sequencer/metrics.go | 159 ++++++++ sequencer/metrics/metrics.go | 153 -------- sequencer/sequencer.go | 17 +- sequencer/timeoutCond.go | 63 ++++ sequencer/worker.go | 18 +- sequencer/worker_test.go | 3 +- sequencesender/sequencesender.go | 3 - .../sequencer/common/metrics/metrics.go | 193 ---------- .../sequencer/common/params/constants.go | 16 - .../sequencer/common/params/variables.go | 30 -- .../sequencer/common/setup/setup.go | 150 -------- .../common/transactions/transactions.go | 117 ------ .../e2e/erc20-transfers/deployment.go | 43 --- .../e2e/erc20-transfers/erc20_test.go | 80 ---- .../e2e/erc20-transfers/tx_sender.go | 47 --- .../sequencer/e2e/eth-transfers/eth_test.go | 69 ---- .../sequencer/e2e/eth-transfers/tx_sender.go | 56 --- .../e2e/uniswap-transfers/tx_sender.go | 44 --- .../e2e/uniswap-transfers/uniswap_test.go | 66 ---- .../benchmarks/sequencer/scripts/.env.example | 17 - test/benchmarks/sequencer/scripts/README.md | 51 --- .../scripts/environment/constants.go | 26 -- .../sequencer/scripts/environment/init.go | 81 ---- .../sequencer/scripts/erc20-transfers/main.go | 57 --- .../sequencer/scripts/eth-transfers/main.go | 52 --- test/benchmarks/sequencer/scripts/main.go | 348 ------------------ .../scripts/uniswap-transfers/main.go | 61 --- test/config/debug.node.config.toml | 3 + test/config/test.node.config.toml | 3 + 41 files changed, 411 insertions(+), 1827 deletions(-) create mode 100644 sequencer/metrics.go delete mode 100644 sequencer/metrics/metrics.go create mode 100644 sequencer/timeoutCond.go delete mode 100644 test/benchmarks/sequencer/common/metrics/metrics.go delete mode 100644 test/benchmarks/sequencer/common/params/constants.go delete mode 100644 test/benchmarks/sequencer/common/params/variables.go delete mode 100644 test/benchmarks/sequencer/common/setup/setup.go delete mode 100644 test/benchmarks/sequencer/common/transactions/transactions.go delete mode 100644 test/benchmarks/sequencer/e2e/erc20-transfers/deployment.go delete mode 100644 test/benchmarks/sequencer/e2e/erc20-transfers/erc20_test.go delete mode 100644 test/benchmarks/sequencer/e2e/erc20-transfers/tx_sender.go delete mode 100644 test/benchmarks/sequencer/e2e/eth-transfers/eth_test.go delete mode 100644 test/benchmarks/sequencer/e2e/eth-transfers/tx_sender.go delete mode 100644 test/benchmarks/sequencer/e2e/uniswap-transfers/tx_sender.go delete mode 100644 test/benchmarks/sequencer/e2e/uniswap-transfers/uniswap_test.go delete mode 100644 test/benchmarks/sequencer/scripts/.env.example delete mode 100644 test/benchmarks/sequencer/scripts/README.md delete mode 100644 test/benchmarks/sequencer/scripts/environment/constants.go delete mode 100644 test/benchmarks/sequencer/scripts/environment/init.go delete mode 100644 test/benchmarks/sequencer/scripts/erc20-transfers/main.go delete mode 100644 test/benchmarks/sequencer/scripts/eth-transfers/main.go delete mode 100644 test/benchmarks/sequencer/scripts/main.go delete mode 100644 test/benchmarks/sequencer/scripts/uniswap-transfers/main.go diff --git a/config/config_test.go b/config/config_test.go index 2efaaf0616..6cd4ad0863 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -116,6 +116,14 @@ func Test_Defaults(t *testing.T) { path: "Sequencer.Finalizer.BatchMaxDeltaTimestamp", expectedValue: types.NewDuration(10 * time.Second), }, + { + path: "Sequencer.Finalizer.Metrics.Interval", + expectedValue: types.NewDuration(60 * time.Minute), + }, + { + path: "Sequencer.Finalizer.Metrics.EnableLog", + expectedValue: true, + }, { path: "Sequencer.StreamServer.Port", expectedValue: uint16(0), diff --git a/config/default.go b/config/default.go index 4bca8b1c9a..8aaa092969 100644 --- a/config/default.go +++ b/config/default.go @@ -137,6 +137,9 @@ StateConsistencyCheckInterval = "5s" HaltOnBatchNumber = 0 SequentialBatchSanityCheck = false SequentialProcessL2Block = true + [Sequencer.Finalizer.Metrics] + Interval = "60m" + EnableLog = true [Sequencer.StreamServer] Port = 0 Filename = "" diff --git a/config/environments/local/local.node.config.toml b/config/environments/local/local.node.config.toml index 9fefe6362b..c637c12997 100644 --- a/config/environments/local/local.node.config.toml +++ b/config/environments/local/local.node.config.toml @@ -103,6 +103,9 @@ StateConsistencyCheckInterval = "5s" HaltOnBatchNumber = 0 SequentialBatchSanityCheck = false SequentialProcessL2Block = true + [Sequencer.Finalizer.Metrics] + Interval = "60m" + EnableLog = true [Sequencer.StreamServer] Port = 0 Filename = "" diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index 3fcf675c97..6adbe3cac5 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -50,7 +50,9 @@
"300ms"
 

Default: "3s"Type: string

L2BlockMaxDeltaTimestamp is the resolution of the timestamp used to close a L2 block


Examples:

"1m"
 
"300ms"
-

Default: 0Type: integer

HaltOnBatchNumber specifies the batch number where the Sequencer will stop to process more transactions and generate new batches.
The Sequencer will halt after it closes the batch equal to this number


Default: falseType: boolean

SequentialBatchSanityCheck indicates if the reprocess of a closed batch (sanity check) must be done in a
sequential way (instead than in parallel)


Default: trueType: boolean

SequentialProcessL2Block indicates if the processing of a L2 Block must be done in the same finalizer go func instead
in the processPendingL2Blocks go func


StreamServerCfg is the config for the stream server
Default: 0Type: integer

Port to listen on


Default: ""Type: string

Filename of the binary data file


Default: 0Type: integer

Version of the binary data file


Default: 0Type: integer

ChainID is the chain ID


Default: falseType: boolean

Enabled is a flag to enable/disable the data streamer


Log is the log configuration
Default: ""Type: enum (of string)

Must be one of:

  • "production"
  • "development"

Default: ""Type: enum (of string)

Must be one of:

  • "debug"
  • "info"
  • "warn"
  • "error"
  • "dpanic"
  • "panic"
  • "fatal"

Type: array of string

Each item of this array must be:


Default: 0Type: integer

UpgradeEtrogBatchNumber is the batch number of the upgrade etrog


Configuration of the sequence sender service
Default: "5s"Type: string

WaitPeriodSendSequence is the time the sequencer waits until
trying to send a sequence to L1


Examples:

"1m"
+

Default: 0Type: integer

HaltOnBatchNumber specifies the batch number where the Sequencer will stop to process more transactions and generate new batches.
The Sequencer will halt after it closes the batch equal to this number


Default: falseType: boolean

SequentialBatchSanityCheck indicates if the reprocess of a closed batch (sanity check) must be done in a
sequential way (instead than in parallel)


Default: trueType: boolean

SequentialProcessL2Block indicates if the processing of a L2 Block must be done in the same finalizer go func instead
in the processPendingL2Blocks go func


Metrics is the config for the sequencer metrics
Default: "1h0m0s"Type: string

Interval is the interval of time to calculate sequencer metrics


Examples:

"1m"
+
"300ms"
+

Default: trueType: boolean

EnableLog is a flag to enable/disable metrics logs


StreamServerCfg is the config for the stream server
Default: 0Type: integer

Port to listen on


Default: ""Type: string

Filename of the binary data file


Default: 0Type: integer

Version of the binary data file


Default: 0Type: integer

ChainID is the chain ID


Default: falseType: boolean

Enabled is a flag to enable/disable the data streamer


Log is the log configuration
Default: ""Type: enum (of string)

Must be one of:

  • "production"
  • "development"

Default: ""Type: enum (of string)

Must be one of:

  • "debug"
  • "info"
  • "warn"
  • "error"
  • "dpanic"
  • "panic"
  • "fatal"

Type: array of string

Each item of this array must be:


Default: 0Type: integer

UpgradeEtrogBatchNumber is the batch number of the upgrade etrog


Configuration of the sequence sender service
Default: "5s"Type: string

WaitPeriodSendSequence is the time the sequencer waits until
trying to send a sequence to L1


Examples:

"1m"
 
"300ms"
 

Default: "5s"Type: string

LastBatchVirtualizationTimeMaxWaitPeriod is time since sequences should be sent


Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index 484f48e913..e92f404f2f 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -1856,6 +1856,7 @@ StateConsistencyCheckInterval="5s"
 | - [HaltOnBatchNumber](#Sequencer_Finalizer_HaltOnBatchNumber )                                 | No      | integer | No         | -          | HaltOnBatchNumber specifies the batch number where the Sequencer will stop to process more transactions and generate new batches.
The Sequencer will halt after it closes the batch equal to this number | | - [SequentialBatchSanityCheck](#Sequencer_Finalizer_SequentialBatchSanityCheck ) | No | boolean | No | - | SequentialBatchSanityCheck indicates if the reprocess of a closed batch (sanity check) must be done in a
sequential way (instead than in parallel) | | - [SequentialProcessL2Block](#Sequencer_Finalizer_SequentialProcessL2Block ) | No | boolean | No | - | SequentialProcessL2Block indicates if the processing of a L2 Block must be done in the same finalizer go func instead
in the processPendingL2Blocks go func | +| - [Metrics](#Sequencer_Finalizer_Metrics ) | No | object | No | - | Metrics is the config for the sequencer metrics | #### 10.7.1. `Sequencer.Finalizer.ForcedBatchesTimeout` @@ -2100,6 +2101,56 @@ in the processPendingL2Blocks go func SequentialProcessL2Block=true ``` +#### 10.7.13. `[Sequencer.Finalizer.Metrics]` + +**Type:** : `object` +**Description:** Metrics is the config for the sequencer metrics + +| Property | Pattern | Type | Deprecated | Definition | Title/Description | +| ------------------------------------------------------ | ------- | ------- | ---------- | ---------- | -------------------------------------------------- | +| - [Interval](#Sequencer_Finalizer_Metrics_Interval ) | No | string | No | - | Duration | +| - [EnableLog](#Sequencer_Finalizer_Metrics_EnableLog ) | No | boolean | No | - | EnableLog is a flag to enable/disable metrics logs | + +##### 10.7.13.1. `Sequencer.Finalizer.Metrics.Interval` + +**Title:** Duration + +**Type:** : `string` + +**Default:** `"1h0m0s"` + +**Description:** Interval is the interval of time to calculate sequencer metrics + +**Examples:** + +```json +"1m" +``` + +```json +"300ms" +``` + +**Example setting the default value** ("1h0m0s"): +``` +[Sequencer.Finalizer.Metrics] +Interval="1h0m0s" +``` + +##### 10.7.13.2. `Sequencer.Finalizer.Metrics.EnableLog` + +**Type:** : `boolean` + +**Default:** `true` + +**Description:** EnableLog is a flag to enable/disable metrics logs + +**Example setting the default value** (true): +``` +[Sequencer.Finalizer.Metrics] +EnableLog=true +``` + ### 10.8. `[Sequencer.StreamServer]` **Type:** : `object` diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json index dfdbad179c..6c0adc1261 100644 --- a/docs/config-file/node-config-schema.json +++ b/docs/config-file/node-config-schema.json @@ -778,6 +778,28 @@ "type": "boolean", "description": "SequentialProcessL2Block indicates if the processing of a L2 Block must be done in the same finalizer go func instead\nin the processPendingL2Blocks go func", "default": true + }, + "Metrics": { + "properties": { + "Interval": { + "type": "string", + "title": "Duration", + "description": "Interval is the interval of time to calculate sequencer metrics", + "default": "1h0m0s", + "examples": [ + "1m", + "300ms" + ] + }, + "EnableLog": { + "type": "boolean", + "description": "EnableLog is a flag to enable/disable metrics logs", + "default": true + } + }, + "additionalProperties": false, + "type": "object", + "description": "Metrics is the config for the sequencer metrics" } }, "additionalProperties": false, diff --git a/sequencer/batch.go b/sequencer/batch.go index 00ad8678f6..34d9c870af 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -8,7 +8,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/event" "github.com/0xPolygonHermez/zkevm-node/log" - "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" @@ -145,11 +144,6 @@ func (f *finalizer) initWIPBatch(ctx context.Context) { // finalizeWIPBatch closes the current batch and opens a new one, potentially processing forced batches between the batch is closed and the resulting new empty batch func (f *finalizer) finalizeWIPBatch(ctx context.Context, closeReason state.ClosingReason) { - start := time.Now() - defer func() { - metrics.ProcessingTime(time.Since(start)) - }() - prevTimestamp := f.wipL2Block.timestamp prevL1InfoTreeIndex := f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex @@ -185,7 +179,6 @@ func (f *finalizer) closeAndOpenNewWIPBatch(ctx context.Context, closeReason sta startWait := time.Now() f.pendingL2BlocksToProcessWG.Wait() elapsed := time.Since(startWait) - stateMetrics.ExecutorProcessingTime(string(stateMetrics.SequencerCallerLabel), elapsed) log.Debugf("waiting for pending L2 blocks to be processed took: %v", elapsed) // Wait until all L2 blocks are store @@ -374,11 +367,6 @@ func (f *finalizer) batchSanityCheck(ctx context.Context, batchNum uint64, initi return nil, ErrGetBatchByNumber } - caller := stateMetrics.DiscardCallerLabel - if f.cfg.SequentialBatchSanityCheck { - caller = stateMetrics.SequencerCallerLabel - } - batchRequest := state.ProcessRequest{ BatchNumber: batch.BatchNumber, L1InfoRoot_V2: state.GetMockL1InfoRoot(), @@ -388,7 +376,7 @@ func (f *finalizer) batchSanityCheck(ctx context.Context, batchNum uint64, initi TimestampLimit_V2: uint64(time.Now().Unix()), ForkID: f.stateIntf.GetForkIDByBatchNumber(batch.BatchNumber), SkipVerifyL1InfoRoot_V2: true, - Caller: caller, + Caller: stateMetrics.DiscardCallerLabel, ExecutionMode: executor.ExecutionMode0, } batchRequest.L1InfoTreeData_V2, _, _, err = f.stateIntf.GetL1InfoTreeDataFromBatchL2Data(ctx, batch.BatchL2Data, nil) diff --git a/sequencer/config.go b/sequencer/config.go index f7cb0101bb..45210c4840 100644 --- a/sequencer/config.go +++ b/sequencer/config.go @@ -90,4 +90,16 @@ type FinalizerCfg struct { // SequentialProcessL2Block indicates if the processing of a L2 Block must be done in the same finalizer go func instead // in the processPendingL2Blocks go func SequentialProcessL2Block bool `mapstructure:"SequentialProcessL2Block"` + + // Metrics is the config for the sequencer metrics + Metrics MetricsCfg `mapstructure:"Metrics"` +} + +// MetricsCfg contains the sequencer metrics configuration properties +type MetricsCfg struct { + // Interval is the interval of time to calculate sequencer metrics + Interval types.Duration `mapstructure:"Interval"` + + // EnableLog is a flag to enable/disable metrics logs + EnableLog bool `mapstructure:"EnableLog"` } diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index e2ea879ab0..5da6c9cdef 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -14,7 +14,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/hex" "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/pool" - "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" "github.com/0xPolygonHermez/zkevm-node/state/runtime" @@ -72,6 +71,10 @@ type finalizer struct { storedFlushIDCond *sync.Cond //Condition to wait until storedFlushID has been updated lastPendingFlushID uint64 pendingFlushIDCond *sync.Cond + // worker ready txs condition + workerReadyTxsCond *timeoutCond + // interval metrics + metrics *intervalMetrics // stream server streamServer *datastreamer.StreamServer dataToStream chan interface{} @@ -90,6 +93,7 @@ func newFinalizer( batchConstraints state.BatchConstraintsCfg, eventLog *event.EventLog, streamServer *datastreamer.StreamServer, + workerReadyTxsCond *timeoutCond, dataToStream chan interface{}, ) *finalizer { f := finalizer{ @@ -125,6 +129,10 @@ func newFinalizer( storedFlushIDCond: sync.NewCond(&sync.Mutex{}), lastPendingFlushID: 0, pendingFlushIDCond: sync.NewCond(&sync.Mutex{}), + // worker ready txs condition + workerReadyTxsCond: workerReadyTxsCond, + // metrics + metrics: newIntervalMetrics(cfg.Metrics.Interval.Duration), // stream server streamServer: streamServer, dataToStream: dataToStream, @@ -263,7 +271,6 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { log.Debug("finalizer init loop") showNotFoundTxLog := true // used to log debug only the first message when there is no txs to process for { - start := now() // We have reached the L2 block time, we need to close the current L2 block and open a new one if f.wipL2Block.timestamp+uint64(f.cfg.L2BlockMaxDeltaTimestamp.Seconds()) <= uint64(time.Now().Unix()) { f.finalizeWIPL2Block(ctx) @@ -277,7 +284,6 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { continue } - metrics.WorkerProcessingTime(time.Since(start)) if tx != nil { showNotFoundTxLog = true @@ -302,14 +308,20 @@ func (f *finalizer) finalizeBatches(ctx context.Context) { break } } else { - // wait for new txs + idleTime := time.Now() + if showNotFoundTxLog { log.Debug("no transactions to be processed. Waiting...") showNotFoundTxLog = false } - if f.cfg.NewTxsWaitInterval.Duration > 0 { - time.Sleep(f.cfg.NewTxsWaitInterval.Duration) - } + + // wait for new ready txs in worker + f.workerReadyTxsCond.L.Lock() + f.workerReadyTxsCond.WaitOrTimeout(f.cfg.NewTxsWaitInterval.Duration) + f.workerReadyTxsCond.L.Unlock() + + // Increase idle time of the WIP L2Block + f.wipL2Block.metrics.idleTime += time.Since(idleTime) } if f.haltFinalizer.Load() { @@ -334,9 +346,6 @@ 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) { start := time.Now() - defer func() { - metrics.ProcessingTime(time.Since(start)) - }() log.Infof("processing tx %s, batchNumber: %d, l2Block: [%d], oldStateRoot: %s, L1InfoRootIndex: %d", tx.HashStr, f.wipBatch.batchNumber, f.wipL2Block.trackingNum, f.wipBatch.imStateRoot, f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex) @@ -347,7 +356,7 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first Coinbase: f.wipBatch.coinbase, L1InfoRoot_V2: state.GetMockL1InfoRoot(), TimestampLimit_V2: f.wipL2Block.timestamp, - Caller: stateMetrics.SequencerCallerLabel, + Caller: stateMetrics.DiscardCallerLabel, ForkID: f.stateIntf.GetForkIDByBatchNumber(f.wipBatch.batchNumber), Transactions: tx.RawTx, SkipFirstChangeL2Block_V2: true, @@ -429,7 +438,10 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first batchRequest.Transactions = append(batchRequest.Transactions, effectivePercentageAsDecodedHex...) + executionStart := time.Now() batchResponse, err := f.stateIntf.ProcessBatchV2(ctx, batchRequest, false) + executionTime := time.Since(executionStart) + f.wipL2Block.metrics.transactionsTimes.executor += executionTime 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) @@ -448,8 +460,6 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first 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) - } else { - metrics.TxProcessed(metrics.TxProcessedLabelInvalid, 1) } return nil, err } @@ -465,9 +475,9 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first // Update imStateRoot f.wipBatch.imStateRoot = batchResponse.NewStateRoot - log.Infof("processed tx %s, batchNumber: %d, l2Block: [%d], newStateRoot: %s, oldStateRoot: %s, used counters: %s, reserved counters: %s", + log.Infof("processed tx %s, batchNumber: %d, l2Block: [%d], newStateRoot: %s, oldStateRoot: %s, time: {process: %v, executor: %v}, used counters: %s, reserved counters: %s", tx.HashStr, batchRequest.BatchNumber, f.wipL2Block.trackingNum, batchResponse.NewStateRoot.String(), batchRequest.OldStateRoot.String(), - f.logZKCounters(batchResponse.UsedZkCounters), f.logZKCounters(batchResponse.ReservedZkCounters)) + time.Since(start), executionTime, f.logZKCounters(batchResponse.UsedZkCounters), f.logZKCounters(batchResponse.ReservedZkCounters)) return nil, nil } @@ -563,9 +573,7 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx // If reserved tx resources don't fit in the remaining batch resources (or we got an overflow when trying to subtract the used resources) // we update the ZKCounters of the tx and returns ErrBatchResourceOverFlow error if !fits || subOverflow { - start := time.Now() f.workerIntf.UpdateTxZKCounters(result.BlockResponses[0].TransactionResponses[0].TxHash, tx.From, result.UsedZkCounters, result.ReservedZkCounters) - metrics.WorkerProcessingTime(time.Since(start)) return nil, ErrBatchResourceOverFlow } @@ -644,7 +652,6 @@ func (f *finalizer) updateWorkerAfterSuccessfulProcessing(ctx context.Context, t log.Debugf("tx %s deleted from address %s", txHash.String(), txFrom.Hex()) } - start := time.Now() txsToDelete := f.workerIntf.UpdateAfterSingleSuccessfulTxExecution(txFrom, result.ReadWriteAddresses) for _, txToDelete := range txsToDelete { err := f.poolIntf.UpdateTxStatus(ctx, txToDelete.Hash, pool.TxStatusFailed, false, txToDelete.FailedReason) @@ -652,9 +659,7 @@ func (f *finalizer) updateWorkerAfterSuccessfulProcessing(ctx context.Context, t log.Errorf("failed to update status to failed in the pool for tx %s, error: %v", txToDelete.Hash.String(), err) continue } - metrics.TxProcessed(metrics.TxProcessedLabelFailed, 1) } - metrics.WorkerProcessingTime(time.Since(start)) } // handleProcessTransactionError handles the error of a transaction @@ -667,9 +672,8 @@ func (f *finalizer) handleProcessTransactionError(ctx context.Context, result *s failedReason := executor.RomErr(errorCode).Error() if executor.IsROMOutOfCountersError(errorCode) { log.Errorf("ROM out of counters error, marking tx %s as invalid, errorCode: %d", tx.HashStr, errorCode) - start := time.Now() + f.workerIntf.DeleteTx(tx.Hash, tx.From) - metrics.WorkerProcessingTime(time.Since(start)) wg.Add(1) go func() { @@ -677,8 +681,6 @@ func (f *finalizer) handleProcessTransactionError(ctx context.Context, result *s err := f.poolIntf.UpdateTxStatus(ctx, tx.Hash, pool.TxStatusInvalid, false, &failedReason) if err != nil { log.Errorf("failed to update status to invalid in the pool for tx %s, error: %v", tx.HashStr, err) - } else { - metrics.TxProcessed(metrics.TxProcessedLabelInvalid, 1) } }() } else if executor.IsInvalidNonceError(errorCode) || executor.IsInvalidBalanceError(errorCode) { @@ -690,7 +692,6 @@ func (f *finalizer) handleProcessTransactionError(ctx context.Context, result *s nonce = addressInfo.Nonce balance = addressInfo.Balance } - start := time.Now() log.Errorf("intrinsic error, moving tx %s to not ready: nonce: %d, balance: %d. gasPrice: %d, error: %v", tx.Hash, nonce, balance, tx.GasPrice, txResponse.RomError) txsToDelete := f.workerIntf.MoveTxToNotReady(tx.Hash, tx.From, nonce, balance) for _, txToDelete := range txsToDelete { @@ -699,13 +700,11 @@ func (f *finalizer) handleProcessTransactionError(ctx context.Context, result *s go func() { defer wg.Done() err := f.poolIntf.UpdateTxStatus(ctx, txToDelete.Hash, pool.TxStatusFailed, false, &failedReason) - metrics.TxProcessed(metrics.TxProcessedLabelFailed, 1) if err != nil { log.Errorf("failed to update status to failed in the pool for tx %s, error: %v", txToDelete.Hash.String(), err) } }() } - metrics.WorkerProcessingTime(time.Since(start)) } else { // Delete the transaction from the txSorted list f.workerIntf.DeleteTx(tx.Hash, tx.From) @@ -718,8 +717,6 @@ func (f *finalizer) handleProcessTransactionError(ctx context.Context, result *s err := f.poolIntf.UpdateTxStatus(ctx, tx.Hash, pool.TxStatusFailed, false, &failedReason) if err != nil { log.Errorf("failed to update status to failed in the pool for tx %s, error: %v", tx.Hash.String(), err) - } else { - metrics.TxProcessed(metrics.TxProcessedLabelFailed, 1) } }() } diff --git a/sequencer/finalizer_test.go b/sequencer/finalizer_test.go index e119919ffe..8e7b5fa9d9 100644 --- a/sequencer/finalizer_test.go +++ b/sequencer/finalizer_test.go @@ -117,7 +117,7 @@ func TestNewFinalizer(t *testing.T) { poolMock.On("GetLastSentFlushID", context.Background()).Return(uint64(0), nil) // arrange and act - f = newFinalizer(cfg, poolCfg, workerMock, poolMock, stateMock, ethermanMock, seqAddr, isSynced, bc, eventLog, nil, nil) + f = newFinalizer(cfg, poolCfg, workerMock, poolMock, stateMock, ethermanMock, seqAddr, isSynced, bc, eventLog, nil, newTimeoutCond(&sync.Mutex{}), nil) // assert assert.NotNil(t, f) diff --git a/sequencer/forcedbatch.go b/sequencer/forcedbatch.go index 4f035ec708..9150e7c5f7 100644 --- a/sequencer/forcedbatch.go +++ b/sequencer/forcedbatch.go @@ -105,7 +105,7 @@ func (f *finalizer) processForcedBatch(ctx context.Context, forcedBatch state.Fo TimestampLimit_V2: uint64(forcedBatch.ForcedAt.Unix()), ForkID: f.stateIntf.GetForkIDByBatchNumber(lastBatchNumber), SkipVerifyL1InfoRoot_V2: true, - Caller: stateMetrics.SequencerCallerLabel, + Caller: stateMetrics.DiscardCallerLabel, ExecutionMode: executor.ExecutionMode0, } diff --git a/sequencer/l2block.go b/sequencer/l2block.go index 498d48b193..c674bf4a18 100644 --- a/sequencer/l2block.go +++ b/sequencer/l2block.go @@ -9,7 +9,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/hex" "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/pool" - "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" @@ -18,6 +17,7 @@ import ( // L2Block represents a wip or processed L2 block type L2Block struct { + createdAt time.Time trackingNum uint64 timestamp uint64 deltaTimestamp uint32 @@ -29,6 +29,7 @@ type L2Block struct { reservedZKCounters state.ZKCounters transactions []*TxTracker batchResponse *state.ProcessBatchResponse + metrics metrics } func (b *L2Block) isEmpty() bool { @@ -162,7 +163,7 @@ func (f *finalizer) storePendingL2Blocks(ctx context.Context) { // processL2Block process a L2 Block and adds it to the pendingL2BlocksToStore channel func (f *finalizer) processL2Block(ctx context.Context, l2Block *L2Block) error { - startProcessing := time.Now() + processStart := time.Now() initialStateRoot := f.wipBatch.finalStateRoot @@ -223,11 +224,20 @@ func (f *finalizer) processL2Block(ctx context.Context, l2Block *L2Block) error f.addPendingL2BlockToStore(ctx, l2Block) - endProcessing := time.Now() + // metrics + l2Block.metrics.l2BlockTimes.sequencer = time.Since(processStart) - l2Block.metrics.l2BlockTimes.executor + l2Block.metrics.close(l2Block.createdAt, int64(len(l2Block.transactions))) + f.metrics.addL2BlockMetrics(l2Block.metrics) - log.Infof("processed L2 block %d [%d], batch: %d, deltaTimestamp: %d, timestamp: %d, l1InfoTreeIndex: %d, l1InfoTreeIndexChanged: %v, initialStateRoot: %s, newStateRoot: %s, txs: %d/%d, blockHash: %s, infoRoot: %s, time: %v, used counters: %s, reserved counters: %s", + log.Infof("processed L2 block %d [%d], batch: %d, deltaTimestamp: %d, timestamp: %d, l1InfoTreeIndex: %d, l1InfoTreeIndexChanged: %v, initialStateRoot: %s, newStateRoot: %s, txs: %d/%d, blockHash: %s, infoRoot: %s, used counters: %s, reserved counters: %s", blockResponse.BlockNumber, l2Block.trackingNum, f.wipBatch.batchNumber, l2Block.deltaTimestamp, l2Block.timestamp, l2Block.l1InfoTreeExitRoot.L1InfoTreeIndex, l2Block.l1InfoTreeExitRootChanged, initialStateRoot, l2Block.batchResponse.NewStateRoot, - len(l2Block.transactions), len(blockResponse.TransactionResponses), blockResponse.BlockHash, blockResponse.BlockInfoRoot, endProcessing.Sub(startProcessing), f.logZKCounters(batchResponse.UsedZkCounters), f.logZKCounters(batchResponse.ReservedZkCounters)) + len(l2Block.transactions), len(blockResponse.TransactionResponses), blockResponse.BlockHash, blockResponse.BlockInfoRoot, + f.logZKCounters(batchResponse.UsedZkCounters), f.logZKCounters(batchResponse.ReservedZkCounters)) + + if f.cfg.Metrics.EnableLog { + log.Infof("metrics-log: {l2block: {num: %d, trackingNum: %d, metrics: {%s}}, interval: {startAt: %d, metrics: {%s}}}", + blockResponse.BlockNumber, l2Block.trackingNum, l2Block.metrics.log(), f.metrics.startsAt().Unix(), f.metrics.log()) + } return nil } @@ -287,7 +297,9 @@ func (f *finalizer) executeL2Block(ctx context.Context, initialStateRoot common. batchResponse *state.ProcessBatchResponse ) + executionStart := time.Now() batchResponse, err = f.stateIntf.ProcessBatchV2(ctx, batchRequest, true) + l2Block.metrics.l2BlockTimes.executor = time.Since(executionStart) if err != nil { executeL2BLockError(err) @@ -467,7 +479,10 @@ func (f *finalizer) closeWIPL2Block(ctx context.Context) { // openNewWIPL2Block opens a new wip L2 block func (f *finalizer) openNewWIPL2Block(ctx context.Context, prevTimestamp uint64, prevL1InfoTreeIndex *uint32) { + processStart := time.Now() + newL2Block := &L2Block{} + newL2Block.createdAt = time.Now() // Tracking number f.l2BlockCounter++ @@ -547,6 +562,8 @@ func (f *finalizer) openNewWIPL2Block(ctx context.Context, prevTimestamp uint64, } } + f.wipL2Block.metrics.newL2BlockTimes.sequencer = time.Since(processStart) - f.wipL2Block.metrics.newL2BlockTimes.executor + log.Infof("created new WIP L2 block [%d], batch: %d, deltaTimestamp: %d, timestamp: %d, l1InfoTreeIndex: %d, l1InfoTreeIndexChanged: %v, oldStateRoot: %s, imStateRoot: %s, used counters: %s, reserved counters: %s", f.wipL2Block.trackingNum, f.wipBatch.batchNumber, f.wipL2Block.deltaTimestamp, f.wipL2Block.timestamp, f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex, f.wipL2Block.l1InfoTreeExitRootChanged, oldIMStateRoot, f.wipL2Block.imStateRoot, f.logZKCounters(f.wipL2Block.usedZKCounters), f.logZKCounters(f.wipL2Block.reservedZKCounters)) @@ -554,18 +571,13 @@ func (f *finalizer) openNewWIPL2Block(ctx context.Context, prevTimestamp uint64, // executeNewWIPL2Block executes an empty L2 Block in the executor and returns the batch response from the executor func (f *finalizer) executeNewWIPL2Block(ctx context.Context) (*state.ProcessBatchResponse, error) { - start := time.Now() - defer func() { - metrics.ProcessingTime(time.Since(start)) - }() - batchRequest := state.ProcessRequest{ BatchNumber: f.wipBatch.batchNumber, OldStateRoot: f.wipBatch.imStateRoot, Coinbase: f.wipBatch.coinbase, L1InfoRoot_V2: state.GetMockL1InfoRoot(), TimestampLimit_V2: f.wipL2Block.timestamp, - Caller: stateMetrics.SequencerCallerLabel, + Caller: stateMetrics.DiscardCallerLabel, ForkID: f.stateIntf.GetForkIDByBatchNumber(f.wipBatch.batchNumber), SkipWriteBlockInfoRoot_V2: true, SkipVerifyL1InfoRoot_V2: true, @@ -581,7 +593,9 @@ func (f *finalizer) executeNewWIPL2Block(ctx context.Context) (*state.ProcessBat MinTimestamp: uint64(f.wipL2Block.l1InfoTreeExitRoot.GlobalExitRoot.Timestamp.Unix()), } + executorTime := time.Now() batchResponse, err := f.stateIntf.ProcessBatchV2(ctx, batchRequest, false) + f.wipL2Block.metrics.newL2BlockTimes.executor = time.Since(executorTime) if err != nil { return nil, err diff --git a/sequencer/metrics.go b/sequencer/metrics.go new file mode 100644 index 0000000000..43bd828157 --- /dev/null +++ b/sequencer/metrics.go @@ -0,0 +1,159 @@ +package sequencer + +import ( + "fmt" + "time" +) + +// |-----------------------------------------------------------------------------| -> totalTime +// |------------| |-------------------------| -> transactionsTime +// |-newL2Block-|----tx 1----| |---tx 2---|-----tx 3-----| |-----l2Block-----| +// sequencer |sssss ss|sss ss| |sss ss|sss ss| |ssss ss| -> sequencerTime +// executor | xxxxx | xxxxxxx | | xxxxx | xxxxxxxxx | | xxxxxxxxxxx | -> executorTime +// idle | |iiii| | |ii| | -> idleTime +// + +type processTimes struct { + sequencer time.Duration + executor time.Duration +} + +func (p *processTimes) total() time.Duration { + return p.sequencer + p.executor +} + +func (p *processTimes) sub(ptSub processTimes) { + p.sequencer -= ptSub.sequencer + p.executor -= ptSub.executor +} + +func (p *processTimes) sumUp(ptSumUp processTimes) { + p.sequencer += ptSumUp.sequencer + p.executor += ptSumUp.executor +} + +type metrics struct { + closedAt time.Time + txsCount int64 + idleTime time.Duration + newL2BlockTimes processTimes + transactionsTimes processTimes + l2BlockTimes processTimes + estimatedTxsPerSec float64 +} + +func (m *metrics) sub(mSub metrics) { + m.txsCount -= mSub.txsCount + m.idleTime -= mSub.idleTime + m.newL2BlockTimes.sub(mSub.newL2BlockTimes) + m.transactionsTimes.sub(mSub.transactionsTimes) + m.l2BlockTimes.sub(mSub.l2BlockTimes) +} + +func (m *metrics) sumUp(mSumUp metrics) { + m.txsCount += mSumUp.txsCount + m.idleTime += mSumUp.idleTime + m.newL2BlockTimes.sumUp(mSumUp.newL2BlockTimes) + m.transactionsTimes.sumUp(mSumUp.transactionsTimes) + m.l2BlockTimes.sumUp(mSumUp.l2BlockTimes) +} + +func (m *metrics) executorTime() time.Duration { + return m.newL2BlockTimes.executor + m.transactionsTimes.executor + m.l2BlockTimes.executor +} + +func (m *metrics) sequencerTime() time.Duration { + return m.newL2BlockTimes.sequencer + m.transactionsTimes.sequencer + m.l2BlockTimes.sequencer +} + +func (m *metrics) totalTime() time.Duration { + return m.newL2BlockTimes.total() + m.transactionsTimes.total() + m.l2BlockTimes.total() + m.idleTime +} + +func (m *metrics) close(createdAt time.Time, txsCount int64) { + // Compute pending fields + m.closedAt = time.Now() + totalTime := time.Since(createdAt) + m.txsCount = txsCount + m.transactionsTimes.sequencer = totalTime - m.idleTime - m.newL2BlockTimes.total() - m.transactionsTimes.executor - m.l2BlockTimes.total() + + // Compute performance + if m.txsCount > 0 { + // timePerTxuS is the average time spent per tx. This includes the l2Block time since the processing time of this section is proportional to the number of txs + timePerTxuS := (m.transactionsTimes.total() + m.l2BlockTimes.total()).Microseconds() / m.txsCount + m.estimatedTxsPerSec = float64(m.totalTime().Microseconds()-m.newL2BlockTimes.total().Microseconds()) / float64(timePerTxuS) + } +} + +func (m *metrics) log() string { + return fmt.Sprintf("txs: %d, estimated txs/s: %.1f, time: {total: %d, idle: %d, sequencer: {total: %d, newL2Block: %d, txs: %d, l2Block: %d}, executor: {total: %d, newL2Block: %d, txs: %d, l2Block: %d}", + m.txsCount, m.estimatedTxsPerSec, m.totalTime().Microseconds(), m.idleTime.Microseconds(), + m.sequencerTime().Microseconds(), m.newL2BlockTimes.sequencer.Microseconds(), m.transactionsTimes.sequencer.Microseconds(), m.l2BlockTimes.sequencer.Microseconds(), + m.executorTime().Microseconds(), m.newL2BlockTimes.executor.Microseconds(), m.transactionsTimes.executor.Microseconds(), m.l2BlockTimes.executor.Microseconds()) +} + +type intervalMetrics struct { + l2Blocks []*metrics + maxInterval time.Duration + metrics + estimatedTxsPerSecAcc float64 + estimatedTxsPerSecCount int64 +} + +func newIntervalMetrics(maxInterval time.Duration) *intervalMetrics { + return &intervalMetrics{ + l2Blocks: []*metrics{}, + maxInterval: maxInterval, + metrics: metrics{}, + } +} + +func (i *intervalMetrics) cleanUp() { + now := time.Now() + ct := 0 + for { + if len(i.l2Blocks) == 0 { + return + } + l2Block := i.l2Blocks[0] + if l2Block.closedAt.Add(i.maxInterval).Before(now) { + // Subtract l2Block metrics from accumulated values + i.sub(*l2Block) + if l2Block.txsCount > 0 { + i.estimatedTxsPerSecAcc -= i.estimatedTxsPerSec + i.estimatedTxsPerSecCount-- + } + ct++ + } else { + break + } + } + + if ct > 0 { + // Remove from l2Blocks + i.l2Blocks = i.l2Blocks[ct:] + // Compute performance + i.computeEstimatedTxsPerSec() + } +} + +func (i *intervalMetrics) addL2BlockMetrics(l2Block metrics) { + i.cleanUp() + + i.sumUp(l2Block) + if l2Block.txsCount > 0 { + i.estimatedTxsPerSecAcc += l2Block.estimatedTxsPerSec + i.estimatedTxsPerSecCount++ + i.computeEstimatedTxsPerSec() + } + + i.l2Blocks = append(i.l2Blocks, &l2Block) +} + +func (i *intervalMetrics) computeEstimatedTxsPerSec() { + i.estimatedTxsPerSec = i.estimatedTxsPerSecAcc / float64(i.estimatedTxsPerSecCount) +} + +func (i *intervalMetrics) startsAt() time.Time { + return time.Now().Add(-i.maxInterval) +} diff --git a/sequencer/metrics/metrics.go b/sequencer/metrics/metrics.go deleted file mode 100644 index b88f7d14a5..0000000000 --- a/sequencer/metrics/metrics.go +++ /dev/null @@ -1,153 +0,0 @@ -package metrics - -import ( - "time" - - "github.com/0xPolygonHermez/zkevm-node/metrics" - "github.com/prometheus/client_golang/prometheus" -) - -const ( - // Prefix for the metrics of the sequencer package. - Prefix = "sequencer_" - // SequencesSentToL1CountName is the name of the metric that counts the sequences sent to L1. - SequencesSentToL1CountName = Prefix + "sequences_sent_to_L1_count" - // GasPriceEstimatedAverageName is the name of the metric that shows the average estimated gas price. - GasPriceEstimatedAverageName = Prefix + "gas_price_estimated_average" - // TxProcessedName is the name of the metric that counts the processed transactions. - TxProcessedName = Prefix + "transaction_processed" - // SequencesOversizedDataErrorName is the name of the metric that counts the sequences with oversized data error. - SequencesOversizedDataErrorName = Prefix + "sequences_oversized_data_error" - // EthToPolPriceName is the name of the metric that shows the Ethereum to Pol price. - EthToPolPriceName = Prefix + "eth_to_pol_price" - // SequenceRewardInPolName is the name of the metric that shows the reward in Pol of a sequence. - SequenceRewardInPolName = Prefix + "sequence_reward_in_pol" - // ProcessingTimeName is the name of the metric that shows the processing time. - ProcessingTimeName = Prefix + "processing_time" - // WorkerPrefix is the prefix for the metrics of the worker. - WorkerPrefix = Prefix + "worker_" - // WorkerProcessingTimeName is the name of the metric that shows the worker processing time. - WorkerProcessingTimeName = WorkerPrefix + "processing_time" - // TxProcessedLabelName is the name of the label for the processed transactions. - TxProcessedLabelName = "status" -) - -// TxProcessedLabel represents the possible values for the -// `sequencer_transaction_processed` metric `type` label. -type TxProcessedLabel string - -const ( - // TxProcessedLabelSuccessful represents a successful transaction - TxProcessedLabelSuccessful TxProcessedLabel = "successful" - // TxProcessedLabelInvalid represents an invalid transaction - TxProcessedLabelInvalid TxProcessedLabel = "invalid" - // TxProcessedLabelFailed represents a failed transaction - TxProcessedLabelFailed TxProcessedLabel = "failed" -) - -// Register the metrics for the sequencer package. -func Register() { - var ( - counters []prometheus.CounterOpts - counterVecs []metrics.CounterVecOpts - gauges []prometheus.GaugeOpts - histograms []prometheus.HistogramOpts - ) - - counters = []prometheus.CounterOpts{ - { - Name: SequencesSentToL1CountName, - Help: "[SEQUENCER] total count of sequences sent to L1", - }, - { - Name: SequencesOversizedDataErrorName, - Help: "[SEQUENCER] total count of sequences with oversized data error", - }, - } - - counterVecs = []metrics.CounterVecOpts{ - { - CounterOpts: prometheus.CounterOpts{ - Name: TxProcessedName, - Help: "[SEQUENCER] number of transactions processed", - }, - Labels: []string{TxProcessedLabelName}, - }, - } - - gauges = []prometheus.GaugeOpts{ - { - Name: GasPriceEstimatedAverageName, - Help: "[SEQUENCER] average gas price estimated", - }, - { - Name: EthToPolPriceName, - Help: "[SEQUENCER] eth to pol price", - }, - { - Name: SequenceRewardInPolName, - Help: "[SEQUENCER] reward for a sequence in pol", - }, - } - - histograms = []prometheus.HistogramOpts{ - { - Name: ProcessingTimeName, - Help: "[SEQUENCER] processing time", - }, - { - Name: WorkerProcessingTimeName, - Help: "[SEQUENCER] worker processing time", - }, - } - - metrics.RegisterCounters(counters...) - metrics.RegisterCounterVecs(counterVecs...) - metrics.RegisterGauges(gauges...) - metrics.RegisterHistograms(histograms...) -} - -// AverageGasPrice sets the gauge to the given average gas price. -func AverageGasPrice(price float64) { - metrics.GaugeSet(GasPriceEstimatedAverageName, price) -} - -// SequencesSentToL1 increases the counter by the provided number of sequences -// sent to L1. -func SequencesSentToL1(numSequences float64) { - metrics.CounterAdd(SequencesSentToL1CountName, numSequences) -} - -// TxProcessed increases the counter vector by the provided transactions count -// and for the given label (status). -func TxProcessed(status TxProcessedLabel, count float64) { - metrics.CounterVecAdd(TxProcessedName, string(status), count) -} - -// SequencesOvesizedDataError increases the counter for sequences that -// encounter a OversizedData error. -func SequencesOvesizedDataError() { - metrics.CounterInc(SequencesOversizedDataErrorName) -} - -// EthToPolPrice sets the gauge for the Ethereum to Pol price. -func EthToPolPrice(price float64) { - metrics.GaugeSet(EthToPolPriceName, price) -} - -// SequenceRewardInPol sets the gauge for the reward in Pol of a sequence. -func SequenceRewardInPol(reward float64) { - metrics.GaugeSet(SequenceRewardInPolName, reward) -} - -// ProcessingTime observes the last processing time on the histogram. -func ProcessingTime(lastProcessTime time.Duration) { - execTimeInSeconds := float64(lastProcessTime) / float64(time.Second) - metrics.HistogramObserve(ProcessingTimeName, execTimeInSeconds) -} - -// WorkerProcessingTime observes the last processing time on the histogram. -func WorkerProcessingTime(lastProcessTime time.Duration) { - execTimeInSeconds := float64(lastProcessTime) / float64(time.Second) - metrics.HistogramObserve(WorkerProcessingTimeName, execTimeInSeconds) -} diff --git a/sequencer/sequencer.go b/sequencer/sequencer.go index d53dab0c7d..e98c367fc1 100644 --- a/sequencer/sequencer.go +++ b/sequencer/sequencer.go @@ -3,13 +3,13 @@ package sequencer import ( "context" "fmt" + "sync" "time" "github.com/0xPolygonHermez/zkevm-data-streamer/datastreamer" "github.com/0xPolygonHermez/zkevm-node/event" "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/pool" - "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" "github.com/0xPolygonHermez/zkevm-node/state" "github.com/ethereum/go-ethereum/common" ) @@ -31,6 +31,8 @@ type Sequencer struct { worker *Worker finalizer *finalizer + workerReadyTxsCond *timeoutCond + streamServer *datastreamer.StreamServer dataToStream chan interface{} @@ -70,7 +72,6 @@ func (s *Sequencer) Start(ctx context.Context) { log.Infof("waiting for synchronizer to sync...") time.Sleep(time.Second) } - metrics.Register() err := s.pool.MarkWIPTxsAsPending(ctx) if err != nil { @@ -98,8 +99,9 @@ func (s *Sequencer) Start(ctx context.Context) { go s.sendDataToStreamer(s.cfg.StreamServer.ChainID) } - s.worker = NewWorker(s.stateIntf, s.batchCfg.Constraints) - s.finalizer = newFinalizer(s.cfg.Finalizer, s.poolCfg, s.worker, s.pool, s.stateIntf, s.etherman, s.address, s.isSynced, s.batchCfg.Constraints, s.eventLog, s.streamServer, s.dataToStream) + s.workerReadyTxsCond = newTimeoutCond(&sync.Mutex{}) + s.worker = NewWorker(s.stateIntf, s.batchCfg.Constraints, s.workerReadyTxsCond) + s.finalizer = newFinalizer(s.cfg.Finalizer, s.poolCfg, s.worker, s.pool, s.stateIntf, s.etherman, s.address, s.isSynced, s.batchCfg.Constraints, s.eventLog, s.streamServer, s.workerReadyTxsCond, s.dataToStream) go s.finalizer.Start(ctx) go s.deleteOldPoolTxs(ctx) @@ -183,7 +185,6 @@ func (s *Sequencer) expireOldWorkerTxs(ctx context.Context) { failedReason := ErrExpiredTransaction.Error() for _, txTracker := range txTrackers { err := s.pool.UpdateTxStatus(ctx, txTracker.Hash, pool.TxStatusFailed, false, &failedReason) - metrics.TxProcessed(metrics.TxProcessedLabelFailed, 1) if err != nil { log.Errorf("failed to update tx status, error: %v", err) } @@ -194,8 +195,6 @@ func (s *Sequencer) expireOldWorkerTxs(ctx context.Context) { // loadFromPool keeps loading transactions from the pool func (s *Sequencer) loadFromPool(ctx context.Context) { for { - time.Sleep(s.cfg.LoadPoolTxsCheckInterval.Duration) - poolTransactions, err := s.pool.GetNonWIPPendingTxs(ctx) if err != nil && err != pool.ErrNotFound { log.Errorf("error loading txs from pool, error: %v", err) @@ -207,6 +206,10 @@ func (s *Sequencer) loadFromPool(ctx context.Context) { log.Errorf("error adding transaction to worker, error: %v", err) } } + + if len(poolTransactions) == 0 { + time.Sleep(s.cfg.LoadPoolTxsCheckInterval.Duration) + } } } diff --git a/sequencer/timeoutCond.go b/sequencer/timeoutCond.go new file mode 100644 index 0000000000..862d4eb4fe --- /dev/null +++ b/sequencer/timeoutCond.go @@ -0,0 +1,63 @@ +package sequencer + +import ( + "sync" + "time" +) + +type timeoutCond struct { + L sync.Locker + ch chan bool +} + +func newTimeoutCond(l sync.Locker) *timeoutCond { + return &timeoutCond{ch: make(chan bool), L: l} +} + +func (t *timeoutCond) Wait() { + t.L.Unlock() + <-t.ch + t.L.Lock() +} + +func (t *timeoutCond) WaitOrTimeout(d time.Duration) bool { + timeout := time.NewTimer(d) + t.L.Unlock() + var r bool + select { + case <-timeout.C: + r = false + case <-t.ch: + r = true + } + if !timeout.Stop() { + select { + case <-timeout.C: + default: + } + } + t.L.Lock() + return r +} + +func (t *timeoutCond) Signal() { + t.signal() +} + +func (t *timeoutCond) Broadcast() { + for { + // Stop when we run out of waiters + if !t.signal() { + return + } + } +} + +func (t *timeoutCond) signal() bool { + select { + case t.ch <- true: + return true + default: + return false + } +} diff --git a/sequencer/worker.go b/sequencer/worker.go index d068788bf5..a99f956fed 100644 --- a/sequencer/worker.go +++ b/sequencer/worker.go @@ -22,15 +22,17 @@ type Worker struct { workerMutex sync.Mutex state stateInterface batchConstraints state.BatchConstraintsCfg + readyTxsCond *timeoutCond } // NewWorker creates an init a worker -func NewWorker(state stateInterface, constraints state.BatchConstraintsCfg) *Worker { +func NewWorker(state stateInterface, constraints state.BatchConstraintsCfg, readyTxsCond *timeoutCond) *Worker { w := Worker{ pool: make(map[string]*addrQueue), txSortedList: newTxSortedList(), state: state, batchConstraints: constraints, + readyTxsCond: readyTxsCond, } return &w @@ -108,7 +110,7 @@ func (w *Worker) AddTxTracker(ctx context.Context, tx *TxTracker) (replacedTx *T } if newReadyTx != nil { log.Debugf("newReadyTx %s (nonce: %d, gasPrice: %d, addr: %s) added to TxSortedList", newReadyTx.HashStr, newReadyTx.Nonce, newReadyTx.GasPrice, tx.FromStr) - w.txSortedList.add(newReadyTx) + w.addTxToSortedList(newReadyTx) } if repTx != nil { @@ -132,7 +134,7 @@ func (w *Worker) applyAddressUpdate(from common.Address, fromNonce *uint64, from } if newReadyTx != nil { log.Debugf("newReadyTx %s (nonce: %d, gasPrice: %d) added to TxSortedList", newReadyTx.Hash.String(), newReadyTx.Nonce, newReadyTx.GasPrice) - w.txSortedList.add(newReadyTx) + w.addTxToSortedList(newReadyTx) } return newReadyTx, prevReadyTx, txsToDelete @@ -370,3 +372,13 @@ func (w *Worker) ExpireTransactions(maxTime time.Duration) []*TxTracker { return txs } + +func (w *Worker) addTxToSortedList(readyTx *TxTracker) { + w.txSortedList.add(readyTx) + if w.txSortedList.len() == 1 { + // The txSortedList was empty before to add the new tx, we notify finalizer that we have new ready txs to process + w.readyTxsCond.L.Lock() + w.readyTxsCond.Signal() + w.readyTxsCond.L.Unlock() + } +} diff --git a/sequencer/worker_test.go b/sequencer/worker_test.go index 688576fa7b..a86d7a2f3f 100644 --- a/sequencer/worker_test.go +++ b/sequencer/worker_test.go @@ -3,6 +3,7 @@ package sequencer import ( "context" "math/big" + "sync" "testing" "github.com/0xPolygonHermez/zkevm-node/pool" @@ -283,6 +284,6 @@ func TestWorkerGetBestTx(t *testing.T) { } func initWorker(stateMock *StateMock, rcMax state.BatchConstraintsCfg) *Worker { - worker := NewWorker(stateMock, rcMax) + worker := NewWorker(stateMock, rcMax, newTimeoutCond(&sync.Mutex{})) return worker } diff --git a/sequencesender/sequencesender.go b/sequencesender/sequencesender.go index 674fce1a25..e07c5e379c 100644 --- a/sequencesender/sequencesender.go +++ b/sequencesender/sequencesender.go @@ -11,7 +11,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/ethtxmanager" "github.com/0xPolygonHermez/zkevm-node/event" "github.com/0xPolygonHermez/zkevm-node/log" - "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" "github.com/0xPolygonHermez/zkevm-node/state" ethTypes "github.com/ethereum/go-ethereum/core/types" "github.com/jackc/pgx/v4" @@ -136,7 +135,6 @@ func (s *SequenceSender) tryToSendSequence(ctx context.Context) { // Send sequences to L1 sequenceCount := len(sequences) log.Infof("sending sequences to L1. From batch %d to batch %d", lastVirtualBatchNum+1, lastVirtualBatchNum+uint64(sequenceCount)) - metrics.SequencesSentToL1(float64(sequenceCount)) // Check if we need to wait until last L1 block timestamp is L1BlockTimestampMargin seconds above the timestamp of the last L2 block in the sequence // Get last sequence @@ -294,7 +292,6 @@ func (s *SequenceSender) getSequencesToSend(ctx context.Context) ([]types.Sequen lastSequence := sequences[len(sequences)-1] tx, err = s.etherman.EstimateGasSequenceBatches(s.cfg.SenderAddress, sequences, uint64(lastSequence.LastL2BLockTimestamp), firstSequence.BatchNumber-1, s.cfg.L2Coinbase) if err == nil && tx.Size() > s.cfg.MaxTxSizeForL1 { - metrics.SequencesOvesizedDataError() log.Infof("oversized Data on TX oldHash %s (txSize %d > %d)", tx.Hash(), tx.Size(), s.cfg.MaxTxSizeForL1) err = ErrOversizedData } diff --git a/test/benchmarks/sequencer/common/metrics/metrics.go b/test/benchmarks/sequencer/common/metrics/metrics.go deleted file mode 100644 index 8d3d3da42c..0000000000 --- a/test/benchmarks/sequencer/common/metrics/metrics.go +++ /dev/null @@ -1,193 +0,0 @@ -package metrics - -import ( - "fmt" - "net/http" - "os/exec" - "strings" - "time" - - metricsLib "github.com/0xPolygonHermez/zkevm-node/metrics" - "github.com/0xPolygonHermez/zkevm-node/sequencer/metrics" - metricsState "github.com/0xPolygonHermez/zkevm-node/state/metrics" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/0xPolygonHermez/zkevm-node/test/testutils" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" -) - -const ( - oneHundred = 100 - profilingPort = 6060 -) - -// CalculateAndPrint calculates and prints the results -func CalculateAndPrint( - txsType string, - totalTxs uint64, - client *ethclient.Client, - profilingResult string, - elapsed time.Duration, - sequencerTimeSub, executorTimeSub float64, - allTxs []*types.Transaction, -) { - fmt.Println("##########") - fmt.Println("# Result #") - fmt.Println("##########") - fmt.Printf("Total time (including setup of environment and starting containers): %v\n", elapsed) - totalTime := elapsed.Seconds() - - prometheusResp, err := FetchPrometheus() - if err != nil { - panic(fmt.Sprintf("error getting prometheus metrics: %v", err)) - } - metricValues, err := GetValues(prometheusResp) - if err != nil { - panic(fmt.Sprintf("error getting prometheus metrics: %v\n", err)) - } - actualTotalTime := metricValues.SequencerTotalProcessingTime - sequencerTimeSub - actualExecutorTime := metricValues.ExecutorTotalProcessingTime - executorTimeSub - totalTime = actualTotalTime - PrintSummary(txsType, params.NumberOfOperations, totalTxs, totalTime, actualExecutorTime, GetTotalGasUsedFromTxs(client, allTxs)) - - if profilingResult != "" { - fmt.Println("#####################") - fmt.Println("# Profiling Metrics #") - fmt.Println("#####################") - fmt.Printf("%v", profilingResult) - } -} - -func PrintSummary( - txsType string, - totalTransactionsSent uint64, - totalTxs uint64, - processingTimeSequencer float64, - processingTimeExecutor float64, - totalGas uint64, -) { - var transactionsTypes *string - if txsType == "uniswap" { - transactionsTypes, totalTransactionsSent = getTransactionsBreakdownForUniswap(totalTransactionsSent) - } - randomTxs := totalTxs - totalTransactionsSent - txsType = strings.ToUpper(txsType) - msg := fmt.Sprintf("# %s Benchmarks Summary #", txsType) - delimiter := strings.Repeat("-", len(msg)) - fmt.Println(delimiter) - fmt.Println(msg) - fmt.Println(delimiter) - - if transactionsTypes != nil { - fmt.Printf("Transactions Types: %s\n", *transactionsTypes) - } - fmt.Printf("Total Transactions: %d (%d predefined + %d random transactions)\n\n", totalTxs, totalTransactionsSent, randomTxs) - fmt.Println("Processing Times:") - fmt.Printf("- Total Processing Time: %.2f seconds\n", processingTimeSequencer) - fmt.Printf("- Executor Processing Time: %.2f seconds\n", processingTimeExecutor) - fmt.Printf("- Sequencer Processing Time: %.2f seconds\n\n", processingTimeSequencer-processingTimeExecutor) - fmt.Println("Percentage Breakdown:") - fmt.Printf("- Executor Time Percentage from Total: %.2f%%\n\n", (processingTimeExecutor/processingTimeSequencer)*oneHundred) - fmt.Println("Metrics:") - fmt.Printf("- Transactions per Second: %.2f\n", float64(totalTxs)/processingTimeSequencer) - fmt.Printf("[the rest of the metrics are only for predefined transactions - excluding the random transactions]\n") - fmt.Printf("- Gas per Second: %.2f\n", float64(totalGas)/processingTimeSequencer) - fmt.Printf("- Total Gas Used: %d\n", totalGas) - fmt.Printf("- Average Gas Used per Transaction: %d\n\n", totalGas/totalTxs) -} - -func getTransactionsBreakdownForUniswap(numberOfOperations uint64) (*string, uint64) { - transactionsBreakdown := fmt.Sprintf("Deployments, Approvals, Adding Liquidity, %d Swap Cycles (A -> B -> C)", numberOfOperations) - totalTransactionsSent := (numberOfOperations * 2) + 17 - - return &transactionsBreakdown, totalTransactionsSent -} - -type Values struct { - SequencerTotalProcessingTime float64 - ExecutorTotalProcessingTime float64 - WorkerTotalProcessingTime float64 -} - -// GetValues gets the prometheus metric Values -func GetValues(metricsResponse *http.Response) (Values, error) { - var err error - if metricsResponse == nil { - metricsResponse, err = FetchPrometheus() - if err != nil { - panic(fmt.Sprintf("error getting prometheus metrics: %v", err)) - } - } - - mf, err := testutils.ParseMetricFamilies(metricsResponse.Body) - if err != nil { - return Values{}, err - } - sequencerTotalProcessingTimeHisto := mf[metrics.ProcessingTimeName].Metric[0].Histogram - sequencerTotalProcessingTime := sequencerTotalProcessingTimeHisto.GetSampleSum() - - workerTotalProcessingTimeHisto := mf[metrics.WorkerProcessingTimeName].Metric[0].Histogram - workerTotalProcessingTime := workerTotalProcessingTimeHisto.GetSampleSum() - - executorTotalProcessingTimeHisto := mf[metricsState.ExecutorProcessingTimeName].Metric[0].Histogram - executorTotalProcessingTime := executorTotalProcessingTimeHisto.GetSampleSum() - - return Values{ - SequencerTotalProcessingTime: sequencerTotalProcessingTime, - ExecutorTotalProcessingTime: executorTotalProcessingTime, - WorkerTotalProcessingTime: workerTotalProcessingTime, - }, nil -} - -// FetchPrometheus fetches the prometheus metrics -func FetchPrometheus() (*http.Response, error) { - fmt.Printf("Fetching prometheus metrics ...\n") - return http.Get(fmt.Sprintf("http://localhost:%d%s", params.PrometheusPort, metricsLib.Endpoint)) -} - -// FetchProfiling fetches the profiling metrics -func FetchProfiling() (string, error) { - fullUrl := fmt.Sprintf("http://localhost:%d%s", profilingPort, metricsLib.ProfileEndpoint) - fmt.Printf("Fetching profiling metrics from: %s ...", fullUrl) - cmd := exec.Command("go", "tool", "pprof", "-show=sequencer", "-top", fullUrl) - out, err := cmd.CombinedOutput() - if err != nil { - panic(fmt.Sprintf("error fetching profiling metrics: %v", err)) - } - return string(out), err -} - -func PrintUniswapDeployments(deployments time.Duration, count uint64) { - fmt.Println("#######################") - fmt.Println("# Uniswap Deployments #") - fmt.Println("#######################") - fmt.Printf("Total time took for the sequencer to deploy all contracts: %v\n", deployments) - fmt.Printf("Number of txs sent: %d\n", count) -} - -// GetTotalGasUsedFromTxs sums the total gas used from the transactions -func GetTotalGasUsedFromTxs(client *ethclient.Client, txs []*types.Transaction) uint64 { - // calculate the total gas used - var totalGas uint64 - for _, tx := range txs { - // Fetch the transaction receipt - receipt, err := client.TransactionReceipt(params.Ctx, tx.Hash()) - if err != nil { - fmt.Println("Unable to fetch transaction receipt", "error", err) - continue - } - - totalGas += receipt.GasUsed - - if receipt.Status != types.ReceiptStatusSuccessful { - reason := "unknown" - if receipt.Status == types.ReceiptStatusFailed { - reason = "reverted" - } - fmt.Println("Transaction failed", "tx", tx.Hash(), "status", receipt.Status, "reason", reason) - continue - } - } - - return totalGas -} diff --git a/test/benchmarks/sequencer/common/params/constants.go b/test/benchmarks/sequencer/common/params/constants.go deleted file mode 100644 index d30f97b8fe..0000000000 --- a/test/benchmarks/sequencer/common/params/constants.go +++ /dev/null @@ -1,16 +0,0 @@ -package params - -import ( - "time" -) - -const ( - // DefaultDeadline is the default deadline for the sequencer - DefaultDeadline = 6000 * time.Second - // MaxCumulativeGasUsed is the maximum cumulative gas used - MaxCumulativeGasUsed = 80000000000 - // PrometheusPort is the port where prometheus is running - PrometheusPort = 9092 - // NumberOfOperations is the number of transactions to send - NumberOfOperations = 300 -) diff --git a/test/benchmarks/sequencer/common/params/variables.go b/test/benchmarks/sequencer/common/params/variables.go deleted file mode 100644 index 9b12cbb930..0000000000 --- a/test/benchmarks/sequencer/common/params/variables.go +++ /dev/null @@ -1,30 +0,0 @@ -package params - -import ( - "context" - "strings" - - "github.com/0xPolygonHermez/zkevm-node/test/dbutils" - "github.com/0xPolygonHermez/zkevm-node/test/operations" - "github.com/ethereum/go-ethereum/common" - "github.com/ethereum/go-ethereum/crypto" -) - -var ( - // Ctx is the context - Ctx = context.Background() - // PoolDbConfig is the pool db config - PoolDbConfig = dbutils.NewPoolConfigFromEnv() - // SequencerPrivateKey is the private key of the sequencer - SequencerPrivateKey = operations.DefaultSequencerPrivateKey - // ChainID is the chain id - ChainID = operations.DefaultL2ChainID - // OpsCfg is the operations config - OpsCfg = operations.GetDefaultOperationsConfig() - // ToAddress is the address to send the txs - ToAddress = "0x4d5Cf5032B2a844602278b01199ED191A86c93ff" - // To is the address to send the txs - To = common.HexToAddress(ToAddress) - // PrivateKey is the private key of the sender - PrivateKey, _ = crypto.HexToECDSA(strings.TrimPrefix(SequencerPrivateKey, "0x")) -) diff --git a/test/benchmarks/sequencer/common/setup/setup.go b/test/benchmarks/sequencer/common/setup/setup.go deleted file mode 100644 index 5c38786ae4..0000000000 --- a/test/benchmarks/sequencer/common/setup/setup.go +++ /dev/null @@ -1,150 +0,0 @@ -package setup - -import ( - "context" - "fmt" - "math/big" - "testing" - "time" - - "github.com/0xPolygonHermez/zkevm-node/config/types" - "github.com/0xPolygonHermez/zkevm-node/event" - "github.com/0xPolygonHermez/zkevm-node/event/nileventstorage" - "github.com/0xPolygonHermez/zkevm-node/pool" - "github.com/0xPolygonHermez/zkevm-node/pool/pgpoolstorage" - "github.com/0xPolygonHermez/zkevm-node/state" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/0xPolygonHermez/zkevm-node/test/operations" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/ethclient" - "github.com/stretchr/testify/require" -) - -const ( - sleepDuration = 5 * time.Second - minAllowedGasPriceIntervalMinutes = 5 - pollMinAllowedGasPriceIntervalSeconds = 15 - defaultGasPrice = 1000000000 -) - -var ( - bc = state.BatchConstraintsCfg{ - MaxTxsPerBatch: 300, - MaxBatchBytesSize: 120000, - MaxCumulativeGasUsed: uint64(1125899906842624), - MaxKeccakHashes: 2145, - MaxPoseidonHashes: 252357, - MaxPoseidonPaddings: 135191, - MaxMemAligns: 236585, - MaxArithmetics: 236585, - MaxBinaries: 473170, - MaxSteps: 7570538, - MaxSHA256Hashes: 1596, - } -) - -// Environment sets up the environment for the benchmark -func Environment(ctx context.Context, b *testing.B) (*operations.Manager, *ethclient.Client, *pool.Pool, *bind.TransactOpts) { - if testing.Short() { - b.Skip() - } - - err := operations.Teardown() - require.NoError(b, err) - - params.OpsCfg.State.MaxCumulativeGasUsed = params.MaxCumulativeGasUsed - opsman, err := operations.NewManager(ctx, params.OpsCfg) - require.NoError(b, err) - - err = Components(opsman) - require.NoError(b, err) - time.Sleep(sleepDuration) - - // Load account with balance on local genesis - auth, err := operations.GetAuth(operations.DefaultSequencerPrivateKey, operations.DefaultL2ChainID) - require.NoError(b, err) - - // Load params client - client, err := ethclient.Dial(operations.DefaultL2NetworkURL) - require.NoError(b, err) - - st := opsman.State() - s, err := pgpoolstorage.NewPostgresPoolStorage(params.PoolDbConfig) - require.NoError(b, err) - config := pool.Config{ - DB: params.PoolDbConfig, - MinAllowedGasPriceInterval: types.NewDuration(minAllowedGasPriceIntervalMinutes * time.Minute), - PollMinAllowedGasPriceInterval: types.NewDuration(pollMinAllowedGasPriceIntervalSeconds * time.Second), - } - - eventStorage, err := nileventstorage.NewNilEventStorage() - require.NoError(b, err) - eventLog := event.NewEventLog(event.Config{}, eventStorage) - - pl := pool.NewPool(config, bc, s, st, params.ChainID, eventLog) - - // Print Info before send - senderBalance, err := client.BalanceAt(ctx, auth.From, nil) - require.NoError(b, err) - senderNonce, err := client.PendingNonceAt(ctx, auth.From) - require.NoError(b, err) - - // Print Initial Stats - fmt.Printf("Receiver Addr: %v\n", params.To.String()) - fmt.Printf("Sender Addr: %v\n", auth.From.String()) - fmt.Printf("Sender Balance: %v\n", senderBalance.String()) - fmt.Printf("Sender Nonce: %v\n", senderNonce) - - gasPrice, err := client.SuggestGasPrice(ctx) - require.NoError(b, err) - - if gasPrice == nil || gasPrice.Int64() == 0 { - gasPrice = big.NewInt(defaultGasPrice) - } - - // PrivateKey is the private key of the sender - // Auth is the auth of the sender - auth, err = bind.NewKeyedTransactorWithChainID(params.PrivateKey, new(big.Int).SetUint64(params.ChainID)) - if err != nil { - panic(err) - } - auth.GasPrice = gasPrice - - return opsman, client, pl, auth -} - -// Components runs the network container, starts synchronizer and JSON-RPC components, and approves pol -func Components(opsman *operations.Manager) error { - // Run network container - err := opsman.StartNetwork() - if err != nil { - return err - } - - // Approve pol - err = operations.ApprovePol() - if err != nil { - return err - } - - err = operations.StartComponent("sync") - if err != nil { - return err - } - - err = operations.StartComponent("json-rpc") - if err != nil { - return err - } - time.Sleep(sleepDuration) - - return nil -} - -// BootstrapSequencer starts the sequencer and waits for it to be ready -func BootstrapSequencer(b *testing.B, opsman *operations.Manager) { - fmt.Println("Starting sequencer ....") - err := operations.StartComponent("seq") - require.NoError(b, err) - fmt.Println("Sequencer Started!") -} diff --git a/test/benchmarks/sequencer/common/transactions/transactions.go b/test/benchmarks/sequencer/common/transactions/transactions.go deleted file mode 100644 index 82c4dffb51..0000000000 --- a/test/benchmarks/sequencer/common/transactions/transactions.go +++ /dev/null @@ -1,117 +0,0 @@ -package transactions - -import ( - "context" - "errors" - "fmt" - "math/big" - "strconv" - "time" - - "github.com/0xPolygonHermez/zkevm-node/pool" - "github.com/0xPolygonHermez/zkevm-node/state" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/0xPolygonHermez/zkevm-node/test/operations" - - "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20" - "github.com/0xPolygonHermez/zkevm-node/test/scripts/uniswap/pkg" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" -) - -// SendAndWait sends a number of transactions and waits for them to be marked as pending in the pool -func SendAndWait( - auth *bind.TransactOpts, - client *ethclient.Client, - getTxsByStatus func(ctx context.Context, status pool.TxStatus, limit uint64) ([]pool.Transaction, error), - nTxs uint64, - erc20SC *ERC20.ERC20, - uniswapDeployments *pkg.Deployments, - txSenderFunc func(l2Client *ethclient.Client, gasPrice *big.Int, auth *bind.TransactOpts, erc20SC *ERC20.ERC20, uniswapDeployments *pkg.Deployments) ([]*types.Transaction, error), -) ([]*types.Transaction, error) { - auth.GasLimit = 2100000 - fmt.Printf("Sending %d txs ...\n", nTxs) - if auth.Nonce != nil { - auth.Nonce = nil - } - - allTxs := make([]*types.Transaction, 0, nTxs) - for i := 0; i < int(nTxs); i++ { - txs, err := txSenderFunc(client, auth.GasPrice, auth, erc20SC, uniswapDeployments) - if err != nil { - return nil, err - } - allTxs = append(allTxs, txs...) - } - fmt.Println("All txs were sent!") - fmt.Println("Waiting pending transactions To be added in the pool ...") - err := operations.Poll(1*time.Second, params.DefaultDeadline, func() (bool, error) { - // using a closure here To capture st and currentBatchNumber - pendingTxs, err := getTxsByStatus(params.Ctx, pool.TxStatusPending, 0) - if err != nil { - panic(err) - } - pendingTxsCount := 0 - for _, tx := range pendingTxs { - sender, err := state.GetSender(tx.Transaction) - if err != nil { - panic(err) - } - if sender == auth.From { - pendingTxsCount++ - } - } - - fmt.Printf("amount of pending txs: %d\n\n", pendingTxsCount) - done := pendingTxsCount <= 0 - return done, nil - }) - if err != nil { - return nil, err - } - - fmt.Println("All pending txs are added in the pool!") - - return allTxs, nil -} - -// WaitStatusSelected waits for a number of transactions to be marked as selected in the pool -func WaitStatusSelected(countByStatusFunc func(ctx context.Context, status ...pool.TxStatus) (uint64, error), initialCount uint64, nTxs uint64) error { - fmt.Println("Wait for sequencer to select all txs from the pool") - pollingInterval := 1 * time.Second - - prevCount := uint64(0) - txsPerSecond := 0 - txsPerSecondAsStr := "N/A" - estimatedTimeToFinish := "N/A" - err := operations.Poll(pollingInterval, params.DefaultDeadline, func() (bool, error) { - selectedCount, err := countByStatusFunc(params.Ctx, pool.TxStatusSelected) - if err != nil { - return false, err - } - currCount := selectedCount - initialCount - remainingTxs := nTxs - currCount - if prevCount > 0 { - txsPerSecond = int(currCount - prevCount) - if txsPerSecond == 0 { - estimatedTimeToFinish = "N/A" - } else { - estimatedTimeToFinish = (time.Duration(int(remainingTxs)/txsPerSecond) * time.Second).String() - } - txsPerSecondAsStr = strconv.Itoa(txsPerSecond) - } - fmt.Printf("amount of selected txs: %d/%d, estimated txs per second: %s, time to finish: %s\n", selectedCount-initialCount, nTxs, txsPerSecondAsStr, estimatedTimeToFinish) - prevCount = currCount - - done := (int64(selectedCount) - int64(initialCount)) >= int64(nTxs) - return done, nil - }) - - return err -} - -func ShouldRetryError(err error) bool { - return errors.Is(err, state.ErrStateNotSynchronized) || errors.Is(err, state.ErrInsufficientFundsForTransfer) || errors.Is(err, pool.ErrNonceTooHigh) -} diff --git a/test/benchmarks/sequencer/e2e/erc20-transfers/deployment.go b/test/benchmarks/sequencer/e2e/erc20-transfers/deployment.go deleted file mode 100644 index 452fd42f20..0000000000 --- a/test/benchmarks/sequencer/e2e/erc20-transfers/deployment.go +++ /dev/null @@ -1,43 +0,0 @@ -package erc20_transfers - -import ( - "context" - "fmt" - "time" - - "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20" - "github.com/0xPolygonHermez/zkevm-node/test/operations" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" -) - -const ( - txTimeout = 60 * time.Second -) - -func DeployERC20Contract(client *ethclient.Client, ctx context.Context, auth *bind.TransactOpts) (*ERC20.ERC20, error) { - var ( - tx *types.Transaction - err error - ) - fmt.Println("Sending TX to deploy ERC20 SC") - _, tx, erc20SC, err := ERC20.DeployERC20(auth, client, "Test Coin", "TCO") - if err != nil { - panic(err) - } - err = operations.WaitTxToBeMined(ctx, client, tx, txTimeout) - if err != nil { - panic(err) - } - fmt.Println("Sending TX to do a ERC20 mint") - tx, err = erc20SC.Mint(auth, mintAmountBig) - if err != nil { - panic(err) - } - err = operations.WaitTxToBeMined(ctx, client, tx, txTimeout) - if err != nil { - panic(err) - } - return erc20SC, err -} diff --git a/test/benchmarks/sequencer/e2e/erc20-transfers/erc20_test.go b/test/benchmarks/sequencer/e2e/erc20-transfers/erc20_test.go deleted file mode 100644 index 3f813b203d..0000000000 --- a/test/benchmarks/sequencer/e2e/erc20-transfers/erc20_test.go +++ /dev/null @@ -1,80 +0,0 @@ -package erc20_transfers - -import ( - "fmt" - "testing" - "time" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/metrics" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/setup" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/transactions" - "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20" - "github.com/stretchr/testify/require" -) - -const ( - profilingEnabled = false -) - -var ( - erc20SC *ERC20.ERC20 -) - -func BenchmarkSequencerERC20TransfersPoolProcess(b *testing.B) { - var err error - start := time.Now() - opsman, client, pl, auth := setup.Environment(params.Ctx, b) - setup.BootstrapSequencer(b, opsman) - timeForSetup := time.Since(start) - startDeploySCTime := time.Now() - erc20SC, err = DeployERC20Contract(client, params.Ctx, auth) - require.NoError(b, err) - deploySCElapsed := time.Since(startDeploySCTime) - deployMetricsValues, err := metrics.GetValues(nil) - if err != nil { - return - } - allTxs, err := transactions.SendAndWait( - auth, - client, - pl.GetTxsByStatus, - params.NumberOfOperations, - erc20SC, - nil, - TxSender, - ) - require.NoError(b, err) - - var ( - elapsed time.Duration - ) - - elapsed = time.Since(start) - fmt.Printf("Total elapsed time: %s\n", elapsed) - - var profilingResult string - if profilingEnabled { - profilingResult, err = metrics.FetchProfiling() - require.NoError(b, err) - } - - startMetrics := time.Now() - metrics.CalculateAndPrint( - "erc20", - uint64(len(allTxs)), - client, - profilingResult, - elapsed, - deployMetricsValues.SequencerTotalProcessingTime, - deployMetricsValues.ExecutorTotalProcessingTime, - allTxs, - ) - timeForFetchAndPrintMetrics := time.Since(startMetrics) - fmt.Println("########################################") - fmt.Println("# Deploying ERC20 SC and Mint Tx took: #") - fmt.Println("########################################") - fmt.Printf("%s\n", deploySCElapsed) - fmt.Printf("Time for setup: %s\n", timeForSetup) - fmt.Printf("Time for fetching metrics: %s\n", timeForFetchAndPrintMetrics) -} diff --git a/test/benchmarks/sequencer/e2e/erc20-transfers/tx_sender.go b/test/benchmarks/sequencer/e2e/erc20-transfers/tx_sender.go deleted file mode 100644 index a30bc0e679..0000000000 --- a/test/benchmarks/sequencer/e2e/erc20-transfers/tx_sender.go +++ /dev/null @@ -1,47 +0,0 @@ -package erc20_transfers - -import ( - "fmt" - "math/big" - "time" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/transactions" - "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20" - uniswap "github.com/0xPolygonHermez/zkevm-node/test/scripts/uniswap/pkg" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" -) - -const ( - mintAmount = 1000000000000000000 -) - -var ( - sleepTime = 1 * time.Second - mintAmountBig = big.NewInt(mintAmount) - countTxs = 0 -) - -// TxSender sends ERC20 transfer to the sequencer -func TxSender(l2Client *ethclient.Client, gasPrice *big.Int, auth *bind.TransactOpts, erc20SC *ERC20.ERC20, uniswapDeployments *uniswap.Deployments) ([]*types.Transaction, error) { - fmt.Printf("sending tx num: %d\n", countTxs+1) - var actualTransferAmount *big.Int - if countTxs%2 == 0 { - actualTransferAmount = big.NewInt(0) - } else { - actualTransferAmount = big.NewInt(1) - } - tx, err := erc20SC.Transfer(auth, params.To, actualTransferAmount) - if transactions.ShouldRetryError(err) { - time.Sleep(sleepTime) - tx, err = erc20SC.Transfer(auth, params.To, actualTransferAmount) - } - - if err == nil { - countTxs += 1 - } - - return []*types.Transaction{tx}, err -} diff --git a/test/benchmarks/sequencer/e2e/eth-transfers/eth_test.go b/test/benchmarks/sequencer/e2e/eth-transfers/eth_test.go deleted file mode 100644 index 9969eafcf6..0000000000 --- a/test/benchmarks/sequencer/e2e/eth-transfers/eth_test.go +++ /dev/null @@ -1,69 +0,0 @@ -package eth_transfers - -import ( - "fmt" - "testing" - "time" - - "github.com/0xPolygonHermez/zkevm-node/pool" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/metrics" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/setup" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/transactions" - "github.com/stretchr/testify/require" -) - -const ( - profilingEnabled = false -) - -func BenchmarkSequencerEthTransfersPoolProcess(b *testing.B) { - start := time.Now() - //defer func() { require.NoError(b, operations.Teardown()) }() - opsman, client, pl, auth := setup.Environment(params.Ctx, b) - initialCount, err := pl.CountTransactionsByStatus(params.Ctx, pool.TxStatusSelected) - require.NoError(b, err) - timeForSetup := time.Since(start) - setup.BootstrapSequencer(b, opsman) - allTxs, err := transactions.SendAndWait( - auth, - client, - pl.GetTxsByStatus, - params.NumberOfOperations, - nil, - nil, - TxSender, - ) - require.NoError(b, err) - - var ( - elapsed time.Duration - ) - err = transactions.WaitStatusSelected(pl.CountTransactionsByStatus, initialCount, params.NumberOfOperations) - require.NoError(b, err) - elapsed = time.Since(start) - fmt.Printf("Total elapsed time: %s\n", elapsed) - - startMetrics := time.Now() - var profilingResult string - if profilingEnabled { - profilingResult, err = metrics.FetchProfiling() - require.NoError(b, err) - } - - metrics.CalculateAndPrint( - "eth", - uint64(len(allTxs)), - client, - profilingResult, - elapsed, - 0, - 0, - allTxs, - ) - fmt.Printf("%s\n", profilingResult) - timeForFetchAndPrintMetrics := time.Since(startMetrics) - fmt.Printf("Time for setup: %s\n", timeForSetup) - fmt.Printf("Time for fetching metrics: %s\n", timeForFetchAndPrintMetrics) -} diff --git a/test/benchmarks/sequencer/e2e/eth-transfers/tx_sender.go b/test/benchmarks/sequencer/e2e/eth-transfers/tx_sender.go deleted file mode 100644 index 8041bb39cb..0000000000 --- a/test/benchmarks/sequencer/e2e/eth-transfers/tx_sender.go +++ /dev/null @@ -1,56 +0,0 @@ -package eth_transfers - -import ( - "fmt" - "math/big" - "time" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/transactions" - "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20" - uniswap "github.com/0xPolygonHermez/zkevm-node/test/scripts/uniswap/pkg" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" -) - -var ( - gasLimit = 21000 - ethAmount = big.NewInt(0) - sleepTime = 1 * time.Second - countTxs = 0 -) - -// TxSender sends eth transfer to the sequencer -func TxSender(l2Client *ethclient.Client, gasPrice *big.Int, auth *bind.TransactOpts, erc20SC *ERC20.ERC20, uniswapDeployments *uniswap.Deployments) ([]*types.Transaction, error) { - fmt.Printf("sending tx num: %d\n", countTxs+1) - senderNonce, err := l2Client.PendingNonceAt(params.Ctx, auth.From) - if err != nil { - panic(err) - } - tx := types.NewTx(&types.LegacyTx{ - GasPrice: gasPrice, - Gas: uint64(gasLimit), - To: ¶ms.To, - Value: ethAmount, - Data: nil, - Nonce: senderNonce, - }) - - signedTx, err := auth.Signer(auth.From, tx) - if err != nil { - return nil, err - } - - err = l2Client.SendTransaction(params.Ctx, signedTx) - for transactions.ShouldRetryError(err) { - time.Sleep(sleepTime) - err = l2Client.SendTransaction(params.Ctx, signedTx) - } - - if err == nil { - countTxs += 1 - } - - return []*types.Transaction{signedTx}, err -} diff --git a/test/benchmarks/sequencer/e2e/uniswap-transfers/tx_sender.go b/test/benchmarks/sequencer/e2e/uniswap-transfers/tx_sender.go deleted file mode 100644 index ce24b1ab2d..0000000000 --- a/test/benchmarks/sequencer/e2e/uniswap-transfers/tx_sender.go +++ /dev/null @@ -1,44 +0,0 @@ -package uniswap_transfers - -import ( - "fmt" - "math/big" - "strings" - "time" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/transactions" - "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20" - uniswap "github.com/0xPolygonHermez/zkevm-node/test/scripts/uniswap/pkg" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/core/types" - "github.com/ethereum/go-ethereum/ethclient" -) - -var ( - gasLimit = 21000 - sleepTime = 1 * time.Second - countTxs = 0 - txTimeout = 60 * time.Second -) - -// TxSender sends eth transfer to the sequencer -func TxSender(l2Client *ethclient.Client, gasPrice *big.Int, auth *bind.TransactOpts, erc20SC *ERC20.ERC20, uniswapDeployments *uniswap.Deployments) ([]*types.Transaction, error) { - msg := fmt.Sprintf("# Swap Cycle Number: %d #", countTxs+1) - delimiter := strings.Repeat("#", len(msg)) - fmt.Println(delimiter) - fmt.Println(msg) - fmt.Println(delimiter) - var err error - - txs := uniswap.SwapTokens(l2Client, auth, *uniswapDeployments) - for transactions.ShouldRetryError(err) { - time.Sleep(sleepTime) - txs = uniswap.SwapTokens(l2Client, auth, *uniswapDeployments) - } - - if err == nil { - countTxs += 1 - } - - return txs, err -} diff --git a/test/benchmarks/sequencer/e2e/uniswap-transfers/uniswap_test.go b/test/benchmarks/sequencer/e2e/uniswap-transfers/uniswap_test.go deleted file mode 100644 index 169899eb05..0000000000 --- a/test/benchmarks/sequencer/e2e/uniswap-transfers/uniswap_test.go +++ /dev/null @@ -1,66 +0,0 @@ -package uniswap_transfers - -import ( - "fmt" - "testing" - "time" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/metrics" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/setup" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/transactions" - uniswap "github.com/0xPolygonHermez/zkevm-node/test/scripts/uniswap/pkg" - "github.com/stretchr/testify/require" -) - -const ( - profilingEnabled = false -) - -func BenchmarkSequencerUniswapTransfersPoolProcess(b *testing.B) { - start := time.Now() - //defer func() { require.NoError(b, operations.Teardown()) }() - - opsman, client, pl, auth := setup.Environment(params.Ctx, b) - timeForSetup := time.Since(start) - setup.BootstrapSequencer(b, opsman) - deployments := uniswap.DeployContractsAndAddLiquidity(client, auth) - deploymentTxsCount := uniswap.GetExecutedTransactionsCount() - elapsedTimeForDeployments := time.Since(start) - allTxs, err := transactions.SendAndWait( - auth, - client, - pl.GetTxsByStatus, - params.NumberOfOperations, - nil, - &deployments, - TxSender, - ) - require.NoError(b, err) - - elapsed := time.Since(start) - fmt.Printf("Total elapsed time: %s\n", elapsed) - - startMetrics := time.Now() - var profilingResult string - if profilingEnabled { - profilingResult, err = metrics.FetchProfiling() - require.NoError(b, err) - } - - metrics.CalculateAndPrint( - "uniswap", - deploymentTxsCount+uint64(len(allTxs)), - client, - profilingResult, - elapsed, - 0, - 0, - allTxs, - ) - fmt.Printf("%s\n", profilingResult) - timeForFetchAndPrintMetrics := time.Since(startMetrics) - metrics.PrintUniswapDeployments(elapsedTimeForDeployments, deploymentTxsCount) - fmt.Printf("Time for setup: %s\n", timeForSetup) - fmt.Printf("Time for fetching metrics: %s\n", timeForFetchAndPrintMetrics) -} diff --git a/test/benchmarks/sequencer/scripts/.env.example b/test/benchmarks/sequencer/scripts/.env.example deleted file mode 100644 index c7289860ea..0000000000 --- a/test/benchmarks/sequencer/scripts/.env.example +++ /dev/null @@ -1,17 +0,0 @@ -# Bash Variables (Section from Deployment Docs) -BASTION_HOST= -POOLDB_DBNAME= -POOLDB_EP= -POOLDB_PASS= -POOLDB_USER= -POOLDB_PORT=5433 - -# IP/DNS for PUBLIC TESTNET: sequencer.zkevm-public.aws, INTERNAL TESTNET: sequencer.zkevm-internal.aws, DEV TESTNET: sequencer.zkevm-dev.aws -SEQUENCER_IP= - -# Public URLs (Section from Deployment Docs) -RPC_URL= -CHAIN_ID= - -# Your private key -PRIVATE_KEY= \ No newline at end of file diff --git a/test/benchmarks/sequencer/scripts/README.md b/test/benchmarks/sequencer/scripts/README.md deleted file mode 100644 index 882b0fb84e..0000000000 --- a/test/benchmarks/sequencer/scripts/README.md +++ /dev/null @@ -1,51 +0,0 @@ - -# Benchmark Sequencer Scripts - -This repository contains scripts to benchmark a sequencer. The main script is written in Go and can be used to run a series of commands and perform various operations. - -## Usage - -### 1. Clone the repository: - ``` - git clone git@github.com:0xPolygonHermez/zkevm-node.git - cd zkevm-node/test/benchmarks/sequencer/scripts - ``` - -### 2. Setup Environment Variables: - Copy the `.env.example` file to `.env` and populate it with the appropriate values. - - #### Required environment variables are: - - `BASTION_HOST`: The IP address or domain name of the bastion host. (From `Deployments.doc` under `BASH VARIABLES` section for the specific `Environment`) - - `POOLDB_DBNAME`: Database name for the pool. (From `Deployments.doc` under `BASH VARIABLES` section for the specific `Environment`) - - `POOLDB_EP`: Endpoint for the pool database. (From `Deployments.doc` under `BASH VARIABLES` section for the specific `Environment`) - - `POOLDB_PASS`: Password for the pool database. (From `Deployments.doc` under `BASH VARIABLES` section for the specific `Environment`) - - `POOLDB_USER`: User for the pool database. (From `Deployments.doc` under `BASH VARIABLES` section for the specific `Environment`) - - `SEQUENCER_IP`: The IP address of the sequencer. (`sequencer.zkevm-public.aws` for `public testnet`, `sequencer.zkevm-internal.aws` for `internal testnet`, `sequencer.zkevm-dev.aws` for `dev testnet`) - - `RPC_URL`: The URL for the Remote Procedure Call (RPC) server. (From `Deployments.doc` under `Public URLs` section as a bullet point to `RPC` for the specific `Environment`) - - `CHAIN_ID`: The ID of the blockchain network. (From `Deployments.doc` under `Public URLs` section as a bullet point to `RPC` for the specific `Environment`) - - `PRIVATE_KEY`: Your private key. - - #### Optional environment variables: - - `POOLDB_PORT`: Port for the pool database. (Default is `5433`) - - Example: - ``` - cp .env.example .env - nano .env - ``` -### 3. Run the Benchmark Script: - Run the `main.go` script with the following command-line flags: - - `--type`: The type of transactions to test. Accepted values are `eth`, `erc20` or `uniswap`. - - `--num-ops` (optional): The number of operations to run. Default is 200. - - `--help` (optional): Display the help message. - - Example: - ``` - go run main.go --type erc20 --sequencer-ip - ``` - -## Notes - -- Ensure that the `.env` file exists and contains all the required environment variables before running the script. -- The script will perform various operations based on the provided command-line flags and environment variables. -- Ensure that Go is installed on your system to run the script. \ No newline at end of file diff --git a/test/benchmarks/sequencer/scripts/environment/constants.go b/test/benchmarks/sequencer/scripts/environment/constants.go deleted file mode 100644 index 843622e5d6..0000000000 --- a/test/benchmarks/sequencer/scripts/environment/constants.go +++ /dev/null @@ -1,26 +0,0 @@ -package environment - -import ( - "strconv" - - "github.com/0xPolygonHermez/zkevm-node/test/operations" - "github.com/0xPolygonHermez/zkevm-node/test/testutils" -) - -var ( - // IntBase is the base for the conversion of strings to integers - IntBase = 10 - // PrivateKey is the private key of the sequencer - PrivateKey = testutils.GetEnv("PRIVATE_KEY", operations.DefaultSequencerPrivateKey) - // L2ChainId is the chain id of the L2 network - L2ChainId = testutils.GetEnv("CHAIN_ID", strconv.FormatUint(operations.DefaultL2ChainID, IntBase)) - // L2NetworkRPCURL is the RPC URL of the L2 network - L2NetworkRPCURL = testutils.GetEnv("RPC_URL", operations.DefaultL2NetworkURL) - - // PoolDB Credentials - poolDbName = testutils.GetEnv("POOLDB_DBNAME", "pool_db") - poolDbUser = testutils.GetEnv("POOLDB_USER", "pool_user") - poolDbPass = testutils.GetEnv("POOLDB_PASS", "pool_password") - poolDbHost = testutils.GetEnv("POOLDB_HOST", "localhost") - poolDbPort = testutils.GetEnv("POOLDB_PORT", "5433") -) diff --git a/test/benchmarks/sequencer/scripts/environment/init.go b/test/benchmarks/sequencer/scripts/environment/init.go deleted file mode 100644 index e20c8456e9..0000000000 --- a/test/benchmarks/sequencer/scripts/environment/init.go +++ /dev/null @@ -1,81 +0,0 @@ -package environment - -import ( - "context" - "fmt" - "math/big" - "strconv" - "strings" - - "github.com/0xPolygonHermez/zkevm-node/db" - "github.com/0xPolygonHermez/zkevm-node/pool/pgpoolstorage" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/ethereum/go-ethereum/accounts/abi/bind" - "github.com/ethereum/go-ethereum/crypto" - "github.com/ethereum/go-ethereum/ethclient" -) - -var ( - maxConnections = 10 - bitSize = 64 -) - -// Init sets up the environment for the benchmark -func Init() (*pgpoolstorage.PostgresPoolStorage, *ethclient.Client, *bind.TransactOpts) { - ctx := context.Background() - pl, err := pgpoolstorage.NewPostgresPoolStorage(db.Config{ - Name: poolDbName, - User: poolDbUser, - Password: poolDbPass, - Host: poolDbHost, - Port: poolDbPort, - EnableLog: false, - MaxConns: maxConnections, - }) - if err != nil { - panic(err) - } - - l2Client, err := ethclient.Dial(L2NetworkRPCURL) - if err != nil { - panic(err) - } - // PrivateKey is the private key of the sender - privateKey, err := crypto.HexToECDSA(strings.TrimPrefix(PrivateKey, "0x")) - if err != nil { - panic(err) - } - chainId, err := strconv.ParseUint(L2ChainId, IntBase, bitSize) - if err != nil { - panic(err) - } - fmt.Printf("L2ChainId: %d\n", chainId) - // Auth is the auth of the sender - auth, err := bind.NewKeyedTransactorWithChainID(privateKey, new(big.Int).SetUint64(chainId)) - if err != nil { - panic(err) - } - // Print Info before send - senderBalance, err := l2Client.BalanceAt(ctx, auth.From, nil) - if err != nil { - panic(err) - } - senderNonce, err := l2Client.PendingNonceAt(ctx, auth.From) - if err != nil { - panic(err) - } - - // Print Initial Stats - fmt.Printf("Receiver Addr: %v\n", params.To.String()) - fmt.Printf("Sender Addr: %v\n", auth.From.String()) - fmt.Printf("Sender Balance: %v\n", senderBalance.String()) - fmt.Printf("Sender Nonce: %v\n", senderNonce) - - gasPrice, err := l2Client.SuggestGasPrice(ctx) - if err != nil { - panic(err) - } - auth.GasPrice = gasPrice - - return pl, l2Client, auth -} diff --git a/test/benchmarks/sequencer/scripts/erc20-transfers/main.go b/test/benchmarks/sequencer/scripts/erc20-transfers/main.go deleted file mode 100644 index 8039abdfeb..0000000000 --- a/test/benchmarks/sequencer/scripts/erc20-transfers/main.go +++ /dev/null @@ -1,57 +0,0 @@ -package main - -import ( - "flag" - "fmt" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/metrics" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/scripts/environment" - - "github.com/0xPolygonHermez/zkevm-node/pool" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/transactions" - erc20transfers "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/e2e/erc20-transfers" -) - -func main() { - var ( - err error - ) - - numOps := flag.Uint64("num-ops", 200, "The number of operations to run. Default is 200.") - flag.Parse() - - if numOps == nil { - panic("numOps is nil") - } - - pl, l2Client, auth := environment.Init() - initialCount, err := pl.CountTransactionsByStatus(params.Ctx, pool.TxStatusSelected) - if err != nil { - panic(err) - } - - erc20SC, err := erc20transfers.DeployERC20Contract(l2Client, params.Ctx, auth) - - allTxs, err := transactions.SendAndWait( - auth, - l2Client, - pl.GetTxsByStatus, - *numOps, - erc20SC, - nil, - erc20transfers.TxSender, - ) - if err != nil { - panic(err) - } - - // Wait for Txs to be selected - err = transactions.WaitStatusSelected(pl.CountTransactionsByStatus, initialCount, *numOps) - if err != nil { - panic(err) - } - - totalGas := metrics.GetTotalGasUsedFromTxs(l2Client, allTxs) - fmt.Println("Total Gas: ", totalGas) -} diff --git a/test/benchmarks/sequencer/scripts/eth-transfers/main.go b/test/benchmarks/sequencer/scripts/eth-transfers/main.go deleted file mode 100644 index 9b24d7a52e..0000000000 --- a/test/benchmarks/sequencer/scripts/eth-transfers/main.go +++ /dev/null @@ -1,52 +0,0 @@ -package main - -import ( - "flag" - "fmt" - - "github.com/0xPolygonHermez/zkevm-node/pool" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/metrics" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/transactions" - ethtransfers "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/e2e/eth-transfers" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/scripts/environment" -) - -func main() { - var ( - err error - ) - numOps := flag.Uint64("num-ops", 200, "The number of operations to run. Default is 200.") - flag.Parse() - if numOps == nil { - panic("numOps is nil") - } - - pl, l2Client, auth := environment.Init() - initialCount, err := pl.CountTransactionsByStatus(params.Ctx, pool.TxStatusSelected) - if err != nil { - panic(err) - } - - allTxs, err := transactions.SendAndWait( - auth, - l2Client, - pl.GetTxsByStatus, - *numOps, - nil, - nil, - ethtransfers.TxSender, - ) - if err != nil { - panic(err) - } - - // Wait for Txs to be selected - err = transactions.WaitStatusSelected(pl.CountTransactionsByStatus, initialCount, *numOps) - if err != nil { - panic(err) - } - - totalGas := metrics.GetTotalGasUsedFromTxs(l2Client, allTxs) - fmt.Println("Total Gas: ", totalGas) -} diff --git a/test/benchmarks/sequencer/scripts/main.go b/test/benchmarks/sequencer/scripts/main.go deleted file mode 100644 index bdefb4abf6..0000000000 --- a/test/benchmarks/sequencer/scripts/main.go +++ /dev/null @@ -1,348 +0,0 @@ -package main - -import ( - "bufio" - "errors" - "flag" - "fmt" - "os" - "os/exec" - "strconv" - "strings" - "time" - - "github.com/joho/godotenv" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/metrics" -) - -const ( - maxRetryAttempts = 5 - retryDelay = 1 * time.Second -) - -func main() { - fmt.Println("Starting the program...") - fmt.Println("-----------------------") - - // Command line flags - tType := flag.String("type", "", "The type of transactions to test: erc20, uniswap, or eth.") - numOps := flag.Int("num-ops", 200, "The number of operations to run. Default is 200.") - help := flag.Bool("help", false, "Display help message") - flag.Parse() - - if *help { - fmt.Println("Usage: go run main.go --type TRANSACTIONS_TYPE --sequencer-ip SEQUENCER_IP [--num-ops NUMBER_OF_OPERATIONS]") - flag.PrintDefaults() - return - } - - // Check if .env file exists - if _, err := os.Stat(".env"); os.IsNotExist(err) { - panic(fmt.Sprintf("Error: .env file does not exist. Please create it and add all environment variables from the Deployment Docs." + - "\n ** check env.exmaple for an example. **")) - } - - fmt.Println("Loading .env file...") - fmt.Println("--------------------") - // Load .env file - err := godotenv.Load(".env") - if err != nil { - panic(fmt.Sprintf("Error loading .env file: %v", err)) - } - - fmt.Println("Validating TYPE...") - fmt.Println("------------------") - // Validate TYPE - if *tType == "" || (*tType != "erc20" && *tType != "uniswap" && *tType != "eth") { - panic(fmt.Sprintf("Error: Invalid TYPE argument. Accepted values are 'erc20', 'uniswap', or 'eth'.")) - } - - fmt.Println("Checking environment variables...") - fmt.Println("---------------------------------") - // Check environment variables - checkEnvVar("BASTION_HOST") - checkEnvVar("POOLDB_PORT") - checkEnvVar("POOLDB_EP") - checkEnvVar("RPC_URL") - checkEnvVar("CHAIN_ID") - checkEnvVar("PRIVATE_KEY") - checkEnvVar("SEQUENCER_IP") - - // Forward BASTION Ports - fmt.Println("Forwarding BASTION ports...") - fmt.Println("---------------------------") - sshArgs := []string{"-fN", - "-L", os.Getenv("POOLDB_PORT") + ":" + os.Getenv("POOLDB_EP") + ":5432", - "ubuntu@" + os.Getenv("BASTION_HOST")} - _, err = runCmd("ssh", sshArgs...) - if err != nil { - panic(fmt.Sprintf("Failed to forward BASTION ports: %v", err)) - } - defer killSSHProcess(err) - - // Execute wget to get metrics from the BASTION HOST - sequencerIP := os.Getenv("SEQUENCER_IP") - fmt.Println("Fetching start metrics...") - fmt.Println("--------------------------") - - output, err := retryCmd("ssh", "ubuntu@"+os.Getenv("BASTION_HOST"), "wget", "-qO-", "http://"+sequencerIP+":9091/metrics") - if err != nil { - panic(fmt.Sprintf("Failed to collect start metrics from BASTION HOST: %v", err)) - } - retryTimes := 0 - if err != nil { - fmt.Println(fmt.Sprintf("Failed to collect start metrics from BASTION HOST: %v", err)) - fmt.Println("Retrying...") - time.Sleep(1 * time.Second) - output, err = runCmd("ssh", "ubuntu@"+os.Getenv("BASTION_HOST"), "wget", "-qO-", "http://"+sequencerIP+":9091/metrics") - retryTimes++ - if retryTimes == 5 { - panic(fmt.Sprintf("Failed to collect start metrics from BASTION HOST: %v", err)) - } - } - - err = os.WriteFile("start-metrics.txt", []byte(output), 0644) - if err != nil { - panic(fmt.Sprintf("Failed to write start metrics to file: %v", err)) - } - - // Run the Go script depending on the type argument - var goScript string - switch *tType { - case "erc20": - goScript = "erc20-transfers" - case "uniswap": - goScript = "uniswap-transfers" - case "eth": - goScript = "eth-transfers" - } - - // Run transfers script - fmt.Println("Running transfers script...") - fmt.Println("---------------------------") - lastLine, err := runCmdRealTime("go", "run", "./"+goScript+"/main.go", "--num-ops", strconv.Itoa(*numOps)) - if err != nil { - panic(fmt.Sprintf("Failed to run Go script for %s transactions: %v", *tType, err)) - } - - // Extract Total Gas - fmt.Println("Extracting Total Gas...") - fmt.Println("-----------------------") - var totalGas string - if strings.Contains(lastLine, "Total Gas") { - parts := strings.Split(lastLine, " ") - totalGas = parts[len(parts)-1] - } - if totalGas == "" { - fmt.Println("Warning: Failed to extract Total Gas from Go script output.") - } - - // Execute wget to get metrics from the BASTION HOST - fmt.Println("Fetching end metrics...") - fmt.Println("------------------------") - output, err = retryCmd("ssh", "ubuntu@"+os.Getenv("BASTION_HOST"), "wget", "-qO-", "http://"+sequencerIP+":9091/metrics") - if err != nil { - panic(fmt.Sprintf("Failed to collect end metrics from BASTION HOST: %v", err)) - } - err = os.WriteFile("end-metrics.txt", []byte(output), 0644) - if err != nil { - panic(fmt.Sprintf("Failed to write end metrics to file: %v", err)) - } - - // Run the Go script that calculates the metrics and prints the results - totalGasInt, err := strconv.ParseUint(totalGas, 10, 64) - if err != nil { - fmt.Printf("Failed to convert totalGas to int: %v\n", err) - } - - // Calc and Print Results - fmt.Println("Calculating and printing results...") - fmt.Printf("------------------------------------\n\n") - calculateAndPrintResults(*tType, totalGasInt, uint64(*numOps)) - - fmt.Println("Done!") -} - -func runCmd(command string, args ...string) (string, error) { - cmd := exec.Command(command, args...) - output, err := cmd.CombinedOutput() - return string(output), err -} - -// runCmdWithRetry executes the specified command with arguments and returns the combined output. -// It includes a retryCmd mechanism controlled by the enableRetry flag. -func runCmdWithRetry(enableRetry bool, command string, args ...string) (string, error) { - var output string - var err error - - if enableRetry { - for attempt := 1; attempt <= maxRetryAttempts; attempt++ { - cmd := exec.Command(command, args...) - cmd.Stderr = os.Stderr - result, runErr := cmd.CombinedOutput() - output = string(result) - err = runErr - - if err == nil { - // Command succeeded, no need to retryCmd. - break - } - - fmt.Printf("Attempt %d: Command failed: %v\n", attempt, err) - - if attempt < maxRetryAttempts { - fmt.Println("Retrying...") - time.Sleep(time.Second) // Add a delay between retries (you can adjust the duration). - } - } - } else { - cmd := exec.Command(command, args...) - cmd.Stderr = os.Stderr - result, runErr := cmd.CombinedOutput() - output = string(result) - err = runErr - } - - return output, err -} - -func runCmdRealTime(command string, args ...string) (string, error) { - cmd := exec.Command(command, args...) - stdoutIn, _ := cmd.StdoutPipe() - stderrIn, _ := cmd.StderrPipe() - - cmd.Start() - - var lastLine string - go func() { - scanner := bufio.NewScanner(stdoutIn) - for scanner.Scan() { - line := scanner.Text() - fmt.Println(line) - lastLine = line - } - }() - - go func() { - scanner := bufio.NewScanner(stderrIn) - for scanner.Scan() { - m := scanner.Text() - _, err := fmt.Fprintln(os.Stderr, m) - if err != nil { - fmt.Println("Error printing stderr: ", err) - return - } - } - }() - - err := cmd.Wait() - if err != nil { - return "", err - } - return lastLine, nil -} - -func checkEnvVar(varName string) { - if os.Getenv(varName) == "" { - panic(fmt.Sprintf("Error: %s is not set. Please export all environment variables from the Deployment Docs.", varName)) - } -} - -func killSSHProcess(err error) { - fmt.Println("Killing SSH process...") - _, err = runCmd("pkill", "-f", "ssh -fN -L "+os.Getenv("POOLDB_PORT")) - if err != nil { - panic(fmt.Sprintf("Failed to kill the SSH process: %v", err)) - } -} - -func calculateAndPrintResults(txsType string, totalGas uint64, numberOfOperations uint64) { - totalTransactionsSent := numberOfOperations - - startData := parseFile("start-metrics.txt") - endData := parseFile("end-metrics.txt") - - totalTxs := uint64(endData["sequencer_processing_time"].processingTimeCount - startData["sequencer_processing_time"].processingTimeCount) - - processingTimeSequencer := endData["sequencer_processing_time"].processingTimeSum - startData["sequencer_processing_time"].processingTimeSum - processingTimeExecutor := endData["state_executor_processing_time{caller=\"sequencer\"}"].processingTimeSum - startData["state_executor_processing_time{caller=\"sequencer\"}"].processingTimeSum - - fmt.Println("########################") - fmt.Println("# Results #") - fmt.Printf("########################\n\n") - - metrics.PrintSummary( - txsType, - totalTransactionsSent, - totalTxs, - processingTimeSequencer, - processingTimeExecutor, - totalGas, - ) -} - -type timeData struct { - processingTimeSum float64 - processingTimeCount int -} - -func parseLine(line string) (key string, value float64) { - parts := strings.Split(line, " ") - key = parts[0] - value, _ = strconv.ParseFloat(parts[1], 64) - return -} - -func parseFile(filename string) map[string]timeData { - file, err := os.Open(filename) - if err != nil { - fmt.Println("Error opening file:", err) - return nil - } - defer file.Close() - - result := map[string]timeData{} - scanner := bufio.NewScanner(file) - - for scanner.Scan() { - line := scanner.Text() - key, value := parseLine(line) - if strings.Contains(key, "sum") { - key = strings.Replace(key, "_sum", "", -1) - if data, ok := result[key]; ok { - data.processingTimeSum = value - result[key] = data - } else { - result[key] = timeData{processingTimeSum: value} - } - } else if strings.Contains(key, "count") { - key = strings.Replace(key, "_count", "", -1) - if data, ok := result[key]; ok { - data.processingTimeCount = int(value) - result[key] = data - } else { - result[key] = timeData{processingTimeCount: int(value)} - } - } - } - - return result -} - -func retryCmd(command string, args ...string) (string, error) { - - for i := 0; i < maxRetryAttempts; i++ { - result, err := runCmd(command, args...) - if err == nil { - return result, nil // If the function succeeded, return its result. - } - - // If it failed and it's not the last attempt, wait for the specified delay before retrying. - if i < maxRetryAttempts-1 { - time.Sleep(retryDelay) - } - } - - return "", errors.New("maximum retryCmd attempts reached") -} diff --git a/test/benchmarks/sequencer/scripts/uniswap-transfers/main.go b/test/benchmarks/sequencer/scripts/uniswap-transfers/main.go deleted file mode 100644 index fc269e6514..0000000000 --- a/test/benchmarks/sequencer/scripts/uniswap-transfers/main.go +++ /dev/null @@ -1,61 +0,0 @@ -package main - -import ( - "flag" - "fmt" - "time" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/scripts/environment" - - "github.com/0xPolygonHermez/zkevm-node/pool" - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/params" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/metrics" - - "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/common/transactions" - uniswaptransfers "github.com/0xPolygonHermez/zkevm-node/test/benchmarks/sequencer/e2e/uniswap-transfers" - uniswap "github.com/0xPolygonHermez/zkevm-node/test/scripts/uniswap/pkg" -) - -func main() { - var ( - err error - ) - numOps := flag.Uint64("num-ops", 200, "The number of operations to run. Default is 200.") - flag.Parse() - if numOps == nil { - panic("numOps is nil") - } - pl, l2Client, auth := environment.Init() - initialCount, err := pl.CountTransactionsByStatus(params.Ctx, pool.TxStatusSelected) - if err != nil { - panic(err) - } - start := time.Now() - deployments := uniswap.DeployContractsAndAddLiquidity(l2Client, auth) - deploymentTxsCount := uniswap.GetExecutedTransactionsCount() - elapsedTimeForDeployments := time.Since(start) - - allTxs, err := transactions.SendAndWait( - auth, - l2Client, - pl.GetTxsByStatus, - *numOps, - nil, - &deployments, - uniswaptransfers.TxSender, - ) - if err != nil { - panic(err) - } - - // Wait for Txs to be selected - err = transactions.WaitStatusSelected(pl.CountTransactionsByStatus, initialCount, *numOps) - if err != nil { - panic(err) - } - - metrics.PrintUniswapDeployments(elapsedTimeForDeployments, deploymentTxsCount) - totalGas := metrics.GetTotalGasUsedFromTxs(l2Client, allTxs) - fmt.Println("Total Gas: ", totalGas) -} diff --git a/test/config/debug.node.config.toml b/test/config/debug.node.config.toml index 32bbdd7f56..5072e9f5a1 100644 --- a/test/config/debug.node.config.toml +++ b/test/config/debug.node.config.toml @@ -103,6 +103,9 @@ StateConsistencyCheckInterval = "5s" HaltOnBatchNumber = 0 SequentialBatchSanityCheck = false SequentialProcessL2Block = true + [Sequencer.Finalizer.Metrics] + Interval = "60m" + EnableLog = true [Sequencer.StreamServer] Port = 6900 Filename = "/datastreamer/datastream.bin" diff --git a/test/config/test.node.config.toml b/test/config/test.node.config.toml index 5b7f467457..aa3ca72a64 100644 --- a/test/config/test.node.config.toml +++ b/test/config/test.node.config.toml @@ -117,6 +117,9 @@ StateConsistencyCheckInterval = "5s" HaltOnBatchNumber = 0 SequentialBatchSanityCheck = false SequentialProcessL2Block = true + [Sequencer.Finalizer.Metrics] + Interval = "60m" + EnableLog = true [Sequencer.StreamServer] Port = 6900 Filename = "/datastreamer/datastream.bin" From fe1daccb5389d9fd1a1825c350310dbd01f4d8fd Mon Sep 17 00:00:00 2001 From: Joan Esteban <129153821+joanestebanr@users.noreply.github.com> Date: Tue, 27 Feb 2024 17:41:53 +0100 Subject: [PATCH 34/51] Feature/cherry pick 3370 3374 synchronizer, fix bugs, ReprocessFullBatchOnClose and AcceptEmptyClosedBatches (#3384) * synchronizer accepts empty closed batches from trusted depending on config (#3370) * accept empty closed batches depending on config * if trusted synchronization dont create L2 sync classes * sync reprocess full batch on close, check GER, and fix minor bugs (#3374) * sync reprocess full batch on close * reduce the of live of batch cache from 1hour to 5min * fix reprocess, check virtualBatch before reseting state * #3376 - check GlobalExitRoot before working on a batch * update same data as updateWIPBatch do in the cache of batches * set Synchronizer.L2Synchronization.ReprocessFullBatchOnClose to false * update documentation --- config/config_test.go | 8 + config/default.go | 3 + docs/config-file/node-config-doc.html | 2 +- docs/config-file/node-config-doc.md | 40 ++++ docs/config-file/node-config-schema.json | 17 ++ jsonrpc/client/zkevm_test.go | 25 +++ state/batch.go | 2 +- state/pgstatestorage/l2block.go | 3 +- synchronizer/config.go | 3 + synchronizer/ext_control.go | 203 ++++++++++++++---- synchronizer/l2_sync/config.go | 11 + .../mocks/l1_sync_global_exit_root_checker.go | 89 ++++++++ .../l2_shared/processor_trusted_batch_sync.go | 76 ++++++- .../processor_trusted_batch_sync_test.go | 88 +++++++- .../check_sync_status_to_process_batch.go | 8 +- ...check_sync_status_to_process_batch_test.go | 14 +- .../executor_trusted_batch_sync.go | 89 ++++---- .../executor_trusted_batch_sync_test.go | 72 ++++++- .../l2_sync_etrog/mocks/l1_sync_checker.go | 89 -------- .../l2_sync_etrog/mocks/state_interface.go | 57 +++++ synchronizer/synchronizer.go | 20 +- 21 files changed, 706 insertions(+), 213 deletions(-) create mode 100644 jsonrpc/client/zkevm_test.go create mode 100644 synchronizer/l2_sync/config.go create mode 100644 synchronizer/l2_sync/l2_shared/mocks/l1_sync_global_exit_root_checker.go delete mode 100644 synchronizer/l2_sync/l2_sync_etrog/mocks/l1_sync_checker.go diff --git a/config/config_test.go b/config/config_test.go index 6cd4ad0863..f2e01575b8 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -52,6 +52,14 @@ func Test_Defaults(t *testing.T) { path: "Synchronizer.L1ParallelSynchronization.MaxPendingNoProcessedBlocks", expectedValue: uint64(25), }, + { + path: "Synchronizer.L2Synchronization.AcceptEmptyClosedBatches", + expectedValue: false, + }, + { + path: "Synchronizer.L2Synchronization.ReprocessFullBatchOnClose", + expectedValue: false, + }, { path: "Sequencer.DeletePoolTxsL1BlockConfirmations", expectedValue: uint64(100), diff --git a/config/default.go b/config/default.go index 8aaa092969..b28076b251 100644 --- a/config/default.go +++ b/config/default.go @@ -116,6 +116,9 @@ L1SynchronizationMode = "sequential" [Synchronizer.L1ParallelSynchronization.PerformanceWarning] AceptableInacctivityTime = "5s" ApplyAfterNumRollupReceived = 10 + [Synchronizer.L2Synchronization] + AcceptEmptyClosedBatches = false + ReprocessFullBatchOnClose = false [Sequencer] DeletePoolTxsL1BlockConfirmations = 100 diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index 6adbe3cac5..d76299260d 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -28,7 +28,7 @@
"300ms"
 

Default: "5s"Type: string

RollupInfoRetriesSpacing is the minimum time between retries to request rollup info (it will sleep for fulfill this time) to avoid spamming L1


Examples:

"1m"
 
"300ms"
-

Default: falseType: boolean

FallbackToSequentialModeOnSynchronized if true switch to sequential mode if the system is synchronized


Configuration of the sequencer service
Default: 100Type: integer

DeletePoolTxsL1BlockConfirmations is blocks amount after which txs will be deleted from the pool


Default: "12h0m0s"Type: string

DeletePoolTxsCheckInterval is frequency with which txs will be checked for deleting


Examples:

"1m"
+

Default: falseType: boolean

FallbackToSequentialModeOnSynchronized if true switch to sequential mode if the system is synchronized


L2Synchronization Configuration for L2 synchronization
Default: falseType: boolean

AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.
if true, the synchronizer will accept empty batches and process them.


Default: falseType: boolean

ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again


Configuration of the sequencer service
Default: 100Type: integer

DeletePoolTxsL1BlockConfirmations is blocks amount after which txs will be deleted from the pool


Default: "12h0m0s"Type: string

DeletePoolTxsCheckInterval is frequency with which txs will be checked for deleting


Examples:

"1m"
 
"300ms"
 

Default: "10m0s"Type: string

TxLifetimeCheckInterval is the time the sequencer waits to check txs lifetime


Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index e92f404f2f..5ca12d7e8b 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -1341,6 +1341,7 @@ because depending of this values is going to ask to a trusted node for trusted t
 | - [TrustedSequencerURL](#Synchronizer_TrustedSequencerURL )             | No      | string           | No         | -          | TrustedSequencerURL is the rpc url to connect and sync the trusted state                                                                                                                                                                                |
 | - [L1SynchronizationMode](#Synchronizer_L1SynchronizationMode )         | No      | enum (of string) | No         | -          | L1SynchronizationMode define how to synchronize with L1:
- parallel: Request data to L1 in parallel, and process sequentially. The advantage is that executor is not blocked waiting for L1 data
- sequential: Request data to L1 and execute | | - [L1ParallelSynchronization](#Synchronizer_L1ParallelSynchronization ) | No | object | No | - | L1ParallelSynchronization Configuration for parallel mode (if L1SynchronizationMode equal to 'parallel') | +| - [L2Synchronization](#Synchronizer_L2Synchronization ) | No | object | No | - | L2Synchronization Configuration for L2 synchronization | ### 9.1. `Synchronizer.SyncInterval` @@ -1677,6 +1678,45 @@ RollupInfoRetriesSpacing="5s" FallbackToSequentialModeOnSynchronized=false ``` +### 9.6. `[Synchronizer.L2Synchronization]` + +**Type:** : `object` +**Description:** L2Synchronization Configuration for L2 synchronization + +| Property | Pattern | Type | Deprecated | Definition | Title/Description | +| ----------------------------------------------------------------------------------------- | ------- | ------- | ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| - [AcceptEmptyClosedBatches](#Synchronizer_L2Synchronization_AcceptEmptyClosedBatches ) | No | boolean | No | - | AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.
if true, the synchronizer will accept empty batches and process them. | +| - [ReprocessFullBatchOnClose](#Synchronizer_L2Synchronization_ReprocessFullBatchOnClose ) | No | boolean | No | - | ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again | + +#### 9.6.1. `Synchronizer.L2Synchronization.AcceptEmptyClosedBatches` + +**Type:** : `boolean` + +**Default:** `false` + +**Description:** AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches. +if true, the synchronizer will accept empty batches and process them. + +**Example setting the default value** (false): +``` +[Synchronizer.L2Synchronization] +AcceptEmptyClosedBatches=false +``` + +#### 9.6.2. `Synchronizer.L2Synchronization.ReprocessFullBatchOnClose` + +**Type:** : `boolean` + +**Default:** `false` + +**Description:** ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again + +**Example setting the default value** (false): +``` +[Synchronizer.L2Synchronization] +ReprocessFullBatchOnClose=false +``` + ## 10. `[Sequencer]` **Type:** : `object` diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json index 6c0adc1261..3d8842e926 100644 --- a/docs/config-file/node-config-schema.json +++ b/docs/config-file/node-config-schema.json @@ -624,6 +624,23 @@ "additionalProperties": false, "type": "object", "description": "L1ParallelSynchronization Configuration for parallel mode (if L1SynchronizationMode equal to 'parallel')" + }, + "L2Synchronization": { + "properties": { + "AcceptEmptyClosedBatches": { + "type": "boolean", + "description": "AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.\nif true, the synchronizer will accept empty batches and process them.", + "default": false + }, + "ReprocessFullBatchOnClose": { + "type": "boolean", + "description": "ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again", + "default": false + } + }, + "additionalProperties": false, + "type": "object", + "description": "L2Synchronization Configuration for L2 synchronization" } }, "additionalProperties": false, diff --git a/jsonrpc/client/zkevm_test.go b/jsonrpc/client/zkevm_test.go new file mode 100644 index 0000000000..21b4870d1f --- /dev/null +++ b/jsonrpc/client/zkevm_test.go @@ -0,0 +1,25 @@ +package client + +import ( + "context" + "fmt" + "math/big" + "testing" + + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/stretchr/testify/require" +) + +func TestZkevmGetBatch(t *testing.T) { + t.Skip("This test is exploratory") + // Create a new client + client := NewClient("https://zkevm-rpc.com/") + lastTrustedStateBatchNumberSeen, err := client.BatchNumber(context.Background()) + require.NoError(t, err) + log.Info("lastTrustedStateBatchNumberSeen: ", lastTrustedStateBatchNumberSeen) + batch, err := client.BatchByNumber(context.Background(), big.NewInt(int64(lastTrustedStateBatchNumberSeen))) + require.NoError(t, err) + + // Print the batch + fmt.Println(batch) +} diff --git a/state/batch.go b/state/batch.go index 09b329ee5f..7cf10ebeab 100644 --- a/state/batch.go +++ b/state/batch.go @@ -173,7 +173,7 @@ func (s *State) OpenBatch(ctx context.Context, processingContext ProcessingConte return err } if prevTimestamp.Unix() > processingContext.Timestamp.Unix() { - return ErrTimestampGE + return fmt.Errorf(" oldBatch(%d) tstamp=%d > openingBatch(%d)=%d err: %w", lastBatchNum, prevTimestamp.Unix(), processingContext.BatchNumber, processingContext.Timestamp.Unix(), ErrTimestampGE) } return s.OpenBatchInStorage(ctx, processingContext, dbTx) } diff --git a/state/pgstatestorage/l2block.go b/state/pgstatestorage/l2block.go index f86b10d26d..fac23ce6ce 100644 --- a/state/pgstatestorage/l2block.go +++ b/state/pgstatestorage/l2block.go @@ -197,7 +197,8 @@ func (p *PostgresStorage) AddL2Block(ctx context.Context, batchNumber uint64, l2 } uncles = string(unclesBytes) } - + l2blockNumber := l2Block.Number().Uint64() + log.Debugf("[AddL2Block] adding L2 block %d", l2blockNumber) if _, err := e.Exec(ctx, addL2BlockSQL, l2Block.Number().Uint64(), l2Block.Hash().String(), header, uncles, l2Block.ParentHash().String(), l2Block.Root().String(), diff --git a/synchronizer/config.go b/synchronizer/config.go index 774c55dd37..e1716d7687 100644 --- a/synchronizer/config.go +++ b/synchronizer/config.go @@ -2,6 +2,7 @@ package synchronizer import ( "github.com/0xPolygonHermez/zkevm-node/config/types" + "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync" ) // Config represents the configuration of the synchronizer @@ -19,6 +20,8 @@ type Config struct { L1SynchronizationMode string `jsonschema:"enum=sequential,enum=parallel"` // L1ParallelSynchronization Configuration for parallel mode (if L1SynchronizationMode equal to 'parallel') L1ParallelSynchronization L1ParallelSynchronizationConfig + // L2Synchronization Configuration for L2 synchronization + L2Synchronization l2_sync.Config `mapstructure:"L2Synchronization"` } // L1ParallelSynchronizationConfig Configuration for parallel mode (if UL1SynchronizationMode equal to 'parallel') diff --git a/synchronizer/ext_control.go b/synchronizer/ext_control.go index 0ca2840dca..289d0e27ea 100644 --- a/synchronizer/ext_control.go +++ b/synchronizer/ext_control.go @@ -2,6 +2,8 @@ package synchronizer import ( "bufio" + "errors" + "fmt" "io" "os" "strconv" @@ -14,6 +16,7 @@ import ( const ( externalControlFilename = "/tmp/synchronizer_in" + externalOutputFilename = "/tmp/synchronizer_out" filePermissions = 0644 sleepTimeToReadFile = 500 * time.Millisecond ) @@ -28,16 +31,58 @@ const ( // example of usage (first you need to run the service): // echo "l1_producer_stop" >> /tmp/synchronizer_in // echo "l1_orchestrator_reset|8577060" >> /tmp/synchronizer_in -type externalControl struct { - producer *l1_parallel_sync.L1RollupInfoProducer - orquestrator *l1_parallel_sync.L1SyncOrchestration + +// ExtCmdArgs is the type of the arguments of the command +type ExtCmdArgs []string + +// ExtControlCmd is the interface of the external command +type ExtControlCmd interface { + // FunctionName returns the name of the function to be called example: "l1_producer_stop" + FunctionName() string + // ValidateArguments validates the arguments of the command, returns nil if ok, error if not + ValidateArguments(ExtCmdArgs) error + // Process the command + // args: the arguments of the command + // return: string with the output and an error + Process(ExtCmdArgs) (string, error) + // Help returns the help of the command + Help() string +} + +type externalCmdControl struct { + //producer *l1_parallel_sync.L1RollupInfoProducer + //orquestrator *l1_parallel_sync.L1SyncOrchestration + RegisteredCmds map[string]ExtControlCmd +} + +func newExternalCmdControl(producer *l1_parallel_sync.L1RollupInfoProducer, orquestrator *l1_parallel_sync.L1SyncOrchestration) *externalCmdControl { + res := &externalCmdControl{ + RegisteredCmds: make(map[string]ExtControlCmd), + } + res.RegisterCmd(&helpCmd{externalControl: res}) + res.RegisterCmd(&l1OrchestratorResetCmd{orquestrator: orquestrator}) + res.RegisterCmd(&l1ProducerStopCmd{producer: producer}) + return res } -func newExternalControl(producer *l1_parallel_sync.L1RollupInfoProducer, orquestrator *l1_parallel_sync.L1SyncOrchestration) *externalControl { - return &externalControl{producer: producer, orquestrator: orquestrator} +// RegisterCmd registers a command +func (e *externalCmdControl) RegisterCmd(cmd ExtControlCmd) { + if e.RegisteredCmds == nil { + e.RegisteredCmds = make(map[string]ExtControlCmd) + } + e.RegisteredCmds[cmd.FunctionName()] = cmd } -func (e *externalControl) start() { +// GetCmd returns a command by its name +func (e *externalCmdControl) GetCmd(functionName string) (ExtControlCmd, error) { + cmd, ok := e.RegisteredCmds[functionName] + if !ok { + return nil, errors.New("command not found") + } + return cmd, nil +} + +func (e *externalCmdControl) start() { log.Infof("EXT:start: starting external control opening %s", externalControlFilename) file, err := os.OpenFile(externalControlFilename, os.O_APPEND|os.O_CREATE|os.O_RDONLY, filePermissions) if err != nil { @@ -52,7 +97,7 @@ func (e *externalControl) start() { } // https://medium.com/@arunprabhu.1/tailing-a-file-in-golang-72944204f22b -func (e *externalControl) readFile(file *os.File) { +func (e *externalCmdControl) readFile(file *os.File) { defer file.Close() reader := bufio.NewReader(file) for { @@ -65,66 +110,134 @@ func (e *externalControl) readFile(file *os.File) { time.Sleep(sleepTimeToReadFile) continue } - break } log.Infof("EXT:readFile: new command: %s", line) - e.process(line) + cmd, cmdArgs, err := e.parse(line) + if err != nil { + log.Warnf("EXT:readFile: error parsing command %s:err %s", line, err) + continue + } + e.process(cmd, cmdArgs) } } } -func (e *externalControl) process(line string) { +func (e *externalCmdControl) parse(line string) (ExtControlCmd, ExtCmdArgs, error) { cmd := strings.Split(line, "|") if len(cmd) < 1 { - return + return nil, nil, errors.New("invalid command") } - switch strings.TrimSpace(cmd[0]) { - case "l1_producer_stop": - e.cmdL1ProducerStop(cmd[1:]) - case "l1_orchestrator_reset": - e.cmdL1OrchestratorReset(cmd[1:]) - case "l1_orchestrator_stop": - e.cmdL1OrchestratorAbort(cmd[1:]) - default: - log.Warnf("EXT:process: unknown command: %s", cmd[0]) + functionName := strings.TrimSpace(cmd[0]) + args := cmd[1:] + cmdObj, err := e.GetCmd(functionName) + if err != nil { + return nil, nil, err } + err = cmdObj.ValidateArguments(args) + if err != nil { + return nil, nil, err + } + return cmdObj, args, nil } -func (e *externalControl) cmdL1OrchestratorReset(args []string) { - log.Infof("EXT:cmdL1OrchestratorReset: %s", args) - if len(args) < 1 { - log.Infof("EXT:cmdL1OrchestratorReset: missing block number") +func (e *externalCmdControl) process(cmd ExtControlCmd, args ExtCmdArgs) { + fullFunc, err := fmt.Printf("%s(%s)", cmd.FunctionName(), strings.Join(args, ",")) + if err != nil { + log.Warnf("EXT:readFile: error composing cmd %s:err %s", cmd.FunctionName(), err) return } - blockNumber, err := strconv.ParseUint(strings.TrimSpace(args[0]), 10, 64) + output, err := cmd.Process(args) if err != nil { - log.Infof("EXT:cmdL1OrchestratorReset: error parsing block number: %s", err) + log.Warnf("EXT:readFile: error processing command %s:err %s", fullFunc, err) return } - log.Infof("EXT:cmdL1OrchestratorReset: calling orchestrator reset(%d)", blockNumber) - e.orquestrator.Reset(blockNumber) - log.Infof("EXT:cmdL1OrchestratorReset: calling orchestrator reset(%d) returned", blockNumber) + log.Warnf("EXT:readFile: command %s processed with output: %s", fullFunc, output) } -func (e *externalControl) cmdL1OrchestratorAbort(args []string) { - log.Infof("EXT:cmdL1OrchestratorAbort: %s", args) - if e.orquestrator == nil { - log.Infof("EXT:cmdL1OrchestratorAbort: orquestrator is nil") - return +// COMMANDS IMPLEMENTATION +// HELP +type helpCmd struct { + externalControl *externalCmdControl +} + +func (h *helpCmd) FunctionName() string { + return "help" +} +func (h *helpCmd) ValidateArguments(args ExtCmdArgs) error { + if len(args) > 0 { + return errors.New(h.FunctionName() + " command does not accept arguments") } - log.Infof("EXT:cmdL1OrchestratorAbort: calling orquestrator stop") - e.orquestrator.Abort() - log.Infof("EXT:cmdL1OrchestratorAbort: calling orquestrator stop returned") + return nil } -func (e *externalControl) cmdL1ProducerStop(args []string) { - log.Infof("EXT:cmdL1Stop: %s", args) - if e.producer == nil { - log.Infof("EXT:cmdL1Stop: producer is nil") - return +func (h *helpCmd) Process(args ExtCmdArgs) (string, error) { + var help string + for _, cmd := range h.externalControl.RegisteredCmds { + help += cmd.Help() + "\n" } - log.Infof("EXT:cmdL1Stop: calling producer stop") - e.producer.Stop() - log.Infof("EXT:cmdL1Stop: calling producer stop returned") + return help, nil +} +func (h *helpCmd) Help() string { + return h.FunctionName() + ": show the help of the commands" +} + +// COMMANDS "l1_orchestrator_reset" +type l1OrchestratorResetCmd struct { + orquestrator *l1_parallel_sync.L1SyncOrchestration +} + +func (h *l1OrchestratorResetCmd) FunctionName() string { + return "l1_orchestrator_reset" +} + +func (h *l1OrchestratorResetCmd) ValidateArguments(args ExtCmdArgs) error { + if len(args) != 1 { + return errors.New(h.FunctionName() + " needs 1 argument") + } + _, err := strconv.ParseUint(strings.TrimSpace(args[0]), 10, 64) + if err != nil { + return fmt.Errorf("error parsing block number: %s err:%w", args[0], err) + } + return nil +} +func (h *l1OrchestratorResetCmd) Process(args ExtCmdArgs) (string, error) { + blockNumber, err := strconv.ParseUint(strings.TrimSpace(args[0]), 10, 64) + if err != nil { + return "error param", err + } + log.Warnf("EXT:"+h.FunctionName()+": calling orchestrator reset(%d)", blockNumber) + h.orquestrator.Reset(blockNumber) + res := fmt.Sprintf("EXT: "+h.FunctionName()+": reset to block %d", blockNumber) + return res, nil +} + +func (h *l1OrchestratorResetCmd) Help() string { + return h.FunctionName() + ": reset L1 parallel sync orchestrator to a given block number" +} + +// COMMANDS l1_producer_stop +type l1ProducerStopCmd struct { + producer *l1_parallel_sync.L1RollupInfoProducer +} + +func (h *l1ProducerStopCmd) FunctionName() string { + return "l1_producer_stop" +} + +func (h *l1ProducerStopCmd) ValidateArguments(args ExtCmdArgs) error { + if len(args) > 0 { + return errors.New(h.FunctionName() + " command does not accept arguments") + } + return nil +} +func (h *l1ProducerStopCmd) Process(args ExtCmdArgs) (string, error) { + log.Warnf("EXT:" + h.FunctionName() + ": calling producer stop") + h.producer.Stop() + res := "EXT: " + h.FunctionName() + ": producer stopped" + return res, nil +} + +func (h *l1ProducerStopCmd) Help() string { + return h.FunctionName() + ": stop L1 rollup info producer" } diff --git a/synchronizer/l2_sync/config.go b/synchronizer/l2_sync/config.go new file mode 100644 index 0000000000..7166765b88 --- /dev/null +++ b/synchronizer/l2_sync/config.go @@ -0,0 +1,11 @@ +package l2_sync + +// Config configuration of L2 sync process +type Config struct { + // AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches. + // if true, the synchronizer will accept empty batches and process them. + AcceptEmptyClosedBatches bool `mapstructure:"AcceptEmptyClosedBatches"` + + // ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again + ReprocessFullBatchOnClose bool `mapstructure:"ReprocessFullBatchOnClose"` +} diff --git a/synchronizer/l2_sync/l2_shared/mocks/l1_sync_global_exit_root_checker.go b/synchronizer/l2_sync/l2_shared/mocks/l1_sync_global_exit_root_checker.go new file mode 100644 index 0000000000..0c50000d4d --- /dev/null +++ b/synchronizer/l2_sync/l2_shared/mocks/l1_sync_global_exit_root_checker.go @@ -0,0 +1,89 @@ +// Code generated by mockery. DO NOT EDIT. + +package mock_l2_shared + +import ( + context "context" + + common "github.com/ethereum/go-ethereum/common" + + mock "github.com/stretchr/testify/mock" + + pgx "github.com/jackc/pgx/v4" +) + +// L1SyncGlobalExitRootChecker is an autogenerated mock type for the L1SyncGlobalExitRootChecker type +type L1SyncGlobalExitRootChecker struct { + mock.Mock +} + +type L1SyncGlobalExitRootChecker_Expecter struct { + mock *mock.Mock +} + +func (_m *L1SyncGlobalExitRootChecker) EXPECT() *L1SyncGlobalExitRootChecker_Expecter { + return &L1SyncGlobalExitRootChecker_Expecter{mock: &_m.Mock} +} + +// CheckL1SyncGlobalExitRootEnoughToProcessBatch provides a mock function with given fields: ctx, batchNumber, globalExitRoot, dbTx +func (_m *L1SyncGlobalExitRootChecker) CheckL1SyncGlobalExitRootEnoughToProcessBatch(ctx context.Context, batchNumber uint64, globalExitRoot common.Hash, dbTx pgx.Tx) error { + ret := _m.Called(ctx, batchNumber, globalExitRoot, dbTx) + + if len(ret) == 0 { + panic("no return value specified for CheckL1SyncGlobalExitRootEnoughToProcessBatch") + } + + var r0 error + if rf, ok := ret.Get(0).(func(context.Context, uint64, common.Hash, pgx.Tx) error); ok { + r0 = rf(ctx, batchNumber, globalExitRoot, dbTx) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// L1SyncGlobalExitRootChecker_CheckL1SyncGlobalExitRootEnoughToProcessBatch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CheckL1SyncGlobalExitRootEnoughToProcessBatch' +type L1SyncGlobalExitRootChecker_CheckL1SyncGlobalExitRootEnoughToProcessBatch_Call struct { + *mock.Call +} + +// CheckL1SyncGlobalExitRootEnoughToProcessBatch is a helper method to define mock.On call +// - ctx context.Context +// - batchNumber uint64 +// - globalExitRoot common.Hash +// - dbTx pgx.Tx +func (_e *L1SyncGlobalExitRootChecker_Expecter) CheckL1SyncGlobalExitRootEnoughToProcessBatch(ctx interface{}, batchNumber interface{}, globalExitRoot interface{}, dbTx interface{}) *L1SyncGlobalExitRootChecker_CheckL1SyncGlobalExitRootEnoughToProcessBatch_Call { + return &L1SyncGlobalExitRootChecker_CheckL1SyncGlobalExitRootEnoughToProcessBatch_Call{Call: _e.mock.On("CheckL1SyncGlobalExitRootEnoughToProcessBatch", ctx, batchNumber, globalExitRoot, dbTx)} +} + +func (_c *L1SyncGlobalExitRootChecker_CheckL1SyncGlobalExitRootEnoughToProcessBatch_Call) Run(run func(ctx context.Context, batchNumber uint64, globalExitRoot common.Hash, dbTx pgx.Tx)) *L1SyncGlobalExitRootChecker_CheckL1SyncGlobalExitRootEnoughToProcessBatch_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(uint64), args[2].(common.Hash), args[3].(pgx.Tx)) + }) + return _c +} + +func (_c *L1SyncGlobalExitRootChecker_CheckL1SyncGlobalExitRootEnoughToProcessBatch_Call) Return(_a0 error) *L1SyncGlobalExitRootChecker_CheckL1SyncGlobalExitRootEnoughToProcessBatch_Call { + _c.Call.Return(_a0) + return _c +} + +func (_c *L1SyncGlobalExitRootChecker_CheckL1SyncGlobalExitRootEnoughToProcessBatch_Call) RunAndReturn(run func(context.Context, uint64, common.Hash, pgx.Tx) error) *L1SyncGlobalExitRootChecker_CheckL1SyncGlobalExitRootEnoughToProcessBatch_Call { + _c.Call.Return(run) + return _c +} + +// NewL1SyncGlobalExitRootChecker creates a new instance of L1SyncGlobalExitRootChecker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. +// The first argument is typically a *testing.T value. +func NewL1SyncGlobalExitRootChecker(t interface { + mock.TestingT + Cleanup(func()) +}) *L1SyncGlobalExitRootChecker { + mock := &L1SyncGlobalExitRootChecker{} + mock.Mock.Test(t) + + t.Cleanup(func() { mock.AssertExpectations(t) }) + + return mock +} diff --git a/synchronizer/l2_sync/l2_shared/processor_trusted_batch_sync.go b/synchronizer/l2_sync/l2_shared/processor_trusted_batch_sync.go index 7bb1a326dc..94535ebe4e 100644 --- a/synchronizer/l2_sync/l2_shared/processor_trusted_batch_sync.go +++ b/synchronizer/l2_sync/l2_shared/processor_trusted_batch_sync.go @@ -9,6 +9,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/state" syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common" + "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync" "github.com/ethereum/go-ethereum/common" "github.com/jackc/pgx/v4" ) @@ -124,8 +125,11 @@ type SyncTrustedBatchExecutor interface { ReProcess(ctx context.Context, data *ProcessData, dbTx pgx.Tx) (*ProcessResponse, error) // NothingProcess process a batch that is already synchronized, so we don't need to process it NothingProcess(ctx context.Context, data *ProcessData, dbTx pgx.Tx) (*ProcessResponse, error) - // CloseBatch close a batch - //CloseBatch(ctx context.Context, trustedBatch *types.Batch, dbTx pgx.Tx) error +} + +// L1SyncGlobalExitRootChecker is the interface to check if the required GlobalExitRoot is already synced from L1 +type L1SyncGlobalExitRootChecker interface { + CheckL1SyncGlobalExitRootEnoughToProcessBatch(ctx context.Context, batchNumber uint64, globalExitRoot common.Hash, dbTx pgx.Tx) error } // ProcessorTrustedBatchSync is a template to sync trusted state. It classify what kind of update is needed and call to SyncTrustedStateBatchExecutorSteps @@ -134,16 +138,20 @@ type SyncTrustedBatchExecutor interface { // // the real implementation of the steps is in the SyncTrustedStateBatchExecutorSteps interface that known how to process a batch type ProcessorTrustedBatchSync struct { - Steps SyncTrustedBatchExecutor - timeProvider syncCommon.TimeProvider + Steps SyncTrustedBatchExecutor + timeProvider syncCommon.TimeProvider + l1SyncChecker L1SyncGlobalExitRootChecker + Cfg l2_sync.Config } // NewProcessorTrustedBatchSync creates a new SyncTrustedStateBatchExecutorTemplate func NewProcessorTrustedBatchSync(steps SyncTrustedBatchExecutor, - timeProvider syncCommon.TimeProvider) *ProcessorTrustedBatchSync { + timeProvider syncCommon.TimeProvider, l1SyncChecker L1SyncGlobalExitRootChecker, cfg l2_sync.Config) *ProcessorTrustedBatchSync { return &ProcessorTrustedBatchSync{ - Steps: steps, - timeProvider: timeProvider, + Steps: steps, + timeProvider: timeProvider, + l1SyncChecker: l1SyncChecker, + Cfg: cfg, } } @@ -151,6 +159,15 @@ func NewProcessorTrustedBatchSync(steps SyncTrustedBatchExecutor, func (s *ProcessorTrustedBatchSync) ProcessTrustedBatch(ctx context.Context, trustedBatch *types.Batch, status TrustedState, dbTx pgx.Tx, debugPrefix string) (*TrustedState, error) { log.Debugf("%s Processing trusted batch: %v", debugPrefix, trustedBatch.Number) stateCurrentBatch, statePreviousBatch := s.GetCurrentAndPreviousBatchFromCache(&status) + if s.l1SyncChecker != nil { + err := s.l1SyncChecker.CheckL1SyncGlobalExitRootEnoughToProcessBatch(ctx, uint64(trustedBatch.Number), trustedBatch.GlobalExitRoot, dbTx) + if err != nil { + log.Errorf("%s error checking GlobalExitRoot from TrustedBatch. Error: ", debugPrefix, err) + return nil, err + } + } else { + log.Infof("Disabled check L1 sync status for process batch") + } processMode, err := s.GetModeForProcessBatch(trustedBatch, stateCurrentBatch, statePreviousBatch, debugPrefix) if err != nil { log.Error("%s error getting processMode. Error: ", debugPrefix, trustedBatch.Number, err) @@ -265,7 +282,7 @@ func (s *ProcessorTrustedBatchSync) GetModeForProcessBatch(trustedNodeBatch *typ return ProcessData{}, fmt.Errorf("trustedNodeBatch and statePreviousBatch can't be nil") } - var result ProcessData + var result ProcessData = ProcessData{} if stateBatch == nil { result = ProcessData{ Mode: FullProcessMode, @@ -274,7 +291,7 @@ func (s *ProcessorTrustedBatchSync) GetModeForProcessBatch(trustedNodeBatch *typ Description: "Batch is not on database, so is the first time we process it", } } else { - _, strDiffsBatches := AreEqualStateBatchAndTrustedBatch(stateBatch, trustedNodeBatch, CMP_BATCH_IGNORE_TSTAMP) + areBatchesExactlyEqual, strDiffsBatches := AreEqualStateBatchAndTrustedBatch(stateBatch, trustedNodeBatch, CMP_BATCH_IGNORE_TSTAMP) newL2DataFlag, err := ThereAreNewBatchL2Data(stateBatch.BatchL2Data, trustedNodeBatch.BatchL2Data) if err != nil { return ProcessData{}, err @@ -287,6 +304,10 @@ func (s *ProcessorTrustedBatchSync) GetModeForProcessBatch(trustedNodeBatch *typ BatchMustBeClosed: isTrustedBatchClosed(trustedNodeBatch) && stateBatch.WIP, Description: "no new data on batch. Diffs: " + strDiffsBatches, } + if areBatchesExactlyEqual { + result.BatchMustBeClosed = false + result.Description = "exactly batches: " + strDiffsBatches + } } else { // We have a previous batch, but in node something change // We have processed this batch before, and we have the intermediate state root, so is going to be process only new Tx. @@ -308,9 +329,21 @@ func (s *ProcessorTrustedBatchSync) GetModeForProcessBatch(trustedNodeBatch *typ } } } + + if s.Cfg.ReprocessFullBatchOnClose && result.BatchMustBeClosed { + if result.Mode == IncrementalProcessMode || result.Mode == NothingProcessMode { + result.Description = "forced reprocess due to batch closed and ReprocessFullBatchOnClose" + log.Infof("%s Batch %v: Converted mode %s to %s because cfg.ReprocessFullBatchOnClose", debugPrefix, trustedNodeBatch.Number, result.Mode, ReprocessProcessMode) + result.Mode = ReprocessProcessMode + result.OldStateRoot = statePreviousBatch.StateRoot + result.BatchMustBeClosed = true + } + } + if result.Mode == "" { - return result, fmt.Errorf("failed to get mode for process batch %v", trustedNodeBatch.Number) + return result, fmt.Errorf("batch %v: failed to get mode for process ", trustedNodeBatch.Number) } + result.BatchNumber = uint64(trustedNodeBatch.Number) result.StateBatch = stateBatch result.TrustedBatch = trustedNodeBatch @@ -318,6 +351,17 @@ func (s *ProcessorTrustedBatchSync) GetModeForProcessBatch(trustedNodeBatch *typ result.OldAccInputHash = statePreviousBatch.AccInputHash result.Now = s.timeProvider.Now() result.DebugPrefix = fmt.Sprintf("%s mode %s:", debugPrefix, result.Mode) + + if isTrustedBatchEmptyAndClosed(trustedNodeBatch) { + if s.Cfg.AcceptEmptyClosedBatches { + log.Infof("%s Batch %v: TrustedBatch Empty and closed, accepted due configuration", result.DebugPrefix, trustedNodeBatch.Number) + } else { + err := fmt.Errorf("%s Batch %v: TrustedBatch Empty and closed, rejected due configuration", result.DebugPrefix, trustedNodeBatch.Number) + log.Infof(err.Error()) + return result, err + } + } + return result, nil } @@ -325,6 +369,10 @@ func isTrustedBatchClosed(batch *types.Batch) bool { return batch.Closed } +func isTrustedBatchEmptyAndClosed(batch *types.Batch) bool { + return len(batch.BatchL2Data) == 0 && isTrustedBatchClosed(batch) +} + func checkStateRootAndLER(batchNumber uint64, expectedStateRoot common.Hash, expectedLER common.Hash, calculatedStateRoot common.Hash, calculatedLER common.Hash) error { if calculatedStateRoot != expectedStateRoot { return fmt.Errorf("batch %v: stareRoot calculated [%s] is different from the one in the batch [%s] err:%w", batchNumber, calculatedStateRoot, expectedStateRoot, ErrFatalBatchDesynchronized) @@ -339,7 +387,13 @@ func checkProcessBatchResultMatchExpected(data *ProcessData, processBatchResp *s var err error = nil var trustedBatch = data.TrustedBatch if trustedBatch == nil { - panic("trustedBatch is nil") + err = fmt.Errorf("%s trustedBatch is nil, it never should be nil", data.DebugPrefix) + log.Error(err.Error()) + return err + } + if len(trustedBatch.BatchL2Data) == 0 { + log.Warnf("Batch %v: BatchL2Data is empty, no checking", trustedBatch.Number) + return nil } if processBatchResp == nil { log.Warnf("Batch %v: Can't check processBatchResp because is nil, then check store batch in DB", trustedBatch.Number) diff --git a/synchronizer/l2_sync/l2_shared/tests/processor_trusted_batch_sync_test.go b/synchronizer/l2_sync/l2_shared/tests/processor_trusted_batch_sync_test.go index 1e96f58d2b..79e62c93d5 100644 --- a/synchronizer/l2_sync/l2_shared/tests/processor_trusted_batch_sync_test.go +++ b/synchronizer/l2_sync/l2_shared/tests/processor_trusted_batch_sync_test.go @@ -8,6 +8,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types" "github.com/0xPolygonHermez/zkevm-node/state" commonSync "github.com/0xPolygonHermez/zkevm-node/synchronizer/common" + "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync" "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared" mock_l2_shared "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared/mocks" "github.com/ethereum/go-ethereum/common" @@ -18,12 +19,16 @@ import ( var ( hash1 = common.HexToHash("0x29e885edaf8e4b51e1d2e05f9da28161d2fb4f6b1d53827d9b80a23cf2d7d9f1") hash2 = common.HexToHash("0x979b141b8bcd3ba17815cd76811f1fca1cabaa9d51f7c00712606970f81d6e37") + cfg = l2_sync.Config{ + AcceptEmptyClosedBatches: true, + } ) func TestCacheEmpty(t *testing.T) { mockExecutor := mock_l2_shared.NewSyncTrustedBatchExecutor(t) mockTimer := &commonSync.MockTimerProvider{} - sut := l2_shared.NewProcessorTrustedBatchSync(mockExecutor, mockTimer) + mockL1SyncChecker := mock_l2_shared.NewL1SyncGlobalExitRootChecker(t) + sut := l2_shared.NewProcessorTrustedBatchSync(mockExecutor, mockTimer, mockL1SyncChecker, cfg) current, previous := sut.GetCurrentAndPreviousBatchFromCache(&l2_shared.TrustedState{ LastTrustedBatches: []*state.Batch{nil, nil}, @@ -53,7 +58,7 @@ func TestCacheJustCurrent(t *testing.T) { status := l2_shared.TrustedState{ LastTrustedBatches: []*state.Batch{&batchA}, } - sut := l2_shared.NewProcessorTrustedBatchSync(mockExecutor, mockTimer) + sut := l2_shared.NewProcessorTrustedBatchSync(mockExecutor, mockTimer, nil, cfg) current, previous := sut.GetCurrentAndPreviousBatchFromCache(&status) require.Nil(t, previous) @@ -71,7 +76,7 @@ func TestCacheJustPrevious(t *testing.T) { status := l2_shared.TrustedState{ LastTrustedBatches: []*state.Batch{nil, &batchA}, } - sut := l2_shared.NewProcessorTrustedBatchSync(mockExecutor, mockTimer) + sut := l2_shared.NewProcessorTrustedBatchSync(mockExecutor, mockTimer, nil, cfg) current, previous := sut.GetCurrentAndPreviousBatchFromCache(&status) require.Nil(t, current) @@ -94,7 +99,7 @@ func newTestDataForProcessorTrustedBatchSync(t *testing.T) *TestDataForProcessor return &TestDataForProcessorTrustedBatchSync{ mockTimer: mockTimer, mockExecutor: mockExecutor, - sut: l2_shared.NewProcessorTrustedBatchSync(mockExecutor, mockTimer), + sut: l2_shared.NewProcessorTrustedBatchSync(mockExecutor, mockTimer, nil, cfg), stateCurrentBatch: &state.Batch{ BatchNumber: 123, Coinbase: common.HexToAddress("0x1230"), @@ -187,6 +192,81 @@ func TestGetModeForProcessBatchNothing(t *testing.T) { require.NoError(t, err) require.Equal(t, l2_shared.NothingProcessMode, processData.Mode, "current batch and trusted batch are the same, just need to be closed") require.Equal(t, false, processData.BatchMustBeClosed, "nothing to do") + + testData.stateCurrentBatch.WIP = false + testData.trustedNodeBatch.Closed = false + processData, err = testData.sut.GetModeForProcessBatch(testData.trustedNodeBatch, nil, testData.statePreviousBatch, "test") + require.NoError(t, err) + require.Equal(t, l2_shared.FullProcessMode, processData.Mode, "no batch in DB, fullprocess") + require.Equal(t, false, processData.BatchMustBeClosed, "nothing to do") + + testData.stateCurrentBatch.WIP = false + testData.trustedNodeBatch.Closed = true + processData, err = testData.sut.GetModeForProcessBatch(testData.trustedNodeBatch, nil, testData.statePreviousBatch, "test") + require.NoError(t, err) + require.Equal(t, l2_shared.FullProcessMode, processData.Mode, "no batch in DB, fullprocess") + require.Equal(t, true, processData.BatchMustBeClosed, "must be close") + +} + +func TestGetModeForEmptyAndClosedBatchConfiguredToReject(t *testing.T) { + testData := newTestDataForProcessorTrustedBatchSync(t) + testData.sut.Cfg.AcceptEmptyClosedBatches = false + testData.sut.Cfg.ReprocessFullBatchOnClose = true + testData.stateCurrentBatch.WIP = true + testData.trustedNodeBatch.Closed = true + processData, err := testData.sut.GetModeForProcessBatch(testData.trustedNodeBatch, testData.stateCurrentBatch, testData.statePreviousBatch, "test") + require.Error(t, err) + + testData.stateCurrentBatch.WIP = false + testData.trustedNodeBatch.Closed = true + processData, err = testData.sut.GetModeForProcessBatch(testData.trustedNodeBatch, testData.stateCurrentBatch, testData.statePreviousBatch, "test") + require.Error(t, err) + + testData.stateCurrentBatch.WIP = false + testData.trustedNodeBatch.Closed = false + processData, err = testData.sut.GetModeForProcessBatch(testData.trustedNodeBatch, testData.stateCurrentBatch, testData.statePreviousBatch, "test") + require.NoError(t, err) + require.Equal(t, l2_shared.NothingProcessMode, processData.Mode, "current batch and trusted batch are the same, just need to be closed") + require.Equal(t, false, processData.BatchMustBeClosed, "nothing to do") + + testData.stateCurrentBatch.WIP = false + testData.trustedNodeBatch.Closed = false + processData, err = testData.sut.GetModeForProcessBatch(testData.trustedNodeBatch, nil, testData.statePreviousBatch, "test") + require.NoError(t, err) + require.Equal(t, l2_shared.FullProcessMode, processData.Mode, "current batch and trusted batch are the same, just need to be closed") + require.Equal(t, false, processData.BatchMustBeClosed, "nothing to do") + + testData.stateCurrentBatch.WIP = false + testData.trustedNodeBatch.Closed = true + processData, err = testData.sut.GetModeForProcessBatch(testData.trustedNodeBatch, nil, testData.statePreviousBatch, "test") + require.Error(t, err) +} + +func TestGetModeReprocessFullBatchOnCloseTrue(t *testing.T) { + testData := newTestDataForProcessorTrustedBatchSync(t) + testData.sut.Cfg.AcceptEmptyClosedBatches = true + testData.sut.Cfg.ReprocessFullBatchOnClose = true + testData.stateCurrentBatch.WIP = true + testData.stateCurrentBatch.BatchL2Data = common.Hex2Bytes("112233") + testData.trustedNodeBatch.BatchL2Data = common.Hex2Bytes("11223344") + testData.trustedNodeBatch.Closed = true + // Is a incremental converted to reprocess + testData.sut.Cfg.ReprocessFullBatchOnClose = true + processData, err := testData.sut.GetModeForProcessBatch(testData.trustedNodeBatch, testData.stateCurrentBatch, testData.statePreviousBatch, "test") + require.NoError(t, err) + require.Equal(t, l2_shared.ReprocessProcessMode, processData.Mode, "current batch and trusted batch are the same, just need to be closed") + // Is a incremental to close + testData.sut.Cfg.ReprocessFullBatchOnClose = false + processData, err = testData.sut.GetModeForProcessBatch(testData.trustedNodeBatch, testData.stateCurrentBatch, testData.statePreviousBatch, "test") + require.NoError(t, err) + require.Equal(t, l2_shared.IncrementalProcessMode, processData.Mode, "increment of batchl2data, need to incremental execution") + // No previous batch, is a fullprocess + testData.sut.Cfg.ReprocessFullBatchOnClose = true + processData, err = testData.sut.GetModeForProcessBatch(testData.trustedNodeBatch, nil, testData.statePreviousBatch, "test") + require.NoError(t, err) + require.Equal(t, l2_shared.FullProcessMode, processData.Mode, "no previous batch and close, fullprocess") + } func TestGetNextStatusClear(t *testing.T) { diff --git a/synchronizer/l2_sync/l2_sync_etrog/check_sync_status_to_process_batch.go b/synchronizer/l2_sync/l2_sync_etrog/check_sync_status_to_process_batch.go index da6fc75bdd..019c487231 100644 --- a/synchronizer/l2_sync/l2_sync_etrog/check_sync_status_to_process_batch.go +++ b/synchronizer/l2_sync/l2_sync_etrog/check_sync_status_to_process_batch.go @@ -33,11 +33,11 @@ func NewCheckSyncStatusToProcessBatch(zkevmRPCClient syncinterfaces.ZKEVMClientG } } -// CheckL1SyncStatusEnoughToProcessBatch returns nil if the are sync and could process the batch +// CheckL1SyncGlobalExitRootEnoughToProcessBatch returns nil if the are sync and could process the batch // if not: // - returns syncinterfaces.ErrMissingSyncFromL1 if we are behind the block number that contains the GlobalExitRoot // - returns l2_shared.NewDeSyncPermissionlessAndTrustedNodeError if trusted and and permissionless are not in same page! pass also the discrepance point -func (c *CheckSyncStatusToProcessBatch) CheckL1SyncStatusEnoughToProcessBatch(ctx context.Context, batchNumber uint64, globalExitRoot common.Hash, dbTx pgx.Tx) error { +func (c *CheckSyncStatusToProcessBatch) CheckL1SyncGlobalExitRootEnoughToProcessBatch(ctx context.Context, batchNumber uint64, globalExitRoot common.Hash, dbTx pgx.Tx) error { // Find out if this node have GlobalExitRoot // If not: ask to zkevm-RPC the block number of this GlobalExitRoot // If we are behind this block number returns ErrMissingSyncFromL1 @@ -47,14 +47,14 @@ func (c *CheckSyncStatusToProcessBatch) CheckL1SyncStatusEnoughToProcessBatch(ct return nil } debugStr := fmt.Sprintf("CheckL1SyncStatusEnoughToProcessBatch batchNumber:%d globalExitRoot: %s ", batchNumber, globalExitRoot.Hex()) - _, err := c.state.GetExitRootByGlobalExitRoot(ctx, globalExitRoot, dbTx) + localGERInfo, err := c.state.GetExitRootByGlobalExitRoot(ctx, globalExitRoot, dbTx) if err != nil && !errors.Is(err, state.ErrNotFound) { log.Errorf("error getting GetExitRootByGlobalExitRoot %s . Error: ", debugStr, err) return err } if err == nil { // We have this GlobalExitRoot, so we are synced from L1 - log.Infof("We have this GlobalExitRoot, so we are synced from L1 %s", debugStr) + log.Infof("We have this GlobalExitRoot (%s) in L1block %d, so we are synced from L1 %s", globalExitRoot.String(), localGERInfo.BlockNumber, debugStr) return nil } // this means err != state.ErrNotFound -> so we have to ask to zkevm-RPC the block number of this GlobalExitRoot diff --git a/synchronizer/l2_sync/l2_sync_etrog/check_sync_status_to_process_batch_test.go b/synchronizer/l2_sync/l2_sync_etrog/check_sync_status_to_process_batch_test.go index 9acee59955..84d11dddc8 100644 --- a/synchronizer/l2_sync/l2_sync_etrog/check_sync_status_to_process_batch_test.go +++ b/synchronizer/l2_sync/l2_sync_etrog/check_sync_status_to_process_batch_test.go @@ -42,13 +42,13 @@ func NewTestData(t *testing.T) *testData { func TestCheckL1SyncStatusEnoughToProcessBatchGerZero(t *testing.T) { testData := NewTestData(t) - err := testData.sut.CheckL1SyncStatusEnoughToProcessBatch(testData.ctx, 1, state.ZeroHash, nil) + err := testData.sut.CheckL1SyncGlobalExitRootEnoughToProcessBatch(testData.ctx, 1, state.ZeroHash, nil) require.NoError(t, err) } func TestCheckL1SyncStatusEnoughToProcessBatchGerOnDB(t *testing.T) { testData := NewTestData(t) testData.stateMock.EXPECT().GetExitRootByGlobalExitRoot(testData.ctx, globalExitRootNonZero, nil).Return(&state.GlobalExitRoot{}, nil).Once() - err := testData.sut.CheckL1SyncStatusEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) + err := testData.sut.CheckL1SyncGlobalExitRootEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) require.NoError(t, err) } @@ -57,7 +57,7 @@ func TestCheckL1SyncStatusEnoughToProcessBatchGerDatabaseFails(t *testing.T) { testData.stateMock.EXPECT().GetExitRootByGlobalExitRoot(testData.ctx, globalExitRootNonZero, nil).Return(nil, randomError).Once() - err := testData.sut.CheckL1SyncStatusEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) + err := testData.sut.CheckL1SyncGlobalExitRootEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) require.Error(t, err) } @@ -67,7 +67,7 @@ func TestCheckL1SyncStatusEnoughToProcessBatchGerNoOnDBFailsCallToZkevm(t *testi testData.stateMock.EXPECT().GetExitRootByGlobalExitRoot(testData.ctx, globalExitRootNonZero, nil).Return(nil, state.ErrNotFound).Once() testData.zkevmMock.EXPECT().ExitRootsByGER(testData.ctx, globalExitRootNonZero).Return(nil, randomError).Once() - err := testData.sut.CheckL1SyncStatusEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) + err := testData.sut.CheckL1SyncGlobalExitRootEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) require.Error(t, err) } @@ -79,7 +79,7 @@ func TestCheckL1SyncStatusEnoughToProcessBatchGerNoOnDBWeAre1BlockBehind(t *test testData.zkevmMock.EXPECT().ExitRootsByGER(testData.ctx, globalExitRootNonZero).Return(&types.ExitRoots{BlockNumber: types.ArgUint64(l1Block)}, nil).Once() testData.stateMock.EXPECT().GetLastBlock(testData.ctx, nil).Return(&state.Block{BlockNumber: l1Block - 1}, nil).Once() - err := testData.sut.CheckL1SyncStatusEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) + err := testData.sut.CheckL1SyncGlobalExitRootEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) require.ErrorIs(t, err, syncinterfaces.ErrMissingSyncFromL1) } @@ -91,7 +91,7 @@ func TestCheckL1SyncStatusEnoughToProcessBatchGerNoOnDBWeAre1BlockBeyond(t *test testData.zkevmMock.EXPECT().ExitRootsByGER(testData.ctx, globalExitRootNonZero).Return(&types.ExitRoots{BlockNumber: types.ArgUint64(l1Block)}, nil).Once() testData.stateMock.EXPECT().GetLastBlock(testData.ctx, nil).Return(&state.Block{BlockNumber: l1Block + 1}, nil).Once() - err := testData.sut.CheckL1SyncStatusEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) + err := testData.sut.CheckL1SyncGlobalExitRootEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) require.ErrorIs(t, err, syncinterfaces.ErrFatalDesyncFromL1) l1BlockNumber := err.(*l2_shared.DeSyncPermissionlessAndTrustedNodeError).L1BlockNumber require.Equal(t, l1Block, l1BlockNumber, "returns the block where is the discrepancy") @@ -105,7 +105,7 @@ func TestCheckL1SyncStatusEnoughToProcessBatchGerNoOnDBWeAreLastBlockSynced(t *t testData.zkevmMock.EXPECT().ExitRootsByGER(testData.ctx, globalExitRootNonZero).Return(&types.ExitRoots{BlockNumber: types.ArgUint64(l1Block)}, nil).Once() testData.stateMock.EXPECT().GetLastBlock(testData.ctx, nil).Return(&state.Block{BlockNumber: l1Block}, nil).Once() - err := testData.sut.CheckL1SyncStatusEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) + err := testData.sut.CheckL1SyncGlobalExitRootEnoughToProcessBatch(testData.ctx, 1, globalExitRootNonZero, nil) require.ErrorIs(t, err, syncinterfaces.ErrFatalDesyncFromL1) l1BlockNumber := err.(*l2_shared.DeSyncPermissionlessAndTrustedNodeError).L1BlockNumber require.Equal(t, l1Block, l1BlockNumber, "returns the block where is the discrepancy") diff --git a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go index 73f6fa247a..1975f6c42b 100644 --- a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go +++ b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go @@ -12,11 +12,16 @@ import ( "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common" "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces" + "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync" "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared" "github.com/ethereum/go-ethereum/common" "github.com/jackc/pgx/v4" ) +const ( + timeOfLiveBatchOnCache = 5 * time.Minute +) + var ( // ErrNotImplemented is returned when a method is not implemented ErrNotImplemented = errors.New("not implemented") @@ -40,33 +45,28 @@ type StateInterface interface { ProcessBatchV2(ctx context.Context, request state.ProcessRequest, updateMerkleTree bool) (*state.ProcessBatchResponse, error) StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *state.ProcessBlockResponse, txsEGPLog []*state.EffectiveGasPriceLog, dbTx pgx.Tx) error GetL1InfoTreeDataFromBatchL2Data(ctx context.Context, batchL2Data []byte, dbTx pgx.Tx) (map[uint32]state.L1DataV2, common.Hash, common.Hash, error) -} - -// L1SyncChecker is the interface to check if we are synced from L1 to process a batch -type L1SyncChecker interface { - CheckL1SyncStatusEnoughToProcessBatch(ctx context.Context, batchNumber uint64, globalExitRoot common.Hash, dbTx pgx.Tx) error + GetLastVirtualBatchNum(ctx context.Context, dbTx pgx.Tx) (uint64, error) } // SyncTrustedBatchExecutorForEtrog is the implementation of the SyncTrustedStateBatchExecutorSteps that // have the functions to sync a fullBatch, incrementalBatch and reprocessBatch type SyncTrustedBatchExecutorForEtrog struct { - state StateInterface - sync syncinterfaces.SynchronizerFlushIDManager - l1SyncChecker L1SyncChecker + state StateInterface + sync syncinterfaces.SynchronizerFlushIDManager } // NewSyncTrustedBatchExecutorForEtrog creates a new prcessor for sync with L2 batches func NewSyncTrustedBatchExecutorForEtrog(zkEVMClient syncinterfaces.ZKEVMClientTrustedBatchesGetter, state l2_shared.StateInterface, stateBatchExecutor StateInterface, - sync syncinterfaces.SynchronizerFlushIDManager, timeProvider syncCommon.TimeProvider, l1SyncChecker L1SyncChecker) *l2_shared.TrustedBatchesRetrieve { + sync syncinterfaces.SynchronizerFlushIDManager, timeProvider syncCommon.TimeProvider, l1SyncChecker l2_shared.L1SyncGlobalExitRootChecker, + cfg l2_sync.Config) *l2_shared.TrustedBatchesRetrieve { executorSteps := &SyncTrustedBatchExecutorForEtrog{ - state: stateBatchExecutor, - sync: sync, - l1SyncChecker: l1SyncChecker, + state: stateBatchExecutor, + sync: sync, } - executor := l2_shared.NewProcessorTrustedBatchSync(executorSteps, timeProvider) - a := l2_shared.NewTrustedBatchesRetrieve(executor, zkEVMClient, state, sync, *l2_shared.NewTrustedStateManager(timeProvider, time.Hour)) + executor := l2_shared.NewProcessorTrustedBatchSync(executorSteps, timeProvider, l1SyncChecker, cfg) + a := l2_shared.NewTrustedBatchesRetrieve(executor, zkEVMClient, state, sync, *l2_shared.NewTrustedStateManager(timeProvider, timeOfLiveBatchOnCache)) return a } @@ -107,18 +107,28 @@ func (b *SyncTrustedBatchExecutorForEtrog) NothingProcess(ctx context.Context, d // CreateEmptyBatch create a new empty batch (no batchL2Data and WIP) func (b *SyncTrustedBatchExecutorForEtrog) CreateEmptyBatch(ctx context.Context, data *l2_shared.ProcessData, dbTx pgx.Tx) (*l2_shared.ProcessResponse, error) { - log.Debugf("%s The Batch is a WIP empty, so just creating a DB entry", data.DebugPrefix) + log.Debugf("%s The Batch is a empty (batchl2data=0 bytes), so just creating a DB entry", data.DebugPrefix) err := b.openBatch(ctx, data.TrustedBatch, dbTx, data.DebugPrefix) if err != nil { log.Errorf("%s error openning batch. Error: %v", data.DebugPrefix, err) return nil, err } - log.Debugf("%s updateWIPBatch", data.DebugPrefix) - err = b.updateWIPBatch(ctx, data, data.TrustedBatch.StateRoot, dbTx) - if err != nil { - log.Errorf("%s error updateWIPBatch. Error: ", data.DebugPrefix, err) - return nil, err + if data.BatchMustBeClosed { + log.Infof("%s Closing empty batch (no execution)", data.DebugPrefix) + err = b.CloseBatch(ctx, data.TrustedBatch, dbTx, data.DebugPrefix) + if err != nil { + log.Error("%s error closing batch. Error: ", data.DebugPrefix, err) + return nil, err + } + } else { + log.Debugf("%s updateWIPBatch", data.DebugPrefix) + err = b.updateWIPBatch(ctx, data, data.TrustedBatch.StateRoot, dbTx) + if err != nil { + log.Errorf("%s error updateWIPBatch. Error: ", data.DebugPrefix, err) + return nil, err + } } + res := l2_shared.NewProcessResponse() stateBatch := syncCommon.RpcBatchToStateBatch(data.TrustedBatch) res.UpdateCurrentBatch(stateBatch) @@ -128,15 +138,11 @@ func (b *SyncTrustedBatchExecutorForEtrog) CreateEmptyBatch(ctx context.Context, // FullProcess process a batch that is not on database, so is the first time we process it func (b *SyncTrustedBatchExecutorForEtrog) FullProcess(ctx context.Context, data *l2_shared.ProcessData, dbTx pgx.Tx) (*l2_shared.ProcessResponse, error) { log.Debugf("%s FullProcess", data.DebugPrefix) - if len(data.TrustedBatch.BatchL2Data) == 0 && !data.BatchMustBeClosed { + if len(data.TrustedBatch.BatchL2Data) == 0 { + data.DebugPrefix += " (emptyBatch) " return b.CreateEmptyBatch(ctx, data, dbTx) } - err := b.checkIfWeAreSyncedFromL1ToProcessGlobalExitRoot(ctx, data, dbTx) - if err != nil { - log.Errorf("%s error checkIfWeAreSyncedFromL1ToProcessGlobalExitRoot. Error: %v", data.DebugPrefix, err) - return nil, err - } - err = b.openBatch(ctx, data.TrustedBatch, dbTx, data.DebugPrefix) + err := b.openBatch(ctx, data.TrustedBatch, dbTx, data.DebugPrefix) if err != nil { log.Errorf("%s error openning batch. Error: %v", data.DebugPrefix, err) return nil, err @@ -196,11 +202,6 @@ func (b *SyncTrustedBatchExecutorForEtrog) IncrementalProcess(ctx context.Contex log.Errorf("%s error checkThatL2DataIsIncremental. Error: %v", data.DebugPrefix, err) return nil, err } - err = b.checkIfWeAreSyncedFromL1ToProcessGlobalExitRoot(ctx, data, dbTx) - if err != nil { - log.Errorf("%s error checkIfWeAreSyncedFromL1ToProcessGlobalExitRoot. Error: %v", data.DebugPrefix, err) - return nil, err - } PartialBatchL2Data, err := b.composePartialBatch(data.StateBatch, data.TrustedBatch) if err != nil { @@ -247,21 +248,17 @@ func (b *SyncTrustedBatchExecutorForEtrog) IncrementalProcess(ctx context.Contex } updatedBatch := *data.StateBatch + updatedBatch.LocalExitRoot = data.TrustedBatch.LocalExitRoot + updatedBatch.AccInputHash = data.TrustedBatch.AccInputHash + updatedBatch.GlobalExitRoot = data.TrustedBatch.GlobalExitRoot updatedBatch.BatchL2Data = data.TrustedBatch.BatchL2Data updatedBatch.WIP = !data.BatchMustBeClosed + res := l2_shared.NewProcessResponse() res.UpdateCurrentBatchWithExecutionResult(&updatedBatch, processBatchResp) return &res, nil } -func (b *SyncTrustedBatchExecutorForEtrog) checkIfWeAreSyncedFromL1ToProcessGlobalExitRoot(ctx context.Context, data *l2_shared.ProcessData, dbTx pgx.Tx) error { - if b.l1SyncChecker == nil { - log.Infof("Disabled check L1 sync status for process batch") - return nil - } - return b.l1SyncChecker.CheckL1SyncStatusEnoughToProcessBatch(ctx, data.BatchNumber, data.TrustedBatch.GlobalExitRoot, dbTx) -} - func (b *SyncTrustedBatchExecutorForEtrog) updateWIPBatch(ctx context.Context, data *l2_shared.ProcessData, NewStateRoot common.Hash, dbTx pgx.Tx) error { receipt := state.ProcessingReceipt{ BatchNumber: data.BatchNumber, @@ -283,7 +280,17 @@ func (b *SyncTrustedBatchExecutorForEtrog) updateWIPBatch(ctx context.Context, d // ReProcess process a batch that we have processed before, but we don't have the intermediate state root, so we need to reprocess it func (b *SyncTrustedBatchExecutorForEtrog) ReProcess(ctx context.Context, data *l2_shared.ProcessData, dbTx pgx.Tx) (*l2_shared.ProcessResponse, error) { log.Warnf("%s needs to be reprocessed! deleting batches from this batch, because it was partially processed but the intermediary stateRoot is lost", data.DebugPrefix) - err := b.state.ResetTrustedState(ctx, uint64(data.TrustedBatch.Number)-1, dbTx) + // Check that there are no VirtualBatches neither VerifiedBatches that are newer than this batch + lastVirtualBatchNum, err := b.state.GetLastVirtualBatchNum(ctx, dbTx) + if err != nil { + log.Errorf("%s error getting lastVirtualBatchNum. Error: %v", data.DebugPrefix, err) + return nil, err + } + if lastVirtualBatchNum >= uint64(data.TrustedBatch.Number) { + log.Errorf("%s there are newer or equal virtualBatches than this batch. Can't reprocess because then will delete a virtualBatch", data.DebugPrefix) + return nil, syncinterfaces.ErrMissingSyncFromL1 + } + err = b.state.ResetTrustedState(ctx, uint64(data.TrustedBatch.Number)-1, dbTx) if err != nil { log.Warnf("%s error deleting batches from this batch: %v", data.DebugPrefix, err) return nil, err diff --git a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync_test.go b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync_test.go index 706fb204ec..97a7125b96 100644 --- a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync_test.go +++ b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync_test.go @@ -196,6 +196,7 @@ func TestNothingProcessDoesntMatchBatchReprocess(t *testing.T) { StateRoot: common.HexToHash(hashExamplesValues[2]), }, } + testData.stateMock.EXPECT().GetLastVirtualBatchNum(testData.ctx, mock.Anything).Return(uint64(122), nil).Maybe() testData.stateMock.EXPECT().ResetTrustedState(testData.ctx, data.BatchNumber-1, mock.Anything).Return(nil).Once() testData.stateMock.EXPECT().OpenBatch(testData.ctx, mock.Anything, mock.Anything).Return(nil).Once() testData.stateMock.EXPECT().GetL1InfoTreeDataFromBatchL2Data(testData.ctx, mock.Anything, mock.Anything).Return(map[uint32]state.L1DataV2{}, common.Hash{}, common.Hash{}, nil).Once() @@ -211,6 +212,35 @@ func TestNothingProcessDoesntMatchBatchReprocess(t *testing.T) { require.NoError(t, err) } +func TestReprocessRejectDeleteVirtualBatch(t *testing.T) { + testData := newTestData(t) + // Arrange + data := l2_shared.ProcessData{ + BatchNumber: 123, + Mode: l2_shared.NothingProcessMode, + BatchMustBeClosed: false, + DebugPrefix: "test", + StateBatch: &state.Batch{ + BatchNumber: 123, + StateRoot: common.HexToHash(hashExamplesValues[1]), + BatchL2Data: []byte{1, 2, 3, 4}, + WIP: true, + }, + TrustedBatch: &types.Batch{ + Number: 123, + StateRoot: common.HexToHash(hashExamplesValues[0]), + BatchL2Data: []byte{1, 2, 3, 4}, + }, + PreviousStateBatch: &state.Batch{ + BatchNumber: 122, + StateRoot: common.HexToHash(hashExamplesValues[2]), + }, + } + testData.stateMock.EXPECT().GetLastVirtualBatchNum(testData.ctx, mock.Anything).Return(uint64(123), nil).Maybe() + _, err := testData.sut.ReProcess(testData.ctx, &data, nil) + require.Error(t, err) +} + func TestNothingProcessIfBatchMustBeClosedThenCloseBatch(t *testing.T) { testData := newTestData(t) // Arrange @@ -265,7 +295,7 @@ func TestCloseBatchGivenAlreadyClosedAndTheDataAreRightThenNoError(t *testing.T) require.NoError(t, res) } -func TestEmptyBatch(t *testing.T) { +func TestEmptyWIPBatch(t *testing.T) { testData := newTestData(t) // Arrange expectedBatch := state.Batch{ @@ -304,3 +334,43 @@ func TestEmptyBatch(t *testing.T) { require.Equal(t, 0, len(response.UpdateBatch.BatchL2Data)) require.Equal(t, expectedBatch, *response.UpdateBatch) } + +func TestEmptyBatchClosed(t *testing.T) { + testData := newTestData(t) + // Arrange + expectedBatch := state.Batch{ + BatchNumber: 123, + Coinbase: common.HexToAddress("0x01"), + StateRoot: common.HexToHash("0x02"), + GlobalExitRoot: common.HexToHash("0x03"), + LocalExitRoot: common.HexToHash("0x04"), + Timestamp: time.Now().Truncate(time.Second), + WIP: false, + } + data := l2_shared.ProcessData{ + BatchNumber: 123, + Mode: l2_shared.FullProcessMode, + BatchMustBeClosed: true, + DebugPrefix: "test", + StateBatch: nil, + TrustedBatch: &types.Batch{ + Number: 123, + Coinbase: expectedBatch.Coinbase, + StateRoot: expectedBatch.StateRoot, + GlobalExitRoot: expectedBatch.GlobalExitRoot, + LocalExitRoot: expectedBatch.LocalExitRoot, + Timestamp: (types.ArgUint64)(expectedBatch.Timestamp.Unix()), + Closed: true, + }, + } + testData.stateMock.EXPECT().OpenBatch(testData.ctx, mock.Anything, mock.Anything).Return(nil).Once() + testData.stateMock.EXPECT().CloseBatch(testData.ctx, mock.Anything, mock.Anything).Return(nil).Once() + + response, err := testData.sut.FullProcess(testData.ctx, &data, nil) + require.NoError(t, err) + require.Equal(t, false, response.ClearCache) + require.Equal(t, false, response.UpdateBatchWithProcessBatchResponse) + require.Equal(t, false, response.UpdateBatch.WIP) + require.Equal(t, 0, len(response.UpdateBatch.BatchL2Data)) + require.Equal(t, expectedBatch, *response.UpdateBatch) +} diff --git a/synchronizer/l2_sync/l2_sync_etrog/mocks/l1_sync_checker.go b/synchronizer/l2_sync/l2_sync_etrog/mocks/l1_sync_checker.go deleted file mode 100644 index ced3c7a54f..0000000000 --- a/synchronizer/l2_sync/l2_sync_etrog/mocks/l1_sync_checker.go +++ /dev/null @@ -1,89 +0,0 @@ -// Code generated by mockery. DO NOT EDIT. - -package mock_l2_sync_etrog - -import ( - context "context" - - common "github.com/ethereum/go-ethereum/common" - - mock "github.com/stretchr/testify/mock" - - pgx "github.com/jackc/pgx/v4" -) - -// L1SyncChecker is an autogenerated mock type for the L1SyncChecker type -type L1SyncChecker struct { - mock.Mock -} - -type L1SyncChecker_Expecter struct { - mock *mock.Mock -} - -func (_m *L1SyncChecker) EXPECT() *L1SyncChecker_Expecter { - return &L1SyncChecker_Expecter{mock: &_m.Mock} -} - -// CheckL1SyncStatusEnoughToProcessBatch provides a mock function with given fields: ctx, batchNumber, globalExitRoot, dbTx -func (_m *L1SyncChecker) CheckL1SyncStatusEnoughToProcessBatch(ctx context.Context, batchNumber uint64, globalExitRoot common.Hash, dbTx pgx.Tx) error { - ret := _m.Called(ctx, batchNumber, globalExitRoot, dbTx) - - if len(ret) == 0 { - panic("no return value specified for CheckL1SyncStatusEnoughToProcessBatch") - } - - var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, common.Hash, pgx.Tx) error); ok { - r0 = rf(ctx, batchNumber, globalExitRoot, dbTx) - } else { - r0 = ret.Error(0) - } - - return r0 -} - -// L1SyncChecker_CheckL1SyncStatusEnoughToProcessBatch_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'CheckL1SyncStatusEnoughToProcessBatch' -type L1SyncChecker_CheckL1SyncStatusEnoughToProcessBatch_Call struct { - *mock.Call -} - -// CheckL1SyncStatusEnoughToProcessBatch is a helper method to define mock.On call -// - ctx context.Context -// - batchNumber uint64 -// - globalExitRoot common.Hash -// - dbTx pgx.Tx -func (_e *L1SyncChecker_Expecter) CheckL1SyncStatusEnoughToProcessBatch(ctx interface{}, batchNumber interface{}, globalExitRoot interface{}, dbTx interface{}) *L1SyncChecker_CheckL1SyncStatusEnoughToProcessBatch_Call { - return &L1SyncChecker_CheckL1SyncStatusEnoughToProcessBatch_Call{Call: _e.mock.On("CheckL1SyncStatusEnoughToProcessBatch", ctx, batchNumber, globalExitRoot, dbTx)} -} - -func (_c *L1SyncChecker_CheckL1SyncStatusEnoughToProcessBatch_Call) Run(run func(ctx context.Context, batchNumber uint64, globalExitRoot common.Hash, dbTx pgx.Tx)) *L1SyncChecker_CheckL1SyncStatusEnoughToProcessBatch_Call { - _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint64), args[2].(common.Hash), args[3].(pgx.Tx)) - }) - return _c -} - -func (_c *L1SyncChecker_CheckL1SyncStatusEnoughToProcessBatch_Call) Return(_a0 error) *L1SyncChecker_CheckL1SyncStatusEnoughToProcessBatch_Call { - _c.Call.Return(_a0) - return _c -} - -func (_c *L1SyncChecker_CheckL1SyncStatusEnoughToProcessBatch_Call) RunAndReturn(run func(context.Context, uint64, common.Hash, pgx.Tx) error) *L1SyncChecker_CheckL1SyncStatusEnoughToProcessBatch_Call { - _c.Call.Return(run) - return _c -} - -// NewL1SyncChecker creates a new instance of L1SyncChecker. It also registers a testing interface on the mock and a cleanup function to assert the mocks expectations. -// The first argument is typically a *testing.T value. -func NewL1SyncChecker(t interface { - mock.TestingT - Cleanup(func()) -}) *L1SyncChecker { - mock := &L1SyncChecker{} - mock.Mock.Test(t) - - t.Cleanup(func() { mock.AssertExpectations(t) }) - - return mock -} diff --git a/synchronizer/l2_sync/l2_sync_etrog/mocks/state_interface.go b/synchronizer/l2_sync/l2_sync_etrog/mocks/state_interface.go index 1772294e0c..5101bb4b6a 100644 --- a/synchronizer/l2_sync/l2_sync_etrog/mocks/state_interface.go +++ b/synchronizer/l2_sync/l2_sync_etrog/mocks/state_interface.go @@ -317,6 +317,63 @@ func (_c *StateInterface_GetL1InfoTreeDataFromBatchL2Data_Call) RunAndReturn(run return _c } +// GetLastVirtualBatchNum provides a mock function with given fields: ctx, dbTx +func (_m *StateInterface) GetLastVirtualBatchNum(ctx context.Context, dbTx pgx.Tx) (uint64, error) { + ret := _m.Called(ctx, dbTx) + + if len(ret) == 0 { + panic("no return value specified for GetLastVirtualBatchNum") + } + + var r0 uint64 + var r1 error + if rf, ok := ret.Get(0).(func(context.Context, pgx.Tx) (uint64, error)); ok { + return rf(ctx, dbTx) + } + if rf, ok := ret.Get(0).(func(context.Context, pgx.Tx) uint64); ok { + r0 = rf(ctx, dbTx) + } else { + r0 = ret.Get(0).(uint64) + } + + if rf, ok := ret.Get(1).(func(context.Context, pgx.Tx) error); ok { + r1 = rf(ctx, dbTx) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// StateInterface_GetLastVirtualBatchNum_Call is a *mock.Call that shadows Run/Return methods with type explicit version for method 'GetLastVirtualBatchNum' +type StateInterface_GetLastVirtualBatchNum_Call struct { + *mock.Call +} + +// GetLastVirtualBatchNum is a helper method to define mock.On call +// - ctx context.Context +// - dbTx pgx.Tx +func (_e *StateInterface_Expecter) GetLastVirtualBatchNum(ctx interface{}, dbTx interface{}) *StateInterface_GetLastVirtualBatchNum_Call { + return &StateInterface_GetLastVirtualBatchNum_Call{Call: _e.mock.On("GetLastVirtualBatchNum", ctx, dbTx)} +} + +func (_c *StateInterface_GetLastVirtualBatchNum_Call) Run(run func(ctx context.Context, dbTx pgx.Tx)) *StateInterface_GetLastVirtualBatchNum_Call { + _c.Call.Run(func(args mock.Arguments) { + run(args[0].(context.Context), args[1].(pgx.Tx)) + }) + return _c +} + +func (_c *StateInterface_GetLastVirtualBatchNum_Call) Return(_a0 uint64, _a1 error) *StateInterface_GetLastVirtualBatchNum_Call { + _c.Call.Return(_a0, _a1) + return _c +} + +func (_c *StateInterface_GetLastVirtualBatchNum_Call) RunAndReturn(run func(context.Context, pgx.Tx) (uint64, error)) *StateInterface_GetLastVirtualBatchNum_Call { + _c.Call.Return(run) + return _c +} + // OpenBatch provides a mock function with given fields: ctx, processingContext, dbTx func (_m *StateInterface) OpenBatch(ctx context.Context, processingContext state.ProcessingContext, dbTx pgx.Tx) error { ret := _m.Called(ctx, processingContext, dbTx) diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 6e49c064b5..591b2f4357 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -109,16 +109,19 @@ func NewSynchronizer( l1EventProcessors: nil, halter: syncCommon.NewCriticalErrorHalt(eventLog, 5*time.Second), //nolint:gomnd } - L1SyncChecker := l2_sync_etrog.NewCheckSyncStatusToProcessBatch(res.zkEVMClient, res.state) - syncTrustedStateEtrog := l2_sync_etrog.NewSyncTrustedBatchExecutorForEtrog(res.zkEVMClient, res.state, res.state, res, - syncCommon.DefaultTimeProvider{}, L1SyncChecker) + if !isTrustedSequencer { + log.Info("Permissionless: creating and Initializing L2 synchronization components") + L1SyncChecker := l2_sync_etrog.NewCheckSyncStatusToProcessBatch(res.zkEVMClient, res.state) - res.syncTrustedStateExecutor = l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ - uint64(state.FORKID_ETROG): syncTrustedStateEtrog, - uint64(state.FORKID_ELDERBERRY): syncTrustedStateEtrog, - }, res.state) + syncTrustedStateEtrog := l2_sync_etrog.NewSyncTrustedBatchExecutorForEtrog(res.zkEVMClient, res.state, res.state, res, + syncCommon.DefaultTimeProvider{}, L1SyncChecker, cfg.L2Synchronization) + res.syncTrustedStateExecutor = l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ + uint64(state.FORKID_ETROG): syncTrustedStateEtrog, + uint64(state.FORKID_ELDERBERRY): syncTrustedStateEtrog, + }, res.state) + } res.l1EventProcessors = defaultsL1EventProcessors(res) switch cfg.L1SynchronizationMode { case ParallelMode: @@ -161,7 +164,7 @@ func newL1SyncParallel(ctx context.Context, cfg Config, etherManForL1 []syncinte l1SyncOrchestration := l1_parallel_sync.NewL1SyncOrchestration(ctx, l1DataRetriever, L1DataProcessor) if runExternalControl { log.Infof("Starting external control") - externalControl := newExternalControl(l1DataRetriever, l1SyncOrchestration) + externalControl := newExternalCmdControl(l1DataRetriever, l1SyncOrchestration) externalControl.start() } return l1SyncOrchestration @@ -367,6 +370,7 @@ func (s *ClientSynchronizer) Sync() error { metrics.FullL1SyncTime(time.Since(startL1)) if err != nil { log.Warn("error syncing blocks: ", err) + s.CleanTrustedState() lastEthBlockSynced, err = s.state.GetLastBlock(s.ctx, nil) if err != nil { log.Fatal("error getting lastEthBlockSynced to resume the synchronization... Error: ", err) From 4769da06a7688e3894d65ef313a699ba5f2918a1 Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Tue, 27 Feb 2024 18:43:03 +0100 Subject: [PATCH 35/51] fix metrics cleanUp (#3385) --- sequencer/metrics.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sequencer/metrics.go b/sequencer/metrics.go index 43bd828157..409cc79d97 100644 --- a/sequencer/metrics.go +++ b/sequencer/metrics.go @@ -123,6 +123,8 @@ func (i *intervalMetrics) cleanUp() { i.estimatedTxsPerSecAcc -= i.estimatedTxsPerSec i.estimatedTxsPerSecCount-- } + // Remove from l2Blocks + i.l2Blocks = i.l2Blocks[1:] ct++ } else { break @@ -130,8 +132,6 @@ func (i *intervalMetrics) cleanUp() { } if ct > 0 { - // Remove from l2Blocks - i.l2Blocks = i.l2Blocks[ct:] // Compute performance i.computeEstimatedTxsPerSec() } From f7f1809245e8571d4313638674facbb474c80a7b Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Wed, 28 Feb 2024 14:45:24 +0100 Subject: [PATCH 36/51] fix check poseidonHashes exhausted (#3393) --- sequencer/batch.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/sequencer/batch.go b/sequencer/batch.go index 34d9c870af..866d29b1d6 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -457,6 +457,9 @@ func (f *finalizer) isBatchResourcesMarginExhausted(resources state.BatchResourc } else if zkCounters.PoseidonPaddings <= f.getConstraintThresholdUint32(f.batchConstraints.MaxPoseidonPaddings) { resourceName = "PoseidonPaddings" result = true + } else if zkCounters.PoseidonHashes <= f.getConstraintThresholdUint32(f.batchConstraints.MaxPoseidonHashes) { + resourceName = "PoseidonHashes" + result = true } else if zkCounters.Binaries <= f.getConstraintThresholdUint32(f.batchConstraints.MaxBinaries) { resourceName = "Binaries" result = true From e0cd81e4512e2a8c212611e1a8b72c1b245c6a3c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Wed, 28 Feb 2024 16:43:46 +0100 Subject: [PATCH 37/51] remove execution mode (#3395) --- proto/src/proto/executor/v1/executor.proto | 1 - sequencer/batch.go | 2 - sequencer/finalizer.go | 1 - sequencer/forcedbatch.go | 2 - sequencer/l2block.go | 3 - state/batchV2.go | 3 - state/runtime/executor/client.go | 7 - state/runtime/executor/executor.pb.go | 1578 ++++++++--------- state/trace.go | 1 - state/transaction.go | 2 - .../etrog/processor_l1_sequence_batches.go | 3 - .../processor_l1_update_etrog_sequence.go | 2 - .../executor_trusted_batch_sync.go | 2 - .../l2_sync_incaberry/sync_trusted_state.go | 1 - 14 files changed, 784 insertions(+), 824 deletions(-) diff --git a/proto/src/proto/executor/v1/executor.proto b/proto/src/proto/executor/v1/executor.proto index ba1f135304..e18008ba58 100644 --- a/proto/src/proto/executor/v1/executor.proto +++ b/proto/src/proto/executor/v1/executor.proto @@ -292,7 +292,6 @@ message ProcessBatchRequestV2 { // prior to executing the call. map state_override = 23; DebugV2 debug = 24; - uint64 execution_mode = 25; } message L1DataV2 { diff --git a/sequencer/batch.go b/sequencer/batch.go index 866d29b1d6..1d644b22c5 100644 --- a/sequencer/batch.go +++ b/sequencer/batch.go @@ -10,7 +10,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" - "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/ethereum/go-ethereum/common" ) @@ -377,7 +376,6 @@ func (f *finalizer) batchSanityCheck(ctx context.Context, batchNum uint64, initi ForkID: f.stateIntf.GetForkIDByBatchNumber(batch.BatchNumber), SkipVerifyL1InfoRoot_V2: true, Caller: stateMetrics.DiscardCallerLabel, - ExecutionMode: executor.ExecutionMode0, } batchRequest.L1InfoTreeData_V2, _, _, err = f.stateIntf.GetL1InfoTreeDataFromBatchL2Data(ctx, batch.BatchL2Data, nil) if err != nil { diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index 5da6c9cdef..1c0e46489b 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -363,7 +363,6 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first SkipWriteBlockInfoRoot_V2: true, SkipVerifyL1InfoRoot_V2: true, L1InfoTreeData_V2: map[uint32]state.L1DataV2{}, - ExecutionMode: executor.ExecutionMode0, } txGasPrice := tx.GasPrice diff --git a/sequencer/forcedbatch.go b/sequencer/forcedbatch.go index 9150e7c5f7..ebe078c1b8 100644 --- a/sequencer/forcedbatch.go +++ b/sequencer/forcedbatch.go @@ -8,7 +8,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" - "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/ethereum/go-ethereum/common" "github.com/jackc/pgx/v4" ) @@ -106,7 +105,6 @@ func (f *finalizer) processForcedBatch(ctx context.Context, forcedBatch state.Fo ForkID: f.stateIntf.GetForkIDByBatchNumber(lastBatchNumber), SkipVerifyL1InfoRoot_V2: true, Caller: stateMetrics.DiscardCallerLabel, - ExecutionMode: executor.ExecutionMode0, } batchResponse, err := f.stateIntf.ProcessBatchV2(ctx, batchRequest, true) diff --git a/sequencer/l2block.go b/sequencer/l2block.go index c674bf4a18..a148d5b5ea 100644 --- a/sequencer/l2block.go +++ b/sequencer/l2block.go @@ -11,7 +11,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/pool" "github.com/0xPolygonHermez/zkevm-node/state" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" - "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/ethereum/go-ethereum/common" ) @@ -284,7 +283,6 @@ func (f *finalizer) executeL2Block(ctx context.Context, initialStateRoot common. ForkID: f.stateIntf.GetForkIDByBatchNumber(f.wipBatch.batchNumber), SkipVerifyL1InfoRoot_V2: true, L1InfoTreeData_V2: map[uint32]state.L1DataV2{}, - ExecutionMode: executor.ExecutionMode0, } batchRequest.L1InfoTreeData_V2[l2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{ GlobalExitRoot: l2Block.l1InfoTreeExitRoot.GlobalExitRoot.GlobalExitRoot, @@ -584,7 +582,6 @@ func (f *finalizer) executeNewWIPL2Block(ctx context.Context) (*state.ProcessBat SkipFirstChangeL2Block_V2: false, Transactions: f.stateIntf.BuildChangeL2Block(f.wipL2Block.deltaTimestamp, f.wipL2Block.getL1InfoTreeIndex()), L1InfoTreeData_V2: map[uint32]state.L1DataV2{}, - ExecutionMode: executor.ExecutionMode0, } batchRequest.L1InfoTreeData_V2[f.wipL2Block.l1InfoTreeExitRoot.L1InfoTreeIndex] = state.L1DataV2{ diff --git a/state/batchV2.go b/state/batchV2.go index d12ae209c7..de402ba92f 100644 --- a/state/batchV2.go +++ b/state/batchV2.go @@ -69,7 +69,6 @@ func (s *State) ProcessBatchV2(ctx context.Context, request ProcessRequest, upda ChainId: s.cfg.ChainID, ForkId: request.ForkID, ContextId: uuid.NewString(), - ExecutionMode: request.ExecutionMode, } if request.SkipFirstChangeL2Block_V2 { @@ -132,7 +131,6 @@ func (s *State) ExecuteBatchV2(ctx context.Context, batch Batch, L1InfoTreeRoot ForkId: forkId, ContextId: uuid.NewString(), SkipVerifyL1InfoRoot: skipVerifyL1InfoRoot, - ExecutionMode: executor.ExecutionMode1, } if forcedBlockHashL1 != nil { @@ -233,7 +231,6 @@ func (s *State) processBatchV2(ctx context.Context, processingCtx *ProcessingCon ContextId: uuid.NewString(), SkipVerifyL1InfoRoot: processingCtx.SkipVerifyL1InfoRoot, L1InfoRoot: processingCtx.L1InfoRoot.Bytes(), - ExecutionMode: processingCtx.ExecutionMode, } if processingCtx.ForcedBlockHashL1 != nil { diff --git a/state/runtime/executor/client.go b/state/runtime/executor/client.go index 40f39bfb50..b386d4320f 100644 --- a/state/runtime/executor/client.go +++ b/state/runtime/executor/client.go @@ -10,13 +10,6 @@ import ( "google.golang.org/grpc/credentials/insecure" ) -const ( - // ExecutionMode0 is the execution mode for the sequencer and RPC, default one - ExecutionMode0 = uint64(0) - // ExecutionMode1 is the execution mode for the synchronizer - ExecutionMode1 = uint64(1) -) - // NewExecutorClient is the executor client constructor. func NewExecutorClient(ctx context.Context, c Config) (ExecutorServiceClient, *grpc.ClientConn, context.CancelFunc) { opts := []grpc.DialOption{ diff --git a/state/runtime/executor/executor.pb.go b/state/runtime/executor/executor.pb.go index ab7c53e6d6..af7ad962b8 100644 --- a/state/runtime/executor/executor.pb.go +++ b/state/runtime/executor/executor.pb.go @@ -2224,7 +2224,6 @@ type ProcessBatchRequestV2 struct { // prior to executing the call. StateOverride map[string]*OverrideAccountV2 `protobuf:"bytes,23,rep,name=state_override,json=stateOverride,proto3" json:"state_override,omitempty" protobuf_key:"bytes,1,opt,name=key,proto3" protobuf_val:"bytes,2,opt,name=value,proto3"` Debug *DebugV2 `protobuf:"bytes,24,opt,name=debug,proto3" json:"debug,omitempty"` - ExecutionMode uint64 `protobuf:"varint,25,opt,name=execution_mode,json=executionMode,proto3" json:"execution_mode,omitempty"` } func (x *ProcessBatchRequestV2) Reset() { @@ -2427,13 +2426,6 @@ func (x *ProcessBatchRequestV2) GetDebug() *DebugV2 { return nil } -func (x *ProcessBatchRequestV2) GetExecutionMode() uint64 { - if x != nil { - return x.ExecutionMode - } - return 0 -} - type L1DataV2 struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -4423,7 +4415,7 @@ var file_executor_proto_rawDesc = []byte{ 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x61, 0x74, 0x63, 0x68, 0x48, 0x61, 0x73, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, - 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xfc, + 0x78, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x22, 0xd5, 0x0b, 0x0a, 0x15, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x56, 0x32, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, @@ -4497,822 +4489,820 @@ var file_executor_proto_rawDesc = []byte{ 0x72, 0x79, 0x52, 0x0d, 0x73, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x12, 0x2a, 0x0a, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x14, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x44, - 0x65, 0x62, 0x75, 0x67, 0x56, 0x32, 0x52, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x12, 0x25, 0x0a, - 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x18, - 0x19, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, - 0x4d, 0x6f, 0x64, 0x65, 0x1a, 0x58, 0x0a, 0x13, 0x4c, 0x31, 0x49, 0x6e, 0x66, 0x6f, 0x54, 0x72, - 0x65, 0x65, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, - 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x31, 0x44, 0x61, 0x74, - 0x61, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x35, - 0x0a, 0x07, 0x44, 0x62, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x44, 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, - 0x74, 0x73, 0x42, 0x79, 0x74, 0x65, 0x63, 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, - 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, - 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x60, 0x0a, 0x12, 0x53, - 0x74, 0x61, 0x74, 0x65, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x34, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, - 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9a, 0x01, - 0x0a, 0x08, 0x4c, 0x31, 0x44, 0x61, 0x74, 0x61, 0x56, 0x32, 0x12, 0x28, 0x0a, 0x10, 0x67, 0x6c, - 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, - 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, - 0x73, 0x68, 0x5f, 0x6c, 0x31, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x31, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, - 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, - 0x0c, 0x6d, 0x69, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1b, 0x0a, - 0x09, 0x73, 0x6d, 0x74, 0x5f, 0x70, 0x72, 0x6f, 0x6f, 0x66, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x08, 0x73, 0x6d, 0x74, 0x50, 0x72, 0x6f, 0x6f, 0x66, 0x22, 0xcc, 0x01, 0x0a, 0x07, 0x44, - 0x65, 0x62, 0x75, 0x67, 0x56, 0x32, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, - 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, - 0x6d, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, 0x77, - 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x77, - 0x5f, 0x61, 0x63, 0x63, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x6e, 0x65, 0x77, 0x41, 0x63, 0x63, 0x49, 0x6e, 0x70, - 0x75, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2d, 0x0a, 0x13, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, - 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x78, 0x69, - 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x77, 0x5f, 0x62, 0x61, 0x74, - 0x63, 0x68, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, - 0x77, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4e, 0x75, 0x6d, 0x22, 0xcb, 0x0c, 0x0a, 0x16, 0x50, 0x72, - 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x56, 0x32, 0x12, 0x24, 0x0a, 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, - 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, - 0x77, 0x5f, 0x61, 0x63, 0x63, 0x5f, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, 0x6e, 0x65, 0x77, 0x41, 0x63, 0x63, 0x49, 0x6e, - 0x70, 0x75, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x2d, 0x0a, 0x13, 0x6e, 0x65, 0x77, 0x5f, 0x6c, - 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6e, 0x65, 0x77, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x78, - 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x77, 0x5f, 0x62, 0x61, - 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x75, 0x6d, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, - 0x65, 0x77, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4e, 0x75, 0x6d, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6e, - 0x74, 0x5f, 0x6b, 0x65, 0x63, 0x63, 0x61, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, - 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x63, 0x6e, 0x74, 0x4b, 0x65, 0x63, 0x63, 0x61, 0x6b, - 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x6e, 0x74, 0x5f, 0x70, 0x6f, - 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x11, 0x63, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, - 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x32, 0x0a, 0x15, 0x63, 0x6e, 0x74, 0x5f, 0x70, 0x6f, - 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x63, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x65, 0x69, 0x64, - 0x6f, 0x6e, 0x50, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6e, - 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x6e, 0x74, 0x4d, 0x65, 0x6d, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x73, - 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6e, 0x74, 0x5f, 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, - 0x69, 0x63, 0x73, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x63, 0x6e, 0x74, 0x41, 0x72, - 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6e, 0x74, - 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x0b, 0x63, 0x6e, 0x74, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, - 0x63, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x08, 0x63, 0x6e, 0x74, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6e, 0x74, - 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x0c, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x63, 0x6e, 0x74, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, - 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x4c, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, - 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, - 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x56, 0x32, 0x52, 0x0e, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0e, 0x20, 0x01, - 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x6d, 0x0a, 0x14, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x77, 0x72, - 0x69, 0x74, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x0f, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x3b, 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, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, - 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x12, 0x72, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, - 0x73, 0x73, 0x65, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x64, - 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x64, 0x12, - 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x5f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, - 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, - 0x46, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x65, - 0x72, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, - 0x65, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, - 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, - 0x19, 0x0a, 0x08, 0x73, 0x6d, 0x74, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, - 0x0c, 0x52, 0x07, 0x73, 0x6d, 0x74, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, - 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x5f, 0x6b, 0x65, 0x79, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0c, - 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x17, 0x0a, - 0x07, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x69, 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, - 0x66, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, - 0x64, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x69, - 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, 0x61, 0x74, 0x63, 0x68, 0x12, 0x32, 0x0a, 0x09, 0x65, - 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x6f, 0x6d, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, - 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, - 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x08, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x6f, 0x6d, 0x12, - 0x39, 0x0a, 0x19, 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x6b, - 0x65, 0x63, 0x63, 0x61, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x19, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x16, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4b, 0x65, - 0x63, 0x63, 0x61, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x1b, 0x63, 0x6e, - 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x65, 0x69, 0x64, - 0x6f, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0d, 0x52, - 0x18, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x50, 0x6f, 0x73, 0x65, 0x69, - 0x64, 0x6f, 0x6e, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x41, 0x0a, 0x1d, 0x63, 0x6e, 0x74, - 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, - 0x6e, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0d, - 0x52, 0x1a, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x50, 0x6f, 0x73, 0x65, - 0x69, 0x64, 0x6f, 0x6e, 0x50, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x33, 0x0a, 0x16, - 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, - 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x73, 0x18, 0x1c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x63, 0x6e, - 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4d, 0x65, 0x6d, 0x41, 0x6c, 0x69, 0x67, 0x6e, - 0x73, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x5f, 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x73, 0x18, 0x1d, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x15, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x41, 0x72, - 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x6e, 0x74, - 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, - 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x12, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x42, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, - 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, - 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x53, 0x74, 0x65, 0x70, 0x73, 0x12, 0x39, 0x0a, 0x19, 0x63, 0x6e, 0x74, 0x5f, 0x72, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, - 0x73, 0x68, 0x65, 0x73, 0x18, 0x20, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x63, 0x6e, 0x74, 0x52, - 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, - 0x65, 0x73, 0x1a, 0x63, 0x0a, 0x17, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, - 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, - 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, - 0x32, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, - 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, - 0x6f, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, - 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0xf3, 0x01, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x63, - 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, 0x56, 0x32, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, - 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, - 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, - 0x6c, 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, - 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x12, - 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, - 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, - 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x1e, 0x74, 0x78, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x74, 0x6f, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, - 0x65, 0x5f, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x19, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x65, 0x6e, 0x65, - 0x72, 0x61, 0x74, 0x65, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x22, 0xde, 0x02, - 0x0a, 0x11, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, - 0x74, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, - 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, - 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x3f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, - 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, - 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, - 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x12, 0x4c, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, - 0x65, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x18, 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, - 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, - 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, - 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x73, 0x74, 0x61, - 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x1a, 0x38, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, + 0x65, 0x62, 0x75, 0x67, 0x56, 0x32, 0x52, 0x05, 0x64, 0x65, 0x62, 0x75, 0x67, 0x1a, 0x58, 0x0a, + 0x13, 0x4c, 0x31, 0x49, 0x6e, 0x66, 0x6f, 0x54, 0x72, 0x65, 0x65, 0x44, 0x61, 0x74, 0x61, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, - 0x1a, 0x3c, 0x0a, 0x0e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, + 0x0d, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x2b, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x31, 0x44, 0x61, 0x74, 0x61, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x35, 0x0a, 0x07, 0x44, 0x62, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x41, - 0x0a, 0x0f, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x56, - 0x32, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, - 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, - 0x65, 0x22, 0x80, 0x01, 0x0a, 0x0b, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, - 0x32, 0x12, 0x3b, 0x0a, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, - 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, - 0x65, 0x78, 0x74, 0x56, 0x32, 0x52, 0x07, 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x34, - 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, - 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, - 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x52, 0x05, 0x73, - 0x74, 0x65, 0x70, 0x73, 0x22, 0x92, 0x03, 0x0a, 0x14, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, - 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x56, 0x32, 0x12, 0x12, 0x0a, - 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, - 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, - 0x75, 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, - 0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, - 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, - 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, - 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x73, - 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x0c, 0x6f, 0x6c, 0x64, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, - 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, - 0x6e, 0x63, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, - 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x19, - 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, 0x49, 0x64, 0x22, 0xae, 0x04, 0x0a, 0x11, 0x54, 0x72, - 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x12, - 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, - 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, - 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, - 0x65, 0x70, 0x74, 0x68, 0x12, 0x0e, 0x0a, 0x02, 0x70, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, - 0x52, 0x02, 0x70, 0x63, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x63, 0x6f, - 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, - 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x67, 0x61, 0x73, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, - 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x70, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x6f, 0x70, - 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, - 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x12, 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, - 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x1f, - 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, - 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x12, - 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, - 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4f, 0x66, - 0x66, 0x73, 0x65, 0x74, 0x12, 0x1f, 0x0a, 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, - 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, - 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x33, 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, - 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, - 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x45, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, - 0x67, 0x65, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, - 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, - 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x1a, 0x3a, - 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, - 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, - 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x8e, 0x01, 0x0a, 0x0a, 0x43, - 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, - 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, - 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x76, - 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, - 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x22, 0xe9, 0x03, 0x0a, 0x16, - 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, - 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, - 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, - 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, - 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, - 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, - 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, - 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, - 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, - 0x70, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x65, 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, - 0x67, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, - 0x68, 0x5f, 0x6c, 0x31, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x31, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, - 0x73, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, - 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, - 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x47, 0x0a, 0x09, 0x72, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x44, + 0x0a, 0x16, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x73, 0x42, 0x79, 0x74, 0x65, 0x63, + 0x6f, 0x64, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, + 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x60, 0x0a, 0x12, 0x53, 0x74, 0x61, 0x74, 0x65, 0x4f, 0x76, 0x65, + 0x72, 0x72, 0x69, 0x64, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, + 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x34, 0x0a, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, + 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x9a, 0x01, 0x0a, 0x08, 0x4c, 0x31, 0x44, 0x61, 0x74, + 0x61, 0x56, 0x32, 0x12, 0x28, 0x0a, 0x10, 0x67, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x5f, 0x65, 0x78, + 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0e, 0x67, + 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, 0x0a, + 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x31, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x4c, + 0x31, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x69, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, + 0x6d, 0x70, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0c, 0x6d, 0x69, 0x6e, 0x54, 0x69, 0x6d, + 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x1b, 0x0a, 0x09, 0x73, 0x6d, 0x74, 0x5f, 0x70, 0x72, + 0x6f, 0x6f, 0x66, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x08, 0x73, 0x6d, 0x74, 0x50, 0x72, + 0x6f, 0x6f, 0x66, 0x22, 0xcc, 0x01, 0x0a, 0x07, 0x44, 0x65, 0x62, 0x75, 0x67, 0x56, 0x32, 0x12, + 0x1b, 0x0a, 0x09, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x24, 0x0a, 0x0e, + 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, + 0x6f, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x63, 0x63, 0x5f, 0x69, 0x6e, + 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0f, + 0x6e, 0x65, 0x77, 0x41, 0x63, 0x63, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x48, 0x61, 0x73, 0x68, 0x12, + 0x2d, 0x0a, 0x13, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, 0x69, + 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6e, 0x65, + 0x77, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x22, + 0x0a, 0x0d, 0x6e, 0x65, 0x77, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x75, 0x6d, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x42, 0x61, 0x74, 0x63, 0x68, 0x4e, + 0x75, 0x6d, 0x22, 0xcb, 0x0c, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x61, + 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x24, 0x0a, + 0x0e, 0x6e, 0x65, 0x77, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, + 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6e, 0x65, 0x77, 0x53, 0x74, 0x61, 0x74, 0x65, 0x52, + 0x6f, 0x6f, 0x74, 0x12, 0x2b, 0x0a, 0x12, 0x6e, 0x65, 0x77, 0x5f, 0x61, 0x63, 0x63, 0x5f, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x0f, 0x6e, 0x65, 0x77, 0x41, 0x63, 0x63, 0x49, 0x6e, 0x70, 0x75, 0x74, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x2d, 0x0a, 0x13, 0x6e, 0x65, 0x77, 0x5f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x78, + 0x69, 0x74, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x10, 0x6e, + 0x65, 0x77, 0x4c, 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x78, 0x69, 0x74, 0x52, 0x6f, 0x6f, 0x74, 0x12, + 0x22, 0x0a, 0x0d, 0x6e, 0x65, 0x77, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, 0x5f, 0x6e, 0x75, 0x6d, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x6e, 0x65, 0x77, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x4e, 0x75, 0x6d, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6e, 0x74, 0x5f, 0x6b, 0x65, 0x63, 0x63, 0x61, + 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, + 0x63, 0x6e, 0x74, 0x4b, 0x65, 0x63, 0x63, 0x61, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, + 0x2e, 0x0a, 0x13, 0x63, 0x6e, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x5f, + 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x63, 0x6e, + 0x74, 0x50, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, + 0x32, 0x0a, 0x15, 0x63, 0x6e, 0x74, 0x5f, 0x70, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x5f, + 0x70, 0x61, 0x64, 0x64, 0x69, 0x6e, 0x67, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, + 0x63, 0x6e, 0x74, 0x50, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x50, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x63, 0x6e, 0x74, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x61, + 0x6c, 0x69, 0x67, 0x6e, 0x73, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x63, 0x6e, 0x74, + 0x4d, 0x65, 0x6d, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x73, 0x12, 0x27, 0x0a, 0x0f, 0x63, 0x6e, 0x74, + 0x5f, 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, 0x63, 0x73, 0x18, 0x09, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0e, 0x63, 0x6e, 0x74, 0x41, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, + 0x63, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x63, 0x6e, 0x74, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x69, + 0x65, 0x73, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0b, 0x63, 0x6e, 0x74, 0x42, 0x69, 0x6e, + 0x61, 0x72, 0x69, 0x65, 0x73, 0x12, 0x1b, 0x0a, 0x09, 0x63, 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x65, + 0x70, 0x73, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x08, 0x63, 0x6e, 0x74, 0x53, 0x74, 0x65, + 0x70, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6e, 0x74, 0x5f, 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0f, 0x63, + 0x6e, 0x74, 0x53, 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x12, 0x4c, + 0x0a, 0x0f, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, + 0x73, 0x18, 0x0d, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x42, 0x6c, 0x6f, + 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x52, 0x0e, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x30, 0x0a, 0x05, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x1a, 0x2e, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x45, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x6f, 0x72, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x6d, + 0x0a, 0x14, 0x72, 0x65, 0x61, 0x64, 0x5f, 0x77, 0x72, 0x69, 0x74, 0x65, 0x5f, 0x61, 0x64, 0x64, + 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, - 0x73, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, - 0x32, 0x12, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, - 0x6f, 0x67, 0x56, 0x32, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, - 0x72, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, - 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, - 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x22, 0x9b, 0x06, 0x0a, 0x1c, 0x50, 0x72, 0x6f, 0x63, - 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, - 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, - 0x68, 0x12, 0x1c, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x32, 0x18, - 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x32, 0x12, - 0x15, 0x0a, 0x06, 0x72, 0x6c, 0x70, 0x5f, 0x74, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x05, 0x72, 0x6c, 0x70, 0x54, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, - 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, - 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, - 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, - 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, - 0x28, 0x0c, 0x52, 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, - 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x65, 0x66, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, - 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x4c, 0x65, 0x66, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, - 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, - 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x2e, 0x0a, 0x13, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, - 0x69, 0x76, 0x65, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, - 0x28, 0x04, 0x52, 0x11, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x47, 0x61, - 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x21, 0x0a, 0x0c, 0x67, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x66, - 0x75, 0x6e, 0x64, 0x65, 0x64, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x67, 0x61, 0x73, - 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, - 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, - 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, - 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, - 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, - 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x6c, - 0x6f, 0x67, 0x73, 0x18, 0x0f, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x65, 0x78, 0x65, 0x63, + 0x73, 0x73, 0x42, 0x61, 0x74, 0x63, 0x68, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, + 0x32, 0x2e, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x65, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x12, 0x72, 0x65, 0x61, 0x64, 0x57, + 0x72, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, 0x73, 0x12, 0x19, 0x0a, + 0x08, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x64, 0x18, 0x10, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x07, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x73, 0x74, 0x6f, 0x72, + 0x65, 0x64, 0x5f, 0x66, 0x6c, 0x75, 0x73, 0x68, 0x5f, 0x69, 0x64, 0x18, 0x11, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x0d, 0x73, 0x74, 0x6f, 0x72, 0x65, 0x64, 0x46, 0x6c, 0x75, 0x73, 0x68, 0x49, 0x64, + 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x5f, 0x69, 0x64, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x08, 0x70, 0x72, 0x6f, 0x76, 0x65, 0x72, 0x49, 0x64, 0x12, 0x19, 0x0a, + 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x13, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x19, 0x0a, 0x08, 0x73, 0x6d, 0x74, 0x5f, + 0x6b, 0x65, 0x79, 0x73, 0x18, 0x14, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x07, 0x73, 0x6d, 0x74, 0x4b, + 0x65, 0x79, 0x73, 0x12, 0x21, 0x0a, 0x0c, 0x70, 0x72, 0x6f, 0x67, 0x72, 0x61, 0x6d, 0x5f, 0x6b, + 0x65, 0x79, 0x73, 0x18, 0x15, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x0b, 0x70, 0x72, 0x6f, 0x67, 0x72, + 0x61, 0x6d, 0x4b, 0x65, 0x79, 0x73, 0x12, 0x17, 0x0a, 0x07, 0x66, 0x6f, 0x72, 0x6b, 0x5f, 0x69, + 0x64, 0x18, 0x16, 0x20, 0x01, 0x28, 0x04, 0x52, 0x06, 0x66, 0x6f, 0x72, 0x6b, 0x49, 0x64, 0x12, + 0x23, 0x0a, 0x0d, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x5f, 0x62, 0x61, 0x74, 0x63, 0x68, + 0x18, 0x17, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x69, 0x6e, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x42, + 0x61, 0x74, 0x63, 0x68, 0x12, 0x32, 0x0a, 0x09, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x5f, 0x72, 0x6f, + 0x6d, 0x18, 0x18, 0x20, 0x01, 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x08, + 0x65, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x6f, 0x6d, 0x12, 0x39, 0x0a, 0x19, 0x63, 0x6e, 0x74, 0x5f, + 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x6b, 0x65, 0x63, 0x63, 0x61, 0x6b, 0x5f, 0x68, + 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x19, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x16, 0x63, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x4b, 0x65, 0x63, 0x63, 0x61, 0x6b, 0x48, 0x61, 0x73, + 0x68, 0x65, 0x73, 0x12, 0x3d, 0x0a, 0x1b, 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x5f, 0x68, 0x61, 0x73, 0x68, + 0x65, 0x73, 0x18, 0x1a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x18, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x50, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x48, 0x61, 0x73, 0x68, + 0x65, 0x73, 0x12, 0x41, 0x0a, 0x1d, 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x5f, 0x70, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x5f, 0x70, 0x61, 0x64, 0x64, 0x69, + 0x6e, 0x67, 0x73, 0x18, 0x1b, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x1a, 0x63, 0x6e, 0x74, 0x52, 0x65, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x50, 0x6f, 0x73, 0x65, 0x69, 0x64, 0x6f, 0x6e, 0x50, 0x61, 0x64, + 0x64, 0x69, 0x6e, 0x67, 0x73, 0x12, 0x33, 0x0a, 0x16, 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x5f, 0x61, 0x6c, 0x69, 0x67, 0x6e, 0x73, 0x18, + 0x1c, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x4d, 0x65, 0x6d, 0x41, 0x6c, 0x69, 0x67, 0x6e, 0x73, 0x12, 0x36, 0x0a, 0x17, 0x63, 0x6e, + 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, 0x61, 0x72, 0x69, 0x74, 0x68, 0x6d, + 0x65, 0x74, 0x69, 0x63, 0x73, 0x18, 0x1d, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x63, 0x6e, 0x74, + 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x41, 0x72, 0x69, 0x74, 0x68, 0x6d, 0x65, 0x74, 0x69, + 0x63, 0x73, 0x12, 0x30, 0x0a, 0x14, 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x5f, 0x62, 0x69, 0x6e, 0x61, 0x72, 0x69, 0x65, 0x73, 0x18, 0x1e, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x12, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x42, 0x69, 0x6e, 0x61, + 0x72, 0x69, 0x65, 0x73, 0x12, 0x2a, 0x0a, 0x11, 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, + 0x72, 0x76, 0x65, 0x5f, 0x73, 0x74, 0x65, 0x70, 0x73, 0x18, 0x1f, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0f, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x53, 0x74, 0x65, 0x70, 0x73, + 0x12, 0x39, 0x0a, 0x19, 0x63, 0x6e, 0x74, 0x5f, 0x72, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x5f, + 0x73, 0x68, 0x61, 0x32, 0x35, 0x36, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x65, 0x73, 0x18, 0x20, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x16, 0x63, 0x6e, 0x74, 0x52, 0x65, 0x73, 0x65, 0x72, 0x76, 0x65, 0x53, + 0x68, 0x61, 0x32, 0x35, 0x36, 0x48, 0x61, 0x73, 0x68, 0x65, 0x73, 0x1a, 0x63, 0x0a, 0x17, 0x52, + 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x41, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x65, + 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x32, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, + 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, + 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x49, 0x6e, 0x66, 0x6f, 0x52, 0x65, 0x61, 0x64, 0x57, 0x72, + 0x69, 0x74, 0x65, 0x56, 0x32, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, + 0x22, 0xf3, 0x01, 0x0a, 0x0d, 0x54, 0x72, 0x61, 0x63, 0x65, 0x43, 0x6f, 0x6e, 0x66, 0x69, 0x67, + 0x56, 0x32, 0x12, 0x27, 0x0a, 0x0f, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, + 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0e, 0x64, 0x69, 0x73, + 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x64, + 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0d, 0x52, 0x0c, 0x64, 0x69, 0x73, 0x61, 0x62, 0x6c, 0x65, 0x53, 0x74, 0x61, 0x63, 0x6b, + 0x12, 0x23, 0x0a, 0x0d, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, 0x6d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x4d, + 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x2c, 0x0a, 0x12, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x5f, + 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x10, 0x65, 0x6e, 0x61, 0x62, 0x6c, 0x65, 0x52, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, + 0x61, 0x74, 0x61, 0x12, 0x41, 0x0a, 0x1e, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x74, + 0x6f, 0x5f, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x5f, 0x66, 0x75, 0x6c, 0x6c, 0x5f, + 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x19, 0x74, 0x78, 0x48, + 0x61, 0x73, 0x68, 0x54, 0x6f, 0x47, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x74, 0x65, 0x46, 0x75, 0x6c, + 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x22, 0xde, 0x02, 0x0a, 0x11, 0x4f, 0x76, 0x65, 0x72, 0x72, + 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x62, + 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, + 0x02, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x12, 0x0a, 0x04, + 0x63, 0x6f, 0x64, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, + 0x12, 0x3f, 0x0a, 0x05, 0x73, 0x74, 0x61, 0x74, 0x65, 0x18, 0x04, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x29, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, + 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x56, 0x32, 0x2e, + 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x12, 0x4c, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x64, 0x69, 0x66, 0x66, 0x18, + 0x05, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x2d, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x4f, 0x76, 0x65, 0x72, 0x72, 0x69, 0x64, 0x65, 0x41, 0x63, 0x63, 0x6f, + 0x75, 0x6e, 0x74, 0x56, 0x32, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x1a, + 0x38, 0x0a, 0x0a, 0x53, 0x74, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x1a, 0x3c, 0x0a, 0x0e, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x44, 0x69, 0x66, 0x66, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, + 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, + 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, + 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x41, 0x0a, 0x0f, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x65, 0x61, 0x64, 0x57, 0x72, 0x69, 0x74, 0x65, 0x56, 0x32, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, + 0x6e, 0x63, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, + 0x12, 0x18, 0x0a, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x07, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x22, 0x80, 0x01, 0x0a, 0x0b, 0x46, + 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, 0x32, 0x12, 0x3b, 0x0a, 0x07, 0x63, 0x6f, + 0x6e, 0x74, 0x65, 0x78, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x65, 0x78, + 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, + 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x56, 0x32, 0x52, 0x07, + 0x63, 0x6f, 0x6e, 0x74, 0x65, 0x78, 0x74, 0x12, 0x34, 0x0a, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, + 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, + 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, + 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x52, 0x05, 0x73, 0x74, 0x65, 0x70, 0x73, 0x22, 0x92, 0x03, + 0x0a, 0x14, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x43, 0x6f, 0x6e, + 0x74, 0x65, 0x78, 0x74, 0x56, 0x32, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x66, 0x72, + 0x6f, 0x6d, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x66, 0x72, 0x6f, 0x6d, 0x12, 0x0e, + 0x0a, 0x02, 0x74, 0x6f, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x74, 0x6f, 0x12, 0x12, + 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x03, 0x67, 0x61, 0x73, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x06, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, + 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x16, 0x0a, 0x06, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x6f, 0x75, 0x74, 0x70, 0x75, + 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x09, 0x20, + 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x1b, 0x0a, 0x09, + 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x09, 0x52, + 0x08, 0x67, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x25, 0x0a, 0x0e, 0x65, 0x78, 0x65, + 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x74, 0x69, 0x6d, 0x65, 0x18, 0x0b, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x0d, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x69, 0x6f, 0x6e, 0x54, 0x69, 0x6d, 0x65, + 0x12, 0x24, 0x0a, 0x0e, 0x6f, 0x6c, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, 0x6f, + 0x6f, 0x74, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0c, 0x6f, 0x6c, 0x64, 0x53, 0x74, 0x61, + 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x18, + 0x0d, 0x20, 0x01, 0x28, 0x04, 0x52, 0x05, 0x6e, 0x6f, 0x6e, 0x63, 0x65, 0x12, 0x19, 0x0a, 0x08, + 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, + 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x19, 0x0a, 0x08, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x5f, 0x69, 0x64, 0x18, 0x0f, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x63, 0x68, 0x61, 0x69, 0x6e, + 0x49, 0x64, 0x22, 0xae, 0x04, 0x0a, 0x11, 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, + 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, 0x32, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, + 0x65, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, + 0x61, 0x74, 0x65, 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x14, 0x0a, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, + 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x64, 0x65, 0x70, 0x74, 0x68, 0x12, 0x0e, 0x0a, + 0x02, 0x70, 0x63, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, 0x02, 0x70, 0x63, 0x12, 0x10, 0x0a, + 0x03, 0x67, 0x61, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, 0x12, + 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x63, 0x6f, 0x73, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, + 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x43, 0x6f, 0x73, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x67, 0x61, + 0x73, 0x5f, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x18, 0x06, 0x20, 0x01, 0x28, 0x04, 0x52, 0x09, + 0x67, 0x61, 0x73, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x12, 0x0e, 0x0a, 0x02, 0x6f, 0x70, 0x18, + 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x02, 0x6f, 0x70, 0x12, 0x14, 0x0a, 0x05, 0x73, 0x74, 0x61, + 0x63, 0x6b, 0x18, 0x08, 0x20, 0x03, 0x28, 0x09, 0x52, 0x05, 0x73, 0x74, 0x61, 0x63, 0x6b, 0x12, + 0x16, 0x0a, 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0c, 0x52, + 0x06, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x12, 0x1f, 0x0a, 0x0b, 0x6d, 0x65, 0x6d, 0x6f, 0x72, + 0x79, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0a, 0x6d, 0x65, + 0x6d, 0x6f, 0x72, 0x79, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x23, 0x0a, 0x0d, 0x6d, 0x65, 0x6d, 0x6f, + 0x72, 0x79, 0x5f, 0x6f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x0c, 0x6d, 0x65, 0x6d, 0x6f, 0x72, 0x79, 0x4f, 0x66, 0x66, 0x73, 0x65, 0x74, 0x12, 0x1f, 0x0a, + 0x0b, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x0c, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x0a, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x44, 0x61, 0x74, 0x61, 0x12, 0x33, + 0x0a, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x18, 0x0d, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x17, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x43, + 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, 0x56, 0x32, 0x52, 0x08, 0x63, 0x6f, 0x6e, 0x74, 0x72, + 0x61, 0x63, 0x74, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0e, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x12, 0x45, 0x0a, 0x07, 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x18, 0x0f, 0x20, 0x03, 0x28, + 0x0b, 0x32, 0x2b, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, + 0x54, 0x72, 0x61, 0x6e, 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x53, 0x74, 0x65, 0x70, 0x56, + 0x32, 0x2e, 0x53, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, + 0x73, 0x74, 0x6f, 0x72, 0x61, 0x67, 0x65, 0x1a, 0x3a, 0x0a, 0x0c, 0x53, 0x74, 0x6f, 0x72, 0x61, + 0x67, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, + 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, + 0x02, 0x38, 0x01, 0x22, 0x8e, 0x01, 0x0a, 0x0a, 0x43, 0x6f, 0x6e, 0x74, 0x72, 0x61, 0x63, 0x74, + 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, + 0x63, 0x61, 0x6c, 0x6c, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x06, 0x63, 0x61, + 0x6c, 0x6c, 0x65, 0x72, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x03, 0x20, + 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x10, + 0x0a, 0x03, 0x67, 0x61, 0x73, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, 0x03, 0x67, 0x61, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, + 0x74, 0x79, 0x70, 0x65, 0x22, 0xe9, 0x03, 0x0a, 0x16, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, + 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, 0x12, + 0x1f, 0x0a, 0x0b, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0a, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x73, 0x68, + 0x12, 0x1a, 0x0a, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x08, 0x63, 0x6f, 0x69, 0x6e, 0x62, 0x61, 0x73, 0x65, 0x12, 0x1b, 0x0a, 0x09, + 0x67, 0x61, 0x73, 0x5f, 0x6c, 0x69, 0x6d, 0x69, 0x74, 0x18, 0x03, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x08, 0x67, 0x61, 0x73, 0x4c, 0x69, 0x6d, 0x69, 0x74, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, + 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x1c, 0x0a, 0x09, + 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x04, 0x52, + 0x09, 0x74, 0x69, 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x12, 0x10, 0x0a, 0x03, 0x67, 0x65, + 0x72, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x03, 0x67, 0x65, 0x72, 0x12, 0x22, 0x0a, 0x0d, + 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x31, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x31, + 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x08, 0x20, 0x01, + 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x26, 0x0a, 0x0f, 0x62, + 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x69, 0x6e, 0x66, 0x6f, 0x5f, 0x72, 0x6f, 0x6f, 0x74, 0x18, 0x09, + 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0d, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x49, 0x6e, 0x66, 0x6f, 0x52, + 0x6f, 0x6f, 0x74, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, + 0x73, 0x68, 0x12, 0x47, 0x0a, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x18, + 0x0b, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, + 0x2e, 0x76, 0x31, 0x2e, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x6e, 0x73, + 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, 0x32, + 0x52, 0x09, 0x72, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x73, 0x12, 0x26, 0x0a, 0x04, 0x6c, + 0x6f, 0x67, 0x73, 0x18, 0x0c, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x6f, 0x67, 0x56, 0x32, 0x52, 0x04, 0x6c, - 0x6f, 0x67, 0x73, 0x12, 0x37, 0x0a, 0x0a, 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, - 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x18, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, - 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, - 0x32, 0x52, 0x09, 0x66, 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, - 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, - 0x69, 0x63, 0x65, 0x18, 0x11, 0x20, 0x01, 0x28, 0x09, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, - 0x74, 0x69, 0x76, 0x65, 0x47, 0x61, 0x73, 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x14, - 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, - 0x74, 0x61, 0x67, 0x65, 0x18, 0x12, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x13, 0x65, 0x66, 0x66, 0x65, - 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, - 0x2e, 0x0a, 0x13, 0x68, 0x61, 0x73, 0x5f, 0x67, 0x61, 0x73, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, - 0x6f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x68, 0x61, - 0x73, 0x47, 0x61, 0x73, 0x70, 0x72, 0x69, 0x63, 0x65, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x12, - 0x2c, 0x0a, 0x12, 0x68, 0x61, 0x73, 0x5f, 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6f, - 0x70, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x14, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x68, 0x61, 0x73, - 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, - 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x15, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, - 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xf7, 0x01, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x56, 0x32, 0x12, - 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, - 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x70, - 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, - 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, - 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, - 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, - 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, - 0x68, 0x12, 0x1c, 0x0a, 0x0a, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x32, 0x18, - 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x32, 0x12, - 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, - 0x0d, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, 0x64, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, - 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, - 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, - 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2a, - 0xbd, 0x0a, 0x0a, 0x08, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x15, - 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x16, 0x0a, 0x12, 0x52, 0x4f, 0x4d, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, - 0x18, 0x0a, 0x14, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, - 0x5f, 0x4f, 0x46, 0x5f, 0x47, 0x41, 0x53, 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x4d, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x4f, 0x56, 0x45, - 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x03, 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x4d, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x52, - 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x04, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x4d, 0x41, 0x58, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x49, 0x5a, - 0x45, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, 0x44, 0x45, 0x44, 0x10, 0x05, 0x12, 0x28, 0x0a, 0x24, - 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, - 0x43, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x49, - 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, - 0x56, 0x45, 0x52, 0x54, 0x45, 0x44, 0x10, 0x07, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x4f, 0x4d, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, - 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x10, 0x08, 0x12, 0x24, 0x0a, 0x20, - 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, - 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, - 0x10, 0x09, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, - 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x0a, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, - 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4d, 0x45, 0x4d, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x52, + 0x6f, 0x67, 0x73, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0d, 0x20, 0x01, + 0x28, 0x0e, 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x52, 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, + 0x22, 0x9b, 0x06, 0x0a, 0x1c, 0x50, 0x72, 0x6f, 0x63, 0x65, 0x73, 0x73, 0x54, 0x72, 0x61, 0x6e, + 0x73, 0x61, 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x56, + 0x32, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x0a, 0x74, 0x78, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x32, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, + 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x32, 0x12, 0x15, 0x0a, 0x06, 0x72, 0x6c, 0x70, 0x5f, + 0x74, 0x78, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x05, 0x72, 0x6c, 0x70, 0x54, 0x78, 0x12, + 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x04, 0x20, + 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, 0x73, 0x68, 0x12, 0x21, + 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x05, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x12, 0x0a, 0x04, 0x74, 0x79, 0x70, 0x65, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0d, 0x52, + 0x04, 0x74, 0x79, 0x70, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x72, 0x65, 0x74, 0x75, 0x72, 0x6e, 0x5f, + 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x0b, 0x72, 0x65, 0x74, + 0x75, 0x72, 0x6e, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, + 0x6c, 0x65, 0x66, 0x74, 0x18, 0x08, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x4c, + 0x65, 0x66, 0x74, 0x12, 0x19, 0x0a, 0x08, 0x67, 0x61, 0x73, 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, + 0x09, 0x20, 0x01, 0x28, 0x04, 0x52, 0x07, 0x67, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x2e, + 0x0a, 0x13, 0x63, 0x75, 0x6d, 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x5f, 0x67, 0x61, 0x73, + 0x5f, 0x75, 0x73, 0x65, 0x64, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x04, 0x52, 0x11, 0x63, 0x75, 0x6d, + 0x75, 0x6c, 0x61, 0x74, 0x69, 0x76, 0x65, 0x47, 0x61, 0x73, 0x55, 0x73, 0x65, 0x64, 0x12, 0x21, + 0x0a, 0x0c, 0x67, 0x61, 0x73, 0x5f, 0x72, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x65, 0x64, 0x18, 0x0b, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x67, 0x61, 0x73, 0x52, 0x65, 0x66, 0x75, 0x6e, 0x64, 0x65, + 0x64, 0x12, 0x2b, 0x0a, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x18, 0x0c, 0x20, 0x01, 0x28, 0x0e, + 0x32, 0x15, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x52, + 0x6f, 0x6d, 0x45, 0x72, 0x72, 0x6f, 0x72, 0x52, 0x05, 0x65, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x25, + 0x0a, 0x0e, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x5f, 0x61, 0x64, 0x64, 0x72, 0x65, 0x73, 0x73, + 0x18, 0x0d, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x63, 0x72, 0x65, 0x61, 0x74, 0x65, 0x41, 0x64, + 0x64, 0x72, 0x65, 0x73, 0x73, 0x12, 0x1d, 0x0a, 0x0a, 0x73, 0x74, 0x61, 0x74, 0x65, 0x5f, 0x72, + 0x6f, 0x6f, 0x74, 0x18, 0x0e, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x73, 0x74, 0x61, 0x74, 0x65, + 0x52, 0x6f, 0x6f, 0x74, 0x12, 0x26, 0x0a, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x18, 0x0f, 0x20, 0x03, + 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, + 0x2e, 0x4c, 0x6f, 0x67, 0x56, 0x32, 0x52, 0x04, 0x6c, 0x6f, 0x67, 0x73, 0x12, 0x37, 0x0a, 0x0a, + 0x66, 0x75, 0x6c, 0x6c, 0x5f, 0x74, 0x72, 0x61, 0x63, 0x65, 0x18, 0x10, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x18, 0x2e, 0x65, 0x78, 0x65, 0x63, 0x75, 0x74, 0x6f, 0x72, 0x2e, 0x76, 0x31, 0x2e, 0x46, + 0x75, 0x6c, 0x6c, 0x54, 0x72, 0x61, 0x63, 0x65, 0x56, 0x32, 0x52, 0x09, 0x66, 0x75, 0x6c, 0x6c, + 0x54, 0x72, 0x61, 0x63, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x67, 0x61, 0x73, 0x5f, 0x70, 0x72, 0x69, 0x63, 0x65, 0x18, 0x11, 0x20, 0x01, + 0x28, 0x09, 0x52, 0x11, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x47, 0x61, 0x73, + 0x50, 0x72, 0x69, 0x63, 0x65, 0x12, 0x31, 0x0a, 0x14, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, + 0x76, 0x65, 0x5f, 0x70, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x18, 0x12, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x13, 0x65, 0x66, 0x66, 0x65, 0x63, 0x74, 0x69, 0x76, 0x65, 0x50, 0x65, + 0x72, 0x63, 0x65, 0x6e, 0x74, 0x61, 0x67, 0x65, 0x12, 0x2e, 0x0a, 0x13, 0x68, 0x61, 0x73, 0x5f, + 0x67, 0x61, 0x73, 0x70, 0x72, 0x69, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x18, + 0x13, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x11, 0x68, 0x61, 0x73, 0x47, 0x61, 0x73, 0x70, 0x72, 0x69, + 0x63, 0x65, 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x2c, 0x0a, 0x12, 0x68, 0x61, 0x73, 0x5f, + 0x62, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, 0x5f, 0x6f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x14, + 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x68, 0x61, 0x73, 0x42, 0x61, 0x6c, 0x61, 0x6e, 0x63, 0x65, + 0x4f, 0x70, 0x63, 0x6f, 0x64, 0x65, 0x12, 0x16, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x15, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x22, 0xf7, + 0x01, 0x0a, 0x05, 0x4c, 0x6f, 0x67, 0x56, 0x32, 0x12, 0x18, 0x0a, 0x07, 0x61, 0x64, 0x64, 0x72, + 0x65, 0x73, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x61, 0x64, 0x64, 0x72, 0x65, + 0x73, 0x73, 0x12, 0x16, 0x0a, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x18, 0x02, 0x20, 0x03, + 0x28, 0x0c, 0x52, 0x06, 0x74, 0x6f, 0x70, 0x69, 0x63, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x64, 0x61, + 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x04, 0x64, 0x61, 0x74, 0x61, 0x12, 0x21, + 0x0a, 0x0c, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x04, + 0x20, 0x01, 0x28, 0x04, 0x52, 0x0b, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x4e, 0x75, 0x6d, 0x62, 0x65, + 0x72, 0x12, 0x17, 0x0a, 0x07, 0x74, 0x78, 0x5f, 0x68, 0x61, 0x73, 0x68, 0x18, 0x05, 0x20, 0x01, + 0x28, 0x0c, 0x52, 0x06, 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x12, 0x1c, 0x0a, 0x0a, 0x74, 0x78, + 0x5f, 0x68, 0x61, 0x73, 0x68, 0x5f, 0x6c, 0x32, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x08, + 0x74, 0x78, 0x48, 0x61, 0x73, 0x68, 0x4c, 0x32, 0x12, 0x19, 0x0a, 0x08, 0x74, 0x78, 0x5f, 0x69, + 0x6e, 0x64, 0x65, 0x78, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x07, 0x74, 0x78, 0x49, 0x6e, + 0x64, 0x65, 0x78, 0x12, 0x1d, 0x0a, 0x0a, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x5f, 0x68, 0x61, 0x73, + 0x68, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x62, 0x6c, 0x6f, 0x63, 0x6b, 0x48, 0x61, + 0x73, 0x68, 0x12, 0x14, 0x0a, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x18, 0x09, 0x20, 0x01, 0x28, + 0x0d, 0x52, 0x05, 0x69, 0x6e, 0x64, 0x65, 0x78, 0x2a, 0xbd, 0x0a, 0x0a, 0x08, 0x52, 0x6f, 0x6d, + 0x45, 0x72, 0x72, 0x6f, 0x72, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, + 0x12, 0x16, 0x0a, 0x12, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x18, 0x0a, 0x14, 0x52, 0x4f, 0x4d, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x47, 0x41, 0x53, + 0x10, 0x02, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x54, 0x41, 0x43, 0x4b, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x03, + 0x12, 0x1d, 0x0a, 0x19, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, + 0x41, 0x43, 0x4b, 0x5f, 0x55, 0x4e, 0x44, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x04, 0x12, + 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4d, 0x41, 0x58, + 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x45, 0x58, 0x43, 0x45, 0x45, + 0x44, 0x45, 0x44, 0x10, 0x05, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, + 0x45, 0x53, 0x53, 0x5f, 0x43, 0x4f, 0x4c, 0x4c, 0x49, 0x53, 0x49, 0x4f, 0x4e, 0x10, 0x06, 0x12, + 0x20, 0x0a, 0x1c, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x52, 0x45, 0x56, 0x45, 0x52, 0x54, 0x45, 0x44, 0x10, + 0x07, 0x12, 0x22, 0x0a, 0x1e, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, + 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x53, + 0x54, 0x45, 0x50, 0x10, 0x08, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, + 0x52, 0x53, 0x5f, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x10, 0x09, 0x12, 0x24, 0x0a, 0x20, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, - 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x10, 0x0c, - 0x12, 0x25, 0x0a, 0x21, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, - 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x50, 0x41, - 0x44, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x0d, 0x12, 0x26, 0x0a, 0x22, 0x52, 0x4f, 0x4d, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, - 0x54, 0x45, 0x52, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x45, 0x49, 0x44, 0x4f, 0x4e, 0x10, 0x0e, 0x12, - 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, - 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x53, 0x48, 0x41, - 0x10, 0x0f, 0x12, 0x1a, 0x0a, 0x16, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4a, 0x55, 0x4d, 0x50, 0x10, 0x10, 0x12, 0x1c, - 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x5f, 0x4f, 0x50, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x11, 0x12, 0x1c, 0x0a, 0x18, - 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, - 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, 0x43, 0x10, 0x12, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, - 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, - 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x53, 0x5f, - 0x45, 0x46, 0x10, 0x13, 0x12, 0x29, 0x0a, 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x49, 0x47, 0x4e, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0x14, 0x12, - 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, - 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, - 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x10, 0x15, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x4f, 0x4d, + 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, + 0x0a, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, + 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4d, + 0x45, 0x4d, 0x10, 0x0b, 0x12, 0x23, 0x0a, 0x1f, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, + 0x53, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x10, 0x0c, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x4f, 0x4d, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, + 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x0d, + 0x12, 0x26, 0x0a, 0x22, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, + 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x50, 0x4f, + 0x53, 0x45, 0x49, 0x44, 0x4f, 0x4e, 0x10, 0x0e, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x53, 0x48, 0x41, 0x10, 0x0f, 0x12, 0x1a, 0x0a, 0x16, 0x52, + 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x5f, 0x4a, 0x55, 0x4d, 0x50, 0x10, 0x10, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4f, 0x50, 0x43, + 0x4f, 0x44, 0x45, 0x10, 0x11, 0x12, 0x1c, 0x0a, 0x18, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x49, + 0x43, 0x10, 0x12, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, + 0x45, 0x5f, 0x53, 0x54, 0x41, 0x52, 0x54, 0x53, 0x5f, 0x45, 0x46, 0x10, 0x13, 0x12, 0x29, 0x0a, + 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, + 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x49, 0x47, + 0x4e, 0x41, 0x54, 0x55, 0x52, 0x45, 0x10, 0x14, 0x12, 0x28, 0x0a, 0x24, 0x52, 0x4f, 0x4d, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, + 0x10, 0x15, 0x12, 0x25, 0x0a, 0x21, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x4e, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x16, 0x12, 0x29, 0x0a, 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, - 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x4e, 0x43, 0x45, 0x10, 0x16, - 0x12, 0x29, 0x0a, 0x25, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, - 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, - 0x47, 0x41, 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x17, 0x12, 0x27, 0x0a, 0x23, 0x52, - 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, - 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, - 0x43, 0x45, 0x10, 0x18, 0x12, 0x2f, 0x0a, 0x2b, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4c, 0x49, 0x4d, + 0x49, 0x54, 0x10, 0x17, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4c, 0x49, - 0x4d, 0x49, 0x54, 0x10, 0x19, 0x12, 0x2b, 0x0a, 0x27, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, - 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x45, 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, - 0x10, 0x1a, 0x12, 0x27, 0x0a, 0x23, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x54, 0x58, 0x5f, 0x47, 0x41, 0x53, - 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x10, 0x1b, 0x12, 0x20, 0x0a, 0x1c, 0x52, - 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x44, - 0x41, 0x54, 0x41, 0x5f, 0x54, 0x4f, 0x4f, 0x5f, 0x42, 0x49, 0x47, 0x10, 0x1c, 0x12, 0x21, 0x0a, - 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x55, 0x50, - 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x4b, 0x5f, 0x49, 0x44, 0x10, 0x1d, - 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, 0x4c, 0x50, 0x10, 0x1e, 0x12, 0x2c, 0x0a, 0x28, 0x52, - 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, - 0x5f, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4c, - 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x1f, 0x12, 0x32, 0x0a, 0x2e, 0x52, 0x4f, 0x4d, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, - 0x4f, 0x54, 0x5f, 0x46, 0x49, 0x52, 0x53, 0x54, 0x5f, 0x54, 0x58, 0x5f, 0x43, 0x48, 0x41, 0x4e, - 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x20, 0x12, 0x38, 0x0a, - 0x34, 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, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, - 0x53, 0x54, 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, - 0xb9, 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, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x1b, - 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x44, 0x42, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x02, 0x12, 0x32, 0x0a, 0x2e, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, - 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x54, 0x45, 0x50, 0x53, 0x10, 0x03, 0x12, - 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, - 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x4b, 0x45, 0x43, 0x43, - 0x41, 0x4b, 0x10, 0x04, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x18, 0x12, 0x2f, 0x0a, + 0x2b, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, + 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x54, + 0x43, 0x48, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4c, 0x49, 0x4d, 0x49, 0x54, 0x10, 0x19, 0x12, 0x2b, + 0x0a, 0x27, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, + 0x49, 0x4e, 0x53, 0x49, 0x43, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x53, 0x45, + 0x4e, 0x44, 0x45, 0x52, 0x5f, 0x43, 0x4f, 0x44, 0x45, 0x10, 0x1a, 0x12, 0x27, 0x0a, 0x23, 0x52, + 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x54, 0x52, 0x49, 0x4e, 0x53, + 0x49, 0x43, 0x5f, 0x54, 0x58, 0x5f, 0x47, 0x41, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, + 0x4f, 0x57, 0x10, 0x1b, 0x12, 0x20, 0x0a, 0x1c, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x54, 0x4f, 0x4f, + 0x5f, 0x42, 0x49, 0x47, 0x10, 0x1c, 0x12, 0x21, 0x0a, 0x1d, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x55, 0x4e, 0x53, 0x55, 0x50, 0x50, 0x4f, 0x52, 0x54, 0x45, 0x44, 0x5f, + 0x46, 0x4f, 0x52, 0x4b, 0x5f, 0x49, 0x44, 0x10, 0x1d, 0x12, 0x19, 0x0a, 0x15, 0x52, 0x4f, 0x4d, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x52, + 0x4c, 0x50, 0x10, 0x1e, 0x12, 0x2c, 0x0a, 0x28, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x45, 0x43, 0x4f, 0x44, 0x45, + 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, + 0x10, 0x1f, 0x12, 0x32, 0x0a, 0x2e, 0x52, 0x4f, 0x4d, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x49, 0x52, 0x53, + 0x54, 0x5f, 0x54, 0x58, 0x5f, 0x43, 0x48, 0x41, 0x4e, 0x47, 0x45, 0x5f, 0x4c, 0x32, 0x5f, 0x42, + 0x4c, 0x4f, 0x43, 0x4b, 0x10, 0x20, 0x12, 0x38, 0x0a, 0x34, 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, 0x4c, + 0x49, 0x4d, 0x49, 0x54, 0x5f, 0x54, 0x49, 0x4d, 0x45, 0x53, 0x54, 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, 0xb9, 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, 0x1b, 0x0a, 0x17, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x4e, 0x4f, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x01, 0x12, 0x1b, 0x0a, 0x17, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x44, 0x42, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x10, 0x02, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, - 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x10, 0x05, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, - 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x4d, 0x45, 0x4d, 0x10, 0x06, 0x12, 0x32, 0x0a, 0x2e, 0x45, + 0x5f, 0x53, 0x54, 0x45, 0x50, 0x53, 0x10, 0x03, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, + 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x4b, 0x45, 0x43, 0x43, 0x41, 0x4b, 0x10, 0x04, 0x12, 0x33, 0x0a, + 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, + 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, + 0x10, 0x05, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, + 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x4d, + 0x45, 0x4d, 0x10, 0x06, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, + 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, + 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x10, 0x07, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, + 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x10, 0x08, 0x12, 0x35, + 0x0a, 0x31, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, + 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x50, 0x4f, 0x53, 0x45, 0x49, + 0x44, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x26, 0x0a, 0x22, 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, 0x46, 0x4f, 0x52, 0x4b, 0x5f, 0x49, 0x44, 0x10, 0x0a, 0x12, 0x23, 0x0a, + 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, + 0x10, 0x0b, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x46, 0x45, 0x41, 0x32, 0x53, 0x43, 0x41, 0x4c, 0x41, 0x52, 0x10, + 0x0c, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x54, 0x4f, 0x53, 0x33, 0x32, 0x10, 0x0d, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, - 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x10, 0x07, 0x12, - 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, - 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x50, 0x41, 0x44, 0x44, - 0x49, 0x4e, 0x47, 0x10, 0x08, 0x12, 0x35, 0x0a, 0x31, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, - 0x57, 0x5f, 0x50, 0x4f, 0x53, 0x45, 0x49, 0x44, 0x4f, 0x4e, 0x10, 0x09, 0x12, 0x26, 0x0a, 0x22, - 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, 0x46, 0x4f, 0x52, 0x4b, 0x5f, - 0x49, 0x44, 0x10, 0x0a, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x5f, 0x4d, - 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x0b, 0x12, 0x1d, 0x0a, 0x19, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x46, 0x45, 0x41, 0x32, - 0x53, 0x43, 0x41, 0x4c, 0x41, 0x52, 0x10, 0x0c, 0x12, 0x18, 0x0a, 0x14, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x54, 0x4f, 0x53, 0x33, 0x32, - 0x10, 0x0d, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x4e, 0x56, - 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x55, 0x4e, 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x5f, 0x54, 0x58, - 0x10, 0x0e, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x4e, 0x56, - 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, - 0x10, 0x0f, 0x12, 0x39, 0x0a, 0x35, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, - 0x54, 0x48, 0x5f, 0x45, 0x43, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x49, 0x56, - 0x49, 0x44, 0x45, 0x5f, 0x42, 0x59, 0x5f, 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x10, 0x12, 0x2f, 0x0a, - 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, - 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x11, 0x12, 0x2b, - 0x0a, 0x27, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, - 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x12, 0x12, 0x2e, 0x0a, 0x2a, 0x45, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x55, 0x4e, + 0x53, 0x49, 0x47, 0x4e, 0x45, 0x44, 0x5f, 0x54, 0x58, 0x10, 0x0e, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x13, 0x12, 0x20, 0x0a, 0x1c, 0x45, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x4f, + 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x10, 0x0f, 0x12, 0x39, 0x0a, 0x35, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x10, 0x14, 0x12, 0x32, 0x0a, - 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x53, 0x49, - 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, - 0x15, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, - 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, - 0x49, 0x56, 0x45, 0x10, 0x16, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, - 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, - 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x17, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, - 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, - 0x18, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, - 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, - 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x19, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x45, 0x43, 0x52, 0x45, + 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x44, 0x49, 0x56, 0x49, 0x44, 0x45, 0x5f, 0x42, 0x59, 0x5f, + 0x5a, 0x45, 0x52, 0x4f, 0x10, 0x10, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, + 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, + 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x11, 0x12, 0x2b, 0x0a, 0x27, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x10, 0x1a, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, - 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x1b, 0x12, 0x32, 0x0a, - 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, 0x4f, - 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, - 0x1c, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, - 0x50, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, - 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, - 0x45, 0x10, 0x1d, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, - 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, - 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x1e, 0x12, 0x34, 0x0a, - 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, - 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, - 0x44, 0x10, 0x1f, 0x12, 0x37, 0x0a, 0x33, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, - 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x4f, 0x55, - 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x20, 0x12, 0x2a, 0x0a, 0x26, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x50, 0x4c, 0x45, 0x5f, - 0x46, 0x52, 0x45, 0x45, 0x49, 0x4e, 0x10, 0x21, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, - 0x49, 0x4e, 0x5f, 0x41, 0x53, 0x53, 0x45, 0x52, 0x54, 0x10, 0x22, 0x12, 0x21, 0x0a, 0x1d, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x10, 0x23, 0x12, 0x30, - 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, - 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x24, - 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, - 0x47, 0x45, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x25, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, - 0x53, 0x48, 0x4b, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, - 0x43, 0x48, 0x10, 0x26, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x4e, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, + 0x56, 0x45, 0x10, 0x12, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x53, + 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4b, + 0x45, 0x59, 0x10, 0x13, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, - 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, - 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x27, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, - 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x28, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, - 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, - 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, - 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x29, 0x12, 0x30, 0x0a, 0x2c, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x4c, 0x45, 0x4e, 0x5f, - 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x2a, 0x12, 0x30, - 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, - 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x2b, - 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, - 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, - 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x2c, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, - 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, - 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x2d, 0x12, 0x2f, 0x0a, - 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x56, 0x41, - 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x2e, 0x12, 0x31, - 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, - 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, - 0x2f, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, - 0x50, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, - 0x30, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, - 0x50, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, - 0x41, 0x54, 0x43, 0x48, 0x10, 0x31, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x41, 0x53, 0x48, 0x4b, 0x10, 0x14, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x4c, 0x45, 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, - 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x32, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, - 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, - 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x33, - 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, + 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x15, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x16, 0x12, 0x40, + 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, + 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, + 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x17, + 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, + 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, + 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x18, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, + 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x19, + 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, - 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, - 0x49, 0x43, 0x45, 0x10, 0x34, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x10, 0x1a, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, + 0x48, 0x50, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, + 0x41, 0x4e, 0x47, 0x45, 0x10, 0x1b, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, + 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x1c, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, + 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, + 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x1d, 0x12, 0x38, 0x0a, 0x34, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, + 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, + 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x1e, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, + 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x1f, 0x12, 0x37, 0x0a, 0x33, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, + 0x4f, 0x46, 0x46, 0x53, 0x45, 0x54, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, + 0x4e, 0x47, 0x45, 0x10, 0x20, 0x12, 0x2a, 0x0a, 0x26, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x35, + 0x4d, 0x55, 0x4c, 0x54, 0x49, 0x50, 0x4c, 0x45, 0x5f, 0x46, 0x52, 0x45, 0x45, 0x49, 0x4e, 0x10, + 0x21, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x53, 0x53, 0x45, + 0x52, 0x54, 0x10, 0x22, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, + 0x45, 0x4d, 0x4f, 0x52, 0x59, 0x10, 0x23, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, + 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x24, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, + 0x41, 0x49, 0x4e, 0x5f, 0x53, 0x54, 0x4f, 0x52, 0x41, 0x47, 0x45, 0x5f, 0x57, 0x52, 0x49, 0x54, + 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x25, 0x12, 0x2f, 0x0a, 0x2b, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x56, 0x41, 0x4c, + 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x26, 0x12, 0x31, 0x0a, + 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x50, 0x41, + 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x27, + 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, + 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x28, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, - 0x5f, 0x45, 0x43, 0x52, 0x45, 0x43, 0x4f, 0x56, 0x45, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, - 0x54, 0x43, 0x48, 0x10, 0x36, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x41, 0x44, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, - 0x54, 0x43, 0x48, 0x10, 0x37, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x53, 0x55, 0x42, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, - 0x54, 0x43, 0x48, 0x10, 0x38, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, + 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, + 0x54, 0x43, 0x48, 0x10, 0x29, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4c, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, - 0x43, 0x48, 0x10, 0x39, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, - 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x53, 0x4c, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, - 0x43, 0x48, 0x10, 0x3a, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, - 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x45, 0x51, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x3b, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, - 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x41, 0x4e, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, - 0x48, 0x10, 0x3c, 0x12, 0x2d, 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, - 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4f, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, - 0x10, 0x3d, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, - 0x41, 0x52, 0x59, 0x5f, 0x58, 0x4f, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, - 0x10, 0x3e, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, - 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, - 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, - 0x41, 0x54, 0x43, 0x48, 0x10, 0x3f, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x48, 0x41, 0x53, 0x48, 0x4b, 0x4c, 0x45, 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, + 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x2a, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, + 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, + 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x2b, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, + 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, + 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, + 0x2c, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, + 0x4b, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, + 0x57, 0x49, 0x43, 0x45, 0x10, 0x2d, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x38, - 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x40, 0x12, 0x31, 0x0a, 0x2d, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x52, - 0x45, 0x41, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x41, 0x12, 0x2c, - 0x0a, 0x28, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4a, 0x4d, 0x50, 0x4e, 0x5f, 0x4f, 0x55, - 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x42, 0x12, 0x32, 0x0a, 0x2e, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, - 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x52, 0x45, 0x41, - 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x43, - 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, - 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, - 0x47, 0x45, 0x10, 0x44, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4f, - 0x4c, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x45, 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, 0x4f, 0x4c, 0x44, 0x5f, 0x41, 0x43, - 0x43, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x46, 0x12, 0x23, - 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, - 0x44, 0x10, 0x47, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, - 0x54, 0x43, 0x48, 0x5f, 0x4c, 0x32, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x10, 0x48, 0x12, 0x2b, 0x0a, - 0x27, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, - 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x45, - 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x49, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, - 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x49, 0x4e, 0x42, 0x41, 0x53, 0x45, 0x10, 0x4a, 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, 0x46, 0x52, 0x4f, 0x4d, 0x10, 0x4b, - 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x4b, 0x45, - 0x59, 0x10, 0x4c, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x42, - 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x4d, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, - 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, - 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, 0x53, 0x5f, 0x42, 0x59, 0x54, - 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x4e, 0x12, 0x33, 0x0a, 0x2f, 0x45, - 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, - 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, 0x53, 0x5f, - 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x4f, - 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, 0x47, 0x45, 0x54, 0x5f, 0x4b, - 0x45, 0x59, 0x10, 0x50, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, - 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, - 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, - 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, 0x10, 0x51, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x2e, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, + 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, + 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x2f, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, + 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x30, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, + 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, + 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, + 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x31, 0x12, + 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x4c, + 0x45, 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, + 0x32, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, + 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x33, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, + 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, + 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x34, 0x12, 0x29, + 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x4d, + 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x35, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x10, 0x52, 0x12, 0x32, 0x0a, 0x2e, 0x45, + 0x41, 0x49, 0x4e, 0x5f, 0x41, 0x52, 0x49, 0x54, 0x48, 0x5f, 0x45, 0x43, 0x52, 0x45, 0x43, 0x4f, + 0x56, 0x45, 0x52, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x36, 0x12, 0x2e, + 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, + 0x41, 0x44, 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x37, 0x12, 0x2e, + 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, + 0x53, 0x55, 0x42, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x38, 0x12, 0x2d, + 0x0a, 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, + 0x4c, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x39, 0x12, 0x2e, 0x0a, + 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x53, + 0x4c, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3a, 0x12, 0x2d, 0x0a, + 0x29, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x45, + 0x51, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3b, 0x12, 0x2e, 0x0a, 0x2a, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x41, 0x4e, + 0x44, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3c, 0x12, 0x2d, 0x0a, 0x29, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4f, 0x52, + 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3d, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, - 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, - 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x53, 0x12, - 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, - 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, - 0x45, 0x10, 0x54, 0x12, 0x40, 0x0a, 0x3c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, - 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, - 0x53, 0x48, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, - 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, - 0x4e, 0x47, 0x45, 0x10, 0x55, 0x12, 0x38, 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, - 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x56, 0x12, - 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, - 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, - 0x54, 0x45, 0x44, 0x10, 0x57, 0x12, 0x2f, 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x58, 0x4f, 0x52, + 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3e, 0x12, 0x32, 0x0a, 0x2e, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x57, + 0x52, 0x49, 0x54, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x3f, 0x12, + 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, 0x45, 0x4d, 0x41, 0x4c, 0x49, + 0x47, 0x4e, 0x5f, 0x57, 0x52, 0x49, 0x54, 0x45, 0x38, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, + 0x43, 0x48, 0x10, 0x40, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x4d, + 0x45, 0x4d, 0x41, 0x4c, 0x49, 0x47, 0x4e, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4d, 0x49, 0x53, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x41, 0x12, 0x2c, 0x0a, 0x28, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, + 0x4e, 0x5f, 0x4a, 0x4d, 0x50, 0x4e, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, + 0x4e, 0x47, 0x45, 0x10, 0x42, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, - 0x41, 0x54, 0x43, 0x48, 0x10, 0x58, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, - 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x59, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, - 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, - 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5a, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, + 0x48, 0x41, 0x53, 0x48, 0x4b, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, + 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x43, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, - 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, - 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5b, 0x12, 0x30, - 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, - 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x4c, 0x45, - 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x5c, - 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, - 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, - 0x10, 0x5d, 0x12, 0x36, 0x0a, 0x32, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x50, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, + 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x44, 0x12, 0x29, 0x0a, + 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4f, 0x4c, 0x44, 0x5f, 0x53, 0x54, 0x41, 0x54, + 0x45, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x45, 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, 0x4f, 0x4c, 0x44, 0x5f, 0x41, 0x43, 0x43, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, + 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x46, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, + 0x44, 0x5f, 0x43, 0x48, 0x41, 0x49, 0x4e, 0x5f, 0x49, 0x44, 0x10, 0x47, 0x12, 0x28, 0x0a, 0x24, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x42, 0x41, 0x54, 0x43, 0x48, 0x5f, 0x4c, 0x32, 0x5f, + 0x44, 0x41, 0x54, 0x41, 0x10, 0x48, 0x12, 0x2b, 0x0a, 0x27, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, + 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, + 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, + 0x54, 0x10, 0x49, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, + 0x49, 0x4e, 0x42, 0x41, 0x53, 0x45, 0x10, 0x4a, 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, 0x46, 0x52, 0x4f, 0x4d, 0x10, 0x4b, 0x12, 0x21, 0x0a, 0x1d, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, + 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x4c, 0x12, 0x23, 0x0a, 0x1f, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x42, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, + 0x4d, 0x12, 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, + 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, 0x4f, 0x4e, 0x54, + 0x52, 0x41, 0x43, 0x54, 0x53, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, 0x45, 0x5f, 0x4b, + 0x45, 0x59, 0x10, 0x4e, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x43, + 0x4f, 0x4e, 0x54, 0x52, 0x41, 0x43, 0x54, 0x53, 0x5f, 0x42, 0x59, 0x54, 0x45, 0x43, 0x4f, 0x44, + 0x45, 0x5f, 0x56, 0x41, 0x4c, 0x55, 0x45, 0x10, 0x4f, 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, 0x47, 0x45, 0x54, 0x5f, 0x4b, 0x45, 0x59, 0x10, 0x50, 0x12, 0x33, 0x0a, + 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, + 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x43, 0x4f, 0x55, 0x4e, 0x54, 0x45, 0x52, 0x53, + 0x5f, 0x4f, 0x56, 0x45, 0x52, 0x46, 0x4c, 0x4f, 0x57, 0x5f, 0x53, 0x48, 0x41, 0x32, 0x35, 0x36, + 0x10, 0x51, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, - 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, - 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5e, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, - 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, - 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, - 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x5f, 0x12, - 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x48, 0x53, 0x10, 0x52, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, + 0x41, 0x53, 0x48, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, + 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x53, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, + 0x4e, 0x5f, 0x4e, 0x45, 0x47, 0x41, 0x54, 0x49, 0x56, 0x45, 0x10, 0x54, 0x12, 0x40, 0x0a, 0x3c, + 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, + 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x50, 0x4f, 0x53, + 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x5f, 0x50, 0x4c, 0x55, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, + 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x55, 0x12, 0x38, + 0x0a, 0x34, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, + 0x47, 0x45, 0x53, 0x54, 0x5f, 0x41, 0x44, 0x44, 0x52, 0x45, 0x53, 0x53, 0x5f, 0x4e, 0x4f, 0x54, + 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x56, 0x12, 0x34, 0x0a, 0x30, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4e, + 0x4f, 0x54, 0x5f, 0x43, 0x4f, 0x4d, 0x50, 0x4c, 0x45, 0x54, 0x45, 0x44, 0x10, 0x57, 0x12, 0x2f, + 0x0a, 0x2b, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x56, + 0x41, 0x4c, 0x55, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x58, 0x12, + 0x31, 0x0a, 0x2d, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, - 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, - 0x45, 0x10, 0x60, 0x12, 0x27, 0x0a, 0x23, 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, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x61, 0x12, 0x2e, 0x0a, 0x2a, - 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, - 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x42, 0x4c, - 0x4f, 0x43, 0x4b, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x4c, 0x31, 0x10, 0x62, 0x12, 0x36, 0x0a, 0x32, + 0x50, 0x41, 0x44, 0x44, 0x49, 0x4e, 0x47, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, + 0x10, 0x59, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, + 0x48, 0x53, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, + 0x10, 0x5a, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, + 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, + 0x48, 0x53, 0x4c, 0x45, 0x4e, 0x5f, 0x4c, 0x45, 0x4e, 0x47, 0x54, 0x48, 0x5f, 0x4d, 0x49, 0x53, + 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x5b, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, 0x43, 0x55, + 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, + 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x4c, 0x45, 0x4e, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, + 0x44, 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x5c, 0x12, 0x30, 0x0a, 0x2c, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, + 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, + 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x5d, 0x12, 0x36, 0x0a, 0x32, 0x45, + 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, + 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, + 0x54, 0x5f, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, + 0x48, 0x10, 0x5e, 0x12, 0x33, 0x0a, 0x2f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, + 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x48, 0x41, + 0x53, 0x48, 0x53, 0x44, 0x49, 0x47, 0x45, 0x53, 0x54, 0x5f, 0x43, 0x41, 0x4c, 0x4c, 0x45, 0x44, + 0x5f, 0x54, 0x57, 0x49, 0x43, 0x45, 0x10, 0x5f, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, + 0x49, 0x4e, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x53, 0x5f, 0x52, 0x45, 0x41, 0x44, 0x5f, 0x4f, 0x55, + 0x54, 0x5f, 0x4f, 0x46, 0x5f, 0x52, 0x41, 0x4e, 0x47, 0x45, 0x10, 0x60, 0x12, 0x27, 0x0a, 0x23, 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, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x56, - 0x32, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, - 0x4f, 0x54, 0x10, 0x63, 0x12, 0x33, 0x0a, 0x2f, 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, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x56, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, - 0x48, 0x41, 0x53, 0x48, 0x5f, 0x4c, 0x31, 0x10, 0x64, 0x12, 0x27, 0x0a, 0x23, 0x45, 0x58, 0x45, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4c, 0x31, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x52, + 0x4f, 0x4f, 0x54, 0x10, 0x61, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, + 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, + 0x46, 0x4f, 0x52, 0x43, 0x45, 0x44, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x48, 0x41, 0x53, 0x48, + 0x5f, 0x4c, 0x31, 0x10, 0x62, 0x12, 0x36, 0x0a, 0x32, 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, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x56, 0x32, 0x5f, 0x47, 0x4c, 0x4f, 0x42, 0x41, + 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x63, 0x12, 0x33, 0x0a, + 0x2f, 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, 0x44, 0x41, 0x54, 0x41, 0x5f, + 0x56, 0x32, 0x5f, 0x42, 0x4c, 0x4f, 0x43, 0x4b, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x5f, 0x4c, 0x31, + 0x10, 0x64, 0x12, 0x27, 0x0a, 0x23, 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, + 0x53, 0x4d, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, 0x10, 0x65, 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, 0x42, 0x41, 0x4c, 0x41, 0x4e, 0x43, 0x45, 0x10, 0x66, 0x12, + 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, + 0x5f, 0x4c, 0x54, 0x34, 0x5f, 0x4d, 0x49, 0x53, 0x4d, 0x41, 0x54, 0x43, 0x48, 0x10, 0x67, 0x12, + 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, + 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x53, 0x54, + 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x68, 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, 0x4e, 0x45, 0x57, 0x5f, 0x41, 0x43, 0x43, 0x5f, 0x49, 0x4e, 0x50, + 0x55, 0x54, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x69, 0x12, 0x2e, 0x0a, 0x2a, 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, 0x53, 0x4d, 0x54, 0x5f, 0x50, 0x52, 0x4f, 0x4f, 0x46, - 0x10, 0x65, 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, 0x42, 0x41, 0x4c, - 0x41, 0x4e, 0x43, 0x45, 0x10, 0x66, 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, - 0x5f, 0x42, 0x49, 0x4e, 0x41, 0x52, 0x59, 0x5f, 0x4c, 0x54, 0x34, 0x5f, 0x4d, 0x49, 0x53, 0x4d, - 0x41, 0x54, 0x43, 0x48, 0x10, 0x67, 0x12, 0x29, 0x0a, 0x25, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, - 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, - 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, - 0x68, 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, 0x4e, 0x45, 0x57, 0x5f, - 0x41, 0x43, 0x43, 0x5f, 0x49, 0x4e, 0x50, 0x55, 0x54, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x10, 0x69, - 0x12, 0x2e, 0x0a, 0x2a, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x4c, - 0x4f, 0x43, 0x41, 0x4c, 0x5f, 0x45, 0x58, 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x6a, - 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, - 0x4f, 0x52, 0x5f, 0x44, 0x42, 0x5f, 0x4b, 0x45, 0x59, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, - 0x55, 0x4e, 0x44, 0x10, 0x6b, 0x12, 0x28, 0x0a, 0x24, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x54, 0x5f, 0x49, 0x4e, 0x56, 0x41, - 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x41, 0x54, 0x41, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x10, 0x6c, 0x12, - 0x24, 0x0a, 0x20, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, - 0x52, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x44, 0x42, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x45, 0x52, - 0x52, 0x4f, 0x52, 0x10, 0x6d, 0x12, 0x20, 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, - 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4d, 0x41, - 0x4e, 0x41, 0x47, 0x45, 0x52, 0x10, 0x6e, 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, 0x4c, 0x31, 0x5f, 0x49, 0x4e, 0x46, 0x4f, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x5f, 0x49, - 0x4e, 0x44, 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, 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, + 0x4c, 0x49, 0x44, 0x5f, 0x4e, 0x45, 0x57, 0x5f, 0x4c, 0x4f, 0x43, 0x41, 0x4c, 0x5f, 0x45, 0x58, + 0x49, 0x54, 0x5f, 0x52, 0x4f, 0x4f, 0x54, 0x10, 0x6a, 0x12, 0x23, 0x0a, 0x1f, 0x45, 0x58, 0x45, + 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x44, 0x42, 0x5f, 0x4b, + 0x45, 0x59, 0x5f, 0x4e, 0x4f, 0x54, 0x5f, 0x46, 0x4f, 0x55, 0x4e, 0x44, 0x10, 0x6b, 0x12, 0x28, + 0x0a, 0x24, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x4d, 0x54, 0x5f, 0x49, 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x44, 0x41, 0x54, + 0x41, 0x5f, 0x53, 0x49, 0x5a, 0x45, 0x10, 0x6c, 0x12, 0x24, 0x0a, 0x20, 0x45, 0x58, 0x45, 0x43, + 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x48, 0x41, 0x53, 0x48, 0x44, + 0x42, 0x5f, 0x47, 0x52, 0x50, 0x43, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x10, 0x6d, 0x12, 0x20, + 0x0a, 0x1c, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, + 0x5f, 0x53, 0x54, 0x41, 0x54, 0x45, 0x5f, 0x4d, 0x41, 0x4e, 0x41, 0x47, 0x45, 0x52, 0x10, 0x6e, + 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, 0x4c, 0x31, 0x5f, 0x49, 0x4e, + 0x46, 0x4f, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x5f, 0x49, 0x4e, 0x44, 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, 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, 0x55, 0x50, 0x44, 0x41, 0x54, 0x45, 0x5f, 0x4d, 0x45, - 0x52, 0x4b, 0x4c, 0x45, 0x5f, 0x54, 0x52, 0x45, 0x45, 0x10, 0x74, 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, + 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, 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, 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, + 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/trace.go b/state/trace.go index 8f6d660683..4dbf2ab0c2 100644 --- a/state/trace.go +++ b/state/trace.go @@ -242,7 +242,6 @@ func (s *State) DebugTransaction(ctx context.Context, transactionHash common.Has TimestampLimit: uint64(time.Now().Unix()), SkipFirstChangeL2Block: cFalse, SkipWriteBlockInfoRoot: cTrue, - ExecutionMode: executor.ExecutionMode0, } // gets the L1InfoTreeData for the transactions diff --git a/state/transaction.go b/state/transaction.go index 71ce4cd2e3..3af99b3f64 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -529,7 +529,6 @@ func (s *State) internalProcessUnsignedTransactionV2(ctx context.Context, tx *ty TimestampLimit: uint64(time.Now().Unix()), SkipFirstChangeL2Block: cFalse, SkipWriteBlockInfoRoot: cTrue, - ExecutionMode: executor.ExecutionMode0, } if noZKEVMCounters { processBatchRequestV2.NoCounters = cTrue @@ -1004,7 +1003,6 @@ func (s *State) internalTestGasEstimationTransactionV2(ctx context.Context, batc TimestampLimit: uint64(time.Now().Unix()), SkipFirstChangeL2Block: cTrue, SkipWriteBlockInfoRoot: cTrue, - ExecutionMode: executor.ExecutionMode0, } log.Debugf("EstimateGas[processBatchRequestV2.From]: %v", processBatchRequestV2.From) diff --git a/synchronizer/actions/etrog/processor_l1_sequence_batches.go b/synchronizer/actions/etrog/processor_l1_sequence_batches.go index ba91be9a13..132079d5bb 100644 --- a/synchronizer/actions/etrog/processor_l1_sequence_batches.go +++ b/synchronizer/actions/etrog/processor_l1_sequence_batches.go @@ -156,7 +156,6 @@ func (p *ProcessorL1SequenceBatchesEtrog) ProcessSequenceBatches(ctx context.Con BatchL2Data: &txs, ForcedBlockHashL1: forcedBlockHashL1, SkipVerifyL1InfoRoot: 1, - ExecutionMode: executor.ExecutionMode1, ClosingReason: state.SyncL1EventSequencedForcedBatchClosingReason, } } else if sbatch.PolygonRollupBaseEtrogBatchData.ForcedTimestamp > 0 && sbatch.BatchNumber == 1 { @@ -174,7 +173,6 @@ func (p *ProcessorL1SequenceBatchesEtrog) ProcessSequenceBatches(ctx context.Con BatchL2Data: &txs, ForcedBlockHashL1: forcedBlockHashL1, SkipVerifyL1InfoRoot: 1, - ExecutionMode: executor.ExecutionMode1, ClosingReason: state.SyncL1EventInitialBatchClosingReason, } } else { @@ -200,7 +198,6 @@ func (p *ProcessorL1SequenceBatchesEtrog) ProcessSequenceBatches(ctx context.Con BatchL2Data: &batch.BatchL2Data, SkipVerifyL1InfoRoot: 1, GlobalExitRoot: batch.GlobalExitRoot, - ExecutionMode: executor.ExecutionMode1, ClosingReason: state.SyncL1EventSequencedBatchClosingReason, } if batch.GlobalExitRoot == (common.Hash{}) { diff --git a/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go b/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go index 166f030b4e..3bd7e03cef 100644 --- a/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go +++ b/synchronizer/actions/etrog/processor_l1_update_etrog_sequence.go @@ -9,7 +9,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/state" "github.com/0xPolygonHermez/zkevm-node/state/metrics" stateMetrics "github.com/0xPolygonHermez/zkevm-node/state/metrics" - "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" "github.com/0xPolygonHermez/zkevm-node/synchronizer/actions" syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common" "github.com/ethereum/go-ethereum/common" @@ -84,7 +83,6 @@ func (g *ProcessorL1UpdateEtrogSequence) processUpdateEtrogSequence(ctx context. ForcedBlockHashL1: forcedBlockHashL1, SkipVerifyL1InfoRoot: 1, GlobalExitRoot: updateEtrogSequence.PolygonRollupBaseEtrogBatchData.ForcedGlobalExitRoot, - ExecutionMode: executor.ExecutionMode1, ClosingReason: state.SyncL1EventUpdateEtrogSequenceClosingReason, } diff --git a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go index 1975f6c42b..377825bf56 100644 --- a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go +++ b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go @@ -9,7 +9,6 @@ import ( "github.com/0xPolygonHermez/zkevm-node/jsonrpc/types" "github.com/0xPolygonHermez/zkevm-node/log" "github.com/0xPolygonHermez/zkevm-node/state" - "github.com/0xPolygonHermez/zkevm-node/state/runtime/executor" syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common" "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces" "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync" @@ -441,7 +440,6 @@ func (b *SyncTrustedBatchExecutorForEtrog) getProcessRequest(data *l2_shared.Pro Transactions: data.TrustedBatch.BatchL2Data, ForkID: b.state.GetForkIDByBatchNumber(uint64(data.TrustedBatch.Number)), SkipVerifyL1InfoRoot_V2: true, - ExecutionMode: executor.ExecutionMode1, } return request } diff --git a/synchronizer/l2_sync/l2_sync_incaberry/sync_trusted_state.go b/synchronizer/l2_sync/l2_sync_incaberry/sync_trusted_state.go index 9957b154ff..9dbf7af212 100644 --- a/synchronizer/l2_sync/l2_sync_incaberry/sync_trusted_state.go +++ b/synchronizer/l2_sync/l2_sync_incaberry/sync_trusted_state.go @@ -196,7 +196,6 @@ func (s *SyncTrustedBatchesAction) processTrustedBatch(ctx context.Context, trus OldAccInputHash: batches[1].AccInputHash, Coinbase: common.HexToAddress(trustedBatch.Coinbase.String()), Timestamp_V1: time.Unix(int64(trustedBatch.Timestamp), 0), - ExecutionMode: executor.ExecutionMode1, } // check if batch needs to be synchronized if batches[0] != nil { From 4bd2089639d574c2dc9d59c95e3fed467f221e9b Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Wed, 28 Feb 2024 17:05:36 +0100 Subject: [PATCH 38/51] fix metrics estimatedTxsPerSec (#3396) --- sequencer/metrics.go | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/sequencer/metrics.go b/sequencer/metrics.go index 409cc79d97..e1a10bc029 100644 --- a/sequencer/metrics.go +++ b/sequencer/metrics.go @@ -81,7 +81,10 @@ func (m *metrics) close(createdAt time.Time, txsCount int64) { if m.txsCount > 0 { // timePerTxuS is the average time spent per tx. This includes the l2Block time since the processing time of this section is proportional to the number of txs timePerTxuS := (m.transactionsTimes.total() + m.l2BlockTimes.total()).Microseconds() / m.txsCount - m.estimatedTxsPerSec = float64(m.totalTime().Microseconds()-m.newL2BlockTimes.total().Microseconds()) / float64(timePerTxuS) + // estimatedTxs is the number of transactions that we estimate could have been processed in the block + estimatedTxs := float64(totalTime.Microseconds()-m.newL2BlockTimes.total().Microseconds()) / float64(timePerTxuS) + // estimatedTxxPerSec is the estimated transactions per second + m.estimatedTxsPerSec = float64(totalTime.Microseconds()) / estimatedTxs } } @@ -151,7 +154,11 @@ func (i *intervalMetrics) addL2BlockMetrics(l2Block metrics) { } func (i *intervalMetrics) computeEstimatedTxsPerSec() { - i.estimatedTxsPerSec = i.estimatedTxsPerSecAcc / float64(i.estimatedTxsPerSecCount) + if i.estimatedTxsPerSecCount > 0 { + i.estimatedTxsPerSec = i.estimatedTxsPerSecAcc / float64(i.estimatedTxsPerSecCount) + } else { + i.estimatedTxsPerSecCount = 0 + } } func (i *intervalMetrics) startsAt() time.Time { From 858edacc704f41beb6ae7b0998158375856326e6 Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Thu, 29 Feb 2024 11:45:27 +0100 Subject: [PATCH 39/51] Fix metrics estimatedTxsPerSec division (#3398) * fix metrics estimatedTxsPerSec div * remove unneeded cast --- sequencer/metrics.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sequencer/metrics.go b/sequencer/metrics.go index e1a10bc029..ea39caa9ac 100644 --- a/sequencer/metrics.go +++ b/sequencer/metrics.go @@ -84,7 +84,7 @@ func (m *metrics) close(createdAt time.Time, txsCount int64) { // estimatedTxs is the number of transactions that we estimate could have been processed in the block estimatedTxs := float64(totalTime.Microseconds()-m.newL2BlockTimes.total().Microseconds()) / float64(timePerTxuS) // estimatedTxxPerSec is the estimated transactions per second - m.estimatedTxsPerSec = float64(totalTime.Microseconds()) / estimatedTxs + m.estimatedTxsPerSec = estimatedTxs / totalTime.Seconds() } } From f4f44b55d50212e731e167f6efc81c22a7090727 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Thu, 29 Feb 2024 15:50:40 +0100 Subject: [PATCH 40/51] Get IM State root from receipt for data stream. (#3400) * get im state root from receipt * get im state root from receipt * get im state root from receipt --- state/datastream.go | 20 +++++++++++--------- state/pgstatestorage/datastream.go | 5 ++++- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/state/datastream.go b/state/datastream.go index 6bad955516..9bcd7fac58 100644 --- a/state/datastream.go +++ b/state/datastream.go @@ -553,16 +553,18 @@ func GenerateDataStreamerFile(ctx context.Context, streamServer *datastreamer.St } for _, tx := range l2Block.Txs { - // Populate intermediate state root - if imStateRoots == nil || (*imStateRoots)[blockStart.L2BlockNumber] == nil { - position := GetSystemSCPosition(l2Block.L2BlockNumber) - imStateRoot, err := stateDB.GetStorageAt(ctx, common.HexToAddress(SystemSC), big.NewInt(0).SetBytes(position), l2Block.StateRoot) - if err != nil { - return err + if l2Block.ForkID < FORKID_ETROG { + // Populate intermediate state root with information from the system SC (or cache if available) + if imStateRoots == nil || (*imStateRoots)[blockStart.L2BlockNumber] == nil { + position := GetSystemSCPosition(l2Block.L2BlockNumber) + imStateRoot, err := stateDB.GetStorageAt(ctx, common.HexToAddress(SystemSC), big.NewInt(0).SetBytes(position), l2Block.StateRoot) + if err != nil { + return err + } + tx.StateRoot = common.BigToHash(imStateRoot) + } else { + tx.StateRoot = common.BytesToHash((*imStateRoots)[blockStart.L2BlockNumber]) } - tx.StateRoot = common.BigToHash(imStateRoot) - } else { - tx.StateRoot = common.BytesToHash((*imStateRoots)[blockStart.L2BlockNumber]) } _, err = streamServer.AddStreamEntry(EntryTypeL2Tx, tx.Encode()) diff --git a/state/pgstatestorage/datastream.go b/state/pgstatestorage/datastream.go index 00d136a278..d94eb385d5 100644 --- a/state/pgstatestorage/datastream.go +++ b/state/pgstatestorage/datastream.go @@ -91,7 +91,7 @@ func scanL2Block(row pgx.Row) (*state.DSL2Block, error) { // GetDSL2Transactions returns the L2 transactions func (p *PostgresStorage) GetDSL2Transactions(ctx context.Context, firstL2Block, lastL2Block uint64, dbTx pgx.Tx) ([]*state.DSL2Transaction, error) { - const l2TxSQL = `SELECT l2_block_num, t.effective_percentage, t.encoded + const l2TxSQL = `SELECT l2_block_num, t.effective_percentage, t.encoded, r.post_state FROM state.transaction t, state.receipt r WHERE l2_block_num BETWEEN $1 AND $2 AND r.tx_hash = t.hash ORDER BY t.l2_block_num ASC, r.tx_index ASC` @@ -119,10 +119,12 @@ func (p *PostgresStorage) GetDSL2Transactions(ctx context.Context, firstL2Block, func scanDSL2Transaction(row pgx.Row) (*state.DSL2Transaction, error) { l2Transaction := state.DSL2Transaction{} encoded := []byte{} + postState := []byte{} if err := row.Scan( &l2Transaction.L2BlockNumber, &l2Transaction.EffectiveGasPricePercentage, &encoded, + &postState, ); err != nil { return nil, err } @@ -139,6 +141,7 @@ func scanDSL2Transaction(row pgx.Row) (*state.DSL2Transaction, error) { l2Transaction.Encoded = binaryTxData l2Transaction.EncodedLength = uint32(len(l2Transaction.Encoded)) l2Transaction.IsValid = 1 + l2Transaction.StateRoot = common.BytesToHash(postState) return &l2Transaction, nil } From f4dd7054c24dc22199cd37697087b29f56aa3869 Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Thu, 29 Feb 2024 15:52:34 +0100 Subject: [PATCH 41/51] Add gas per second estimation in metrics (#3401) * add gas estimation in metrics * fix linter --- sequencer/finalizer.go | 27 ++++++++++++----- sequencer/metrics.go | 66 +++++++++++++++++++++++++++--------------- 2 files changed, 61 insertions(+), 32 deletions(-) diff --git a/sequencer/finalizer.go b/sequencer/finalizer.go index 1c0e46489b..6336df3b79 100644 --- a/sequencer/finalizer.go +++ b/sequencer/finalizer.go @@ -483,12 +483,17 @@ func (f *finalizer) processTransaction(ctx context.Context, tx *TxTracker, first // 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) { + txResponse := result.BlockResponses[0].TransactionResponses[0] + + // Update metrics + f.wipL2Block.metrics.processedTxsCount++ + // Handle Transaction Error - errorCode := executor.RomErrorCode(result.BlockResponses[0].TransactionResponses[0].RomError) + errorCode := executor.RomErrorCode(txResponse.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, txResponse.RomError } egpEnabled := f.effectiveGasPrice.IsEnabled() @@ -499,7 +504,7 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx // Get the tx gas price we will use in the egp calculation. If egp is disabled we will use a "simulated" tx gas price txGasPrice, txL2GasPrice := f.effectiveGasPrice.GetTxAndL2GasPrice(tx.GasPrice, tx.L1GasPrice, tx.L2GasPrice) - newEffectiveGasPrice, err := f.effectiveGasPrice.CalculateEffectiveGasPrice(tx.RawTx, txGasPrice, result.BlockResponses[0].TransactionResponses[0].GasUsed, tx.L1GasPrice, txL2GasPrice) + newEffectiveGasPrice, err := f.effectiveGasPrice.CalculateEffectiveGasPrice(tx.RawTx, txGasPrice, txResponse.GasUsed, tx.L1GasPrice, txL2GasPrice) 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()) @@ -511,9 +516,9 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx } else { // Save new (second) gas used and second effective gas price calculation for later logging tx.EGPLog.ValueSecond.Set(newEffectiveGasPrice) - tx.EGPLog.GasUsedSecond = result.BlockResponses[0].TransactionResponses[0].GasUsed + tx.EGPLog.GasUsedSecond = txResponse.GasUsed - errCompare := f.compareTxEffectiveGasPrice(ctx, tx, newEffectiveGasPrice, result.BlockResponses[0].TransactionResponses[0].HasGaspriceOpcode, result.BlockResponses[0].TransactionResponses[0].HasBalanceOpcode) + errCompare := f.compareTxEffectiveGasPrice(ctx, tx, newEffectiveGasPrice, txResponse.HasGaspriceOpcode, txResponse.HasBalanceOpcode) // If EffectiveGasPrice is disabled we will calculate the percentage and save it for later logging if !egpEnabled { @@ -572,14 +577,14 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx // If reserved tx resources don't fit in the remaining batch resources (or we got an overflow when trying to subtract the used resources) // we update the ZKCounters of the tx and returns ErrBatchResourceOverFlow error if !fits || subOverflow { - f.workerIntf.UpdateTxZKCounters(result.BlockResponses[0].TransactionResponses[0].TxHash, tx.From, result.UsedZkCounters, result.ReservedZkCounters) + f.workerIntf.UpdateTxZKCounters(txResponse.TxHash, tx.From, result.UsedZkCounters, result.ReservedZkCounters) return nil, ErrBatchResourceOverFlow } // Save Enabled, GasPriceOC, BalanceOC and final effective gas price for later logging tx.EGPLog.Enabled = egpEnabled - tx.EGPLog.GasPriceOC = result.BlockResponses[0].TransactionResponses[0].HasGaspriceOpcode - tx.EGPLog.BalanceOC = result.BlockResponses[0].TransactionResponses[0].HasBalanceOpcode + tx.EGPLog.GasPriceOC = txResponse.HasGaspriceOpcode + tx.EGPLog.BalanceOC = txResponse.HasBalanceOpcode tx.EGPLog.ValueFinal.Set(tx.EffectiveGasPrice) // Log here the results of EGP calculation @@ -593,6 +598,9 @@ func (f *finalizer) handleProcessTransactionResponse(ctx context.Context, tx *Tx f.updateWorkerAfterSuccessfulProcessing(ctx, tx.Hash, tx.From, false, result) + // Update metrics + f.wipL2Block.metrics.gas += txResponse.GasUsed + return nil, nil } @@ -720,6 +728,9 @@ func (f *finalizer) handleProcessTransactionError(ctx context.Context, result *s }() } + // Update metrics + f.wipL2Block.metrics.gas += txResponse.GasUsed + return wg } diff --git a/sequencer/metrics.go b/sequencer/metrics.go index ea39caa9ac..2be977e23e 100644 --- a/sequencer/metrics.go +++ b/sequencer/metrics.go @@ -2,6 +2,7 @@ package sequencer import ( "fmt" + "math" "time" ) @@ -34,28 +35,35 @@ func (p *processTimes) sumUp(ptSumUp processTimes) { type metrics struct { closedAt time.Time - txsCount int64 + processedTxsCount int64 + l2BlockTxsCount int64 idleTime time.Duration newL2BlockTimes processTimes transactionsTimes processTimes l2BlockTimes processTimes + gas uint64 estimatedTxsPerSec float64 + estimatedGasPerSec uint64 } func (m *metrics) sub(mSub metrics) { - m.txsCount -= mSub.txsCount + m.processedTxsCount -= mSub.processedTxsCount + m.l2BlockTxsCount -= mSub.l2BlockTxsCount m.idleTime -= mSub.idleTime m.newL2BlockTimes.sub(mSub.newL2BlockTimes) m.transactionsTimes.sub(mSub.transactionsTimes) m.l2BlockTimes.sub(mSub.l2BlockTimes) + m.gas -= mSub.gas } func (m *metrics) sumUp(mSumUp metrics) { - m.txsCount += mSumUp.txsCount + m.processedTxsCount += mSumUp.processedTxsCount + m.l2BlockTxsCount += mSumUp.l2BlockTxsCount m.idleTime += mSumUp.idleTime m.newL2BlockTimes.sumUp(mSumUp.newL2BlockTimes) m.transactionsTimes.sumUp(mSumUp.transactionsTimes) m.l2BlockTimes.sumUp(mSumUp.l2BlockTimes) + m.gas += mSumUp.gas } func (m *metrics) executorTime() time.Duration { @@ -70,27 +78,32 @@ func (m *metrics) totalTime() time.Duration { return m.newL2BlockTimes.total() + m.transactionsTimes.total() + m.l2BlockTimes.total() + m.idleTime } -func (m *metrics) close(createdAt time.Time, txsCount int64) { +func (m *metrics) close(createdAt time.Time, l2BlockTxsCount int64) { // Compute pending fields m.closedAt = time.Now() totalTime := time.Since(createdAt) - m.txsCount = txsCount + m.l2BlockTxsCount = l2BlockTxsCount m.transactionsTimes.sequencer = totalTime - m.idleTime - m.newL2BlockTimes.total() - m.transactionsTimes.executor - m.l2BlockTimes.total() // Compute performance - if m.txsCount > 0 { + if m.processedTxsCount > 0 { // timePerTxuS is the average time spent per tx. This includes the l2Block time since the processing time of this section is proportional to the number of txs - timePerTxuS := (m.transactionsTimes.total() + m.l2BlockTimes.total()).Microseconds() / m.txsCount + timePerTxuS := (m.transactionsTimes.total() + m.l2BlockTimes.total()).Microseconds() / m.processedTxsCount // estimatedTxs is the number of transactions that we estimate could have been processed in the block estimatedTxs := float64(totalTime.Microseconds()-m.newL2BlockTimes.total().Microseconds()) / float64(timePerTxuS) - // estimatedTxxPerSec is the estimated transactions per second - m.estimatedTxsPerSec = estimatedTxs / totalTime.Seconds() + // estimatedTxxPerSec is the estimated transactions per second (rounded to 2 decimal digits) + m.estimatedTxsPerSec = math.Ceil(estimatedTxs/totalTime.Seconds()*100) / 100 //nolint:gomnd + + // gasPerTx is the average gas used per tx + gasPerTx := m.gas / uint64(m.processedTxsCount) + // estimatedGasPerSec is the estimated gas per second + m.estimatedGasPerSec = uint64(m.estimatedTxsPerSec * float64(gasPerTx)) } } func (m *metrics) log() string { - return fmt.Sprintf("txs: %d, estimated txs/s: %.1f, time: {total: %d, idle: %d, sequencer: {total: %d, newL2Block: %d, txs: %d, l2Block: %d}, executor: {total: %d, newL2Block: %d, txs: %d, l2Block: %d}", - m.txsCount, m.estimatedTxsPerSec, m.totalTime().Microseconds(), m.idleTime.Microseconds(), + return fmt.Sprintf("blockTxs: %d, txs: %d, gas: %d, txsSec: %.2f, gasSec: %d, time: {total: %d, idle: %d, sequencer: {total: %d, newL2Block: %d, txs: %d, l2Block: %d}, executor: {total: %d, newL2Block: %d, txs: %d, l2Block: %d}", + m.l2BlockTxsCount, m.processedTxsCount, m.gas, m.estimatedTxsPerSec, m.estimatedGasPerSec, m.totalTime().Microseconds(), m.idleTime.Microseconds(), m.sequencerTime().Microseconds(), m.newL2BlockTimes.sequencer.Microseconds(), m.transactionsTimes.sequencer.Microseconds(), m.l2BlockTimes.sequencer.Microseconds(), m.executorTime().Microseconds(), m.newL2BlockTimes.executor.Microseconds(), m.transactionsTimes.executor.Microseconds(), m.l2BlockTimes.executor.Microseconds()) } @@ -99,8 +112,9 @@ type intervalMetrics struct { l2Blocks []*metrics maxInterval time.Duration metrics - estimatedTxsPerSecAcc float64 - estimatedTxsPerSecCount int64 + estimatedTxsPerSecAcc float64 + estimatedGasPerSecAcc uint64 + l2BlockCountAcc int64 } func newIntervalMetrics(maxInterval time.Duration) *intervalMetrics { @@ -122,9 +136,10 @@ func (i *intervalMetrics) cleanUp() { if l2Block.closedAt.Add(i.maxInterval).Before(now) { // Subtract l2Block metrics from accumulated values i.sub(*l2Block) - if l2Block.txsCount > 0 { - i.estimatedTxsPerSecAcc -= i.estimatedTxsPerSec - i.estimatedTxsPerSecCount-- + if l2Block.processedTxsCount > 0 { + i.estimatedTxsPerSecAcc -= l2Block.estimatedTxsPerSec + i.estimatedGasPerSecAcc -= l2Block.estimatedGasPerSec + i.l2BlockCountAcc-- } // Remove from l2Blocks i.l2Blocks = i.l2Blocks[1:] @@ -136,7 +151,7 @@ func (i *intervalMetrics) cleanUp() { if ct > 0 { // Compute performance - i.computeEstimatedTxsPerSec() + i.computePerformance() } } @@ -144,20 +159,23 @@ func (i *intervalMetrics) addL2BlockMetrics(l2Block metrics) { i.cleanUp() i.sumUp(l2Block) - if l2Block.txsCount > 0 { + if l2Block.processedTxsCount > 0 { i.estimatedTxsPerSecAcc += l2Block.estimatedTxsPerSec - i.estimatedTxsPerSecCount++ - i.computeEstimatedTxsPerSec() + i.estimatedGasPerSecAcc += l2Block.estimatedGasPerSec + i.l2BlockCountAcc++ + i.computePerformance() } i.l2Blocks = append(i.l2Blocks, &l2Block) } -func (i *intervalMetrics) computeEstimatedTxsPerSec() { - if i.estimatedTxsPerSecCount > 0 { - i.estimatedTxsPerSec = i.estimatedTxsPerSecAcc / float64(i.estimatedTxsPerSecCount) +func (i *intervalMetrics) computePerformance() { + if i.l2BlockCountAcc > 0 { + i.estimatedTxsPerSec = math.Ceil(i.estimatedTxsPerSecAcc/float64(i.l2BlockCountAcc)*100) / 100 //nolint:gomnd + i.estimatedGasPerSec = i.estimatedGasPerSecAcc / uint64(i.l2BlockCountAcc) } else { - i.estimatedTxsPerSecCount = 0 + i.estimatedTxsPerSec = 0 + i.estimatedGasPerSec = 0 } } From 2d93d42b43b8e65bee100478cd5d85eb66c66ef3 Mon Sep 17 00:00:00 2001 From: Joan Esteban <129153821+joanestebanr@users.noreply.github.com> Date: Fri, 1 Mar 2024 10:12:10 +0100 Subject: [PATCH 42/51] Feature/cherry pick 3375 sync add check l2block hash (#3406) * check L2Block hash on closed batch during sync from TrustedNode (#3390) --- config/config_test.go | 5 ++ config/default.go | 1 + docs/config-file/node-config-doc.html | 2 +- docs/config-file/node-config-doc.md | 23 +++++-- docs/config-file/node-config-schema.json | 5 ++ synchronizer/l2_sync/config.go | 3 + .../post_closed_batch_check_l2block.go | 63 +++++++++++++++++++ .../l2_shared/processor_trusted_batch_sync.go | 31 +++++++-- .../executor_trusted_batch_sync.go | 19 ++---- synchronizer/synchronizer.go | 18 ++++-- 10 files changed, 141 insertions(+), 29 deletions(-) create mode 100644 synchronizer/l2_sync/l2_shared/post_closed_batch_check_l2block.go diff --git a/config/config_test.go b/config/config_test.go index f2e01575b8..cf918c4afe 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -60,6 +60,11 @@ func Test_Defaults(t *testing.T) { path: "Synchronizer.L2Synchronization.ReprocessFullBatchOnClose", expectedValue: false, }, + { + path: "Synchronizer.L2Synchronization.CheckLastL2BlockHashOnCloseBatch", + expectedValue: true, + }, + { path: "Sequencer.DeletePoolTxsL1BlockConfirmations", expectedValue: uint64(100), diff --git a/config/default.go b/config/default.go index b28076b251..c8db9dbc2d 100644 --- a/config/default.go +++ b/config/default.go @@ -119,6 +119,7 @@ L1SynchronizationMode = "sequential" [Synchronizer.L2Synchronization] AcceptEmptyClosedBatches = false ReprocessFullBatchOnClose = false + CheckLastL2BlockHashOnCloseBatch = true [Sequencer] DeletePoolTxsL1BlockConfirmations = 100 diff --git a/docs/config-file/node-config-doc.html b/docs/config-file/node-config-doc.html index d76299260d..54dd3df718 100644 --- a/docs/config-file/node-config-doc.html +++ b/docs/config-file/node-config-doc.html @@ -28,7 +28,7 @@
"300ms"
 

Default: "5s"Type: string

RollupInfoRetriesSpacing is the minimum time between retries to request rollup info (it will sleep for fulfill this time) to avoid spamming L1


Examples:

"1m"
 
"300ms"
-

Default: falseType: boolean

FallbackToSequentialModeOnSynchronized if true switch to sequential mode if the system is synchronized


L2Synchronization Configuration for L2 synchronization
Default: falseType: boolean

AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.
if true, the synchronizer will accept empty batches and process them.


Default: falseType: boolean

ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again


Configuration of the sequencer service
Default: 100Type: integer

DeletePoolTxsL1BlockConfirmations is blocks amount after which txs will be deleted from the pool


Default: "12h0m0s"Type: string

DeletePoolTxsCheckInterval is frequency with which txs will be checked for deleting


Examples:

"1m"
+

Default: falseType: boolean

FallbackToSequentialModeOnSynchronized if true switch to sequential mode if the system is synchronized


L2Synchronization Configuration for L2 synchronization
Default: falseType: boolean

AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.
if true, the synchronizer will accept empty batches and process them.


Default: falseType: boolean

ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again


Default: trueType: boolean

CheckLastL2BlockHashOnCloseBatch if is true when a batch is closed is force to check the last L2Block hash


Configuration of the sequencer service
Default: 100Type: integer

DeletePoolTxsL1BlockConfirmations is blocks amount after which txs will be deleted from the pool


Default: "12h0m0s"Type: string

DeletePoolTxsCheckInterval is frequency with which txs will be checked for deleting


Examples:

"1m"
 
"300ms"
 

Default: "10m0s"Type: string

TxLifetimeCheckInterval is the time the sequencer waits to check txs lifetime


Examples:

"1m"
 
"300ms"
diff --git a/docs/config-file/node-config-doc.md b/docs/config-file/node-config-doc.md
index 5ca12d7e8b..0d70da8e62 100644
--- a/docs/config-file/node-config-doc.md
+++ b/docs/config-file/node-config-doc.md
@@ -1683,10 +1683,11 @@ FallbackToSequentialModeOnSynchronized=false
 **Type:** : `object`
 **Description:** L2Synchronization Configuration for L2 synchronization
 
-| Property                                                                                  | Pattern | Type    | Deprecated | Definition | Title/Description                                                                                                                                                   |
-| ----------------------------------------------------------------------------------------- | ------- | ------- | ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
-| - [AcceptEmptyClosedBatches](#Synchronizer_L2Synchronization_AcceptEmptyClosedBatches )   | No      | boolean | No         | -          | AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.
if true, the synchronizer will accept empty batches and process them. | -| - [ReprocessFullBatchOnClose](#Synchronizer_L2Synchronization_ReprocessFullBatchOnClose ) | No | boolean | No | - | ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again | +| Property | Pattern | Type | Deprecated | Definition | Title/Description | +| ------------------------------------------------------------------------------------------------------- | ------- | ------- | ---------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| - [AcceptEmptyClosedBatches](#Synchronizer_L2Synchronization_AcceptEmptyClosedBatches ) | No | boolean | No | - | AcceptEmptyClosedBatches is a flag to enable or disable the acceptance of empty batches.
if true, the synchronizer will accept empty batches and process them. | +| - [ReprocessFullBatchOnClose](#Synchronizer_L2Synchronization_ReprocessFullBatchOnClose ) | No | boolean | No | - | ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again | +| - [CheckLastL2BlockHashOnCloseBatch](#Synchronizer_L2Synchronization_CheckLastL2BlockHashOnCloseBatch ) | No | boolean | No | - | CheckLastL2BlockHashOnCloseBatch if is true when a batch is closed is force to check the last L2Block hash | #### 9.6.1. `Synchronizer.L2Synchronization.AcceptEmptyClosedBatches` @@ -1717,6 +1718,20 @@ AcceptEmptyClosedBatches=false ReprocessFullBatchOnClose=false ``` +#### 9.6.3. `Synchronizer.L2Synchronization.CheckLastL2BlockHashOnCloseBatch` + +**Type:** : `boolean` + +**Default:** `true` + +**Description:** CheckLastL2BlockHashOnCloseBatch if is true when a batch is closed is force to check the last L2Block hash + +**Example setting the default value** (true): +``` +[Synchronizer.L2Synchronization] +CheckLastL2BlockHashOnCloseBatch=true +``` + ## 10. `[Sequencer]` **Type:** : `object` diff --git a/docs/config-file/node-config-schema.json b/docs/config-file/node-config-schema.json index 3d8842e926..78e84ea934 100644 --- a/docs/config-file/node-config-schema.json +++ b/docs/config-file/node-config-schema.json @@ -636,6 +636,11 @@ "type": "boolean", "description": "ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again", "default": false + }, + "CheckLastL2BlockHashOnCloseBatch": { + "type": "boolean", + "description": "CheckLastL2BlockHashOnCloseBatch if is true when a batch is closed is force to check the last L2Block hash", + "default": true } }, "additionalProperties": false, diff --git a/synchronizer/l2_sync/config.go b/synchronizer/l2_sync/config.go index 7166765b88..7781c7bd6c 100644 --- a/synchronizer/l2_sync/config.go +++ b/synchronizer/l2_sync/config.go @@ -8,4 +8,7 @@ type Config struct { // ReprocessFullBatchOnClose if is true when a batch is closed is force to reprocess again ReprocessFullBatchOnClose bool `mapstructure:"ReprocessFullBatchOnClose"` + + // CheckLastL2BlockHashOnCloseBatch if is true when a batch is closed is force to check the last L2Block hash + CheckLastL2BlockHashOnCloseBatch bool `mapstructure:"CheckLastL2BlockHashOnCloseBatch"` } diff --git a/synchronizer/l2_sync/l2_shared/post_closed_batch_check_l2block.go b/synchronizer/l2_sync/l2_shared/post_closed_batch_check_l2block.go new file mode 100644 index 0000000000..e42842aa8a --- /dev/null +++ b/synchronizer/l2_sync/l2_shared/post_closed_batch_check_l2block.go @@ -0,0 +1,63 @@ +package l2_shared + +import ( + "context" + "fmt" + "math/big" + + "github.com/0xPolygonHermez/zkevm-node/log" + "github.com/0xPolygonHermez/zkevm-node/state" + "github.com/jackc/pgx/v4" +) + +// Implements PostClosedBatchChecker + +type statePostClosedBatchCheckL2Block interface { + GetLastL2BlockByBatchNumber(ctx context.Context, batchNumber uint64, dbTx pgx.Tx) (*state.L2Block, error) +} + +// PostClosedBatchCheckL2Block is a struct that implements the PostClosedBatchChecker interface and check the las L2Block hash on close batch +type PostClosedBatchCheckL2Block struct { + state statePostClosedBatchCheckL2Block +} + +// NewPostClosedBatchCheckL2Block creates a new PostClosedBatchCheckL2Block +func NewPostClosedBatchCheckL2Block(state statePostClosedBatchCheckL2Block) *PostClosedBatchCheckL2Block { + return &PostClosedBatchCheckL2Block{ + state: state, + } +} + +// CheckPostClosedBatch checks the last L2Block hash on close batch +func (p *PostClosedBatchCheckL2Block) CheckPostClosedBatch(ctx context.Context, processData ProcessData, dbTx pgx.Tx) error { + if processData.TrustedBatch == nil { + log.Warnf("%s trusted batch is nil", processData.DebugPrefix) + return nil + } + if len(processData.TrustedBatch.Blocks) == 0 { + log.Infof("%s trusted batch have no Blocks, so nothing to check", processData.DebugPrefix) + return nil + } + + // Get last L2Block from the database + statelastL2Block, err := p.state.GetLastL2BlockByBatchNumber(ctx, processData.BatchNumber, dbTx) + if err != nil { + return err + } + if statelastL2Block == nil { + return fmt.Errorf("last L2Block in the database is nil") + } + trustedLastL2Block := processData.TrustedBatch.Blocks[len(processData.TrustedBatch.Blocks)-1].Block + log.Info(trustedLastL2Block) + if statelastL2Block.Number().Cmp(big.NewInt(int64(trustedLastL2Block.Number))) != 0 { + return fmt.Errorf("last L2Block in the database %s and the trusted batch %d are different", statelastL2Block.Number().String(), trustedLastL2Block.Number) + } + + if statelastL2Block.Hash() != *trustedLastL2Block.Hash { + return fmt.Errorf("last L2Block %s in the database %s and the trusted batch %s are different", statelastL2Block.Number().String(), statelastL2Block.Hash().String(), trustedLastL2Block.Hash.String()) + } + log.Infof("%s last L2Block in the database %s and the trusted batch %s are the same", processData.DebugPrefix, statelastL2Block.Number().String(), trustedLastL2Block.Number) + // Compare the two blocks + + return nil +} diff --git a/synchronizer/l2_sync/l2_shared/processor_trusted_batch_sync.go b/synchronizer/l2_sync/l2_shared/processor_trusted_batch_sync.go index 94535ebe4e..db4ddd15e0 100644 --- a/synchronizer/l2_sync/l2_shared/processor_trusted_batch_sync.go +++ b/synchronizer/l2_sync/l2_shared/processor_trusted_batch_sync.go @@ -132,16 +132,22 @@ type L1SyncGlobalExitRootChecker interface { CheckL1SyncGlobalExitRootEnoughToProcessBatch(ctx context.Context, batchNumber uint64, globalExitRoot common.Hash, dbTx pgx.Tx) error } +// PostClosedBatchChecker is the interface to implement a checker post closed batch +type PostClosedBatchChecker interface { + CheckPostClosedBatch(ctx context.Context, processData ProcessData, dbTx pgx.Tx) error +} + // ProcessorTrustedBatchSync is a template to sync trusted state. It classify what kind of update is needed and call to SyncTrustedStateBatchExecutorSteps // // that is the one that execute the sync process // // the real implementation of the steps is in the SyncTrustedStateBatchExecutorSteps interface that known how to process a batch type ProcessorTrustedBatchSync struct { - Steps SyncTrustedBatchExecutor - timeProvider syncCommon.TimeProvider - l1SyncChecker L1SyncGlobalExitRootChecker - Cfg l2_sync.Config + Steps SyncTrustedBatchExecutor + timeProvider syncCommon.TimeProvider + l1SyncChecker L1SyncGlobalExitRootChecker + postClosedCheckers []PostClosedBatchChecker + Cfg l2_sync.Config } // NewProcessorTrustedBatchSync creates a new SyncTrustedStateBatchExecutorTemplate @@ -155,6 +161,14 @@ func NewProcessorTrustedBatchSync(steps SyncTrustedBatchExecutor, } } +// AddPostChecker add a post closed batch checker +func (s *ProcessorTrustedBatchSync) AddPostChecker(checker PostClosedBatchChecker) { + if s.postClosedCheckers == nil { + s.postClosedCheckers = make([]PostClosedBatchChecker, 0) + } + s.postClosedCheckers = append(s.postClosedCheckers, checker) +} + // ProcessTrustedBatch processes a trusted batch and return the new state func (s *ProcessorTrustedBatchSync) ProcessTrustedBatch(ctx context.Context, trustedBatch *types.Batch, status TrustedState, dbTx pgx.Tx, debugPrefix string) (*TrustedState, error) { log.Debugf("%s Processing trusted batch: %v", debugPrefix, trustedBatch.Number) @@ -241,6 +255,15 @@ func (s *ProcessorTrustedBatchSync) ExecuteProcessBatch(ctx context.Context, pro log.Error("%s error verifying batch result! Error: ", processMode.DebugPrefix, err) return nil, err } + if s.postClosedCheckers != nil && len(s.postClosedCheckers) > 0 { + for _, checker := range s.postClosedCheckers { + err := checker.CheckPostClosedBatch(ctx, *processMode, dbTx) + if err != nil { + log.Errorf("%s error checking post closed batch. Error: ", processMode.DebugPrefix, err) + return nil, err + } + } + } } return processBatchResp, err } diff --git a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go index 377825bf56..bb1a0798fa 100644 --- a/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go +++ b/synchronizer/l2_sync/l2_sync_etrog/executor_trusted_batch_sync.go @@ -11,16 +11,11 @@ import ( "github.com/0xPolygonHermez/zkevm-node/state" syncCommon "github.com/0xPolygonHermez/zkevm-node/synchronizer/common" "github.com/0xPolygonHermez/zkevm-node/synchronizer/common/syncinterfaces" - "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync" "github.com/0xPolygonHermez/zkevm-node/synchronizer/l2_sync/l2_shared" "github.com/ethereum/go-ethereum/common" "github.com/jackc/pgx/v4" ) -const ( - timeOfLiveBatchOnCache = 5 * time.Minute -) - var ( // ErrNotImplemented is returned when a method is not implemented ErrNotImplemented = errors.New("not implemented") @@ -54,19 +49,13 @@ type SyncTrustedBatchExecutorForEtrog struct { sync syncinterfaces.SynchronizerFlushIDManager } -// NewSyncTrustedBatchExecutorForEtrog creates a new prcessor for sync with L2 batches -func NewSyncTrustedBatchExecutorForEtrog(zkEVMClient syncinterfaces.ZKEVMClientTrustedBatchesGetter, - state l2_shared.StateInterface, stateBatchExecutor StateInterface, - sync syncinterfaces.SynchronizerFlushIDManager, timeProvider syncCommon.TimeProvider, l1SyncChecker l2_shared.L1SyncGlobalExitRootChecker, - cfg l2_sync.Config) *l2_shared.TrustedBatchesRetrieve { - executorSteps := &SyncTrustedBatchExecutorForEtrog{ +// NewSyncTrustedBatchExecutorForEtrog creates a new SyncTrustedBatchExecutorForEtrog +func NewSyncTrustedBatchExecutorForEtrog(stateBatchExecutor StateInterface, + sync syncinterfaces.SynchronizerFlushIDManager) *SyncTrustedBatchExecutorForEtrog { + return &SyncTrustedBatchExecutorForEtrog{ state: stateBatchExecutor, sync: sync, } - - executor := l2_shared.NewProcessorTrustedBatchSync(executorSteps, timeProvider, l1SyncChecker, cfg) - a := l2_shared.NewTrustedBatchesRetrieve(executor, zkEVMClient, state, sync, *l2_shared.NewTrustedStateManager(timeProvider, timeOfLiveBatchOnCache)) - return a } // NothingProcess process a batch that is already on database and no new L2batchData, so it is not going to be processed again. diff --git a/synchronizer/synchronizer.go b/synchronizer/synchronizer.go index 591b2f4357..8029ec36a1 100644 --- a/synchronizer/synchronizer.go +++ b/synchronizer/synchronizer.go @@ -29,8 +29,9 @@ const ( // ParallelMode is the value for L1SynchronizationMode to run in parallel mode ParallelMode = "parallel" // SequentialMode is the value for L1SynchronizationMode to run in sequential mode - SequentialMode = "sequential" - maxBatchNumber = ^uint64(0) + SequentialMode = "sequential" + maxBatchNumber = ^uint64(0) + timeOfLiveBatchOnCache = 5 * time.Minute ) // Synchronizer connects L1 and L2 @@ -113,10 +114,17 @@ func NewSynchronizer( if !isTrustedSequencer { log.Info("Permissionless: creating and Initializing L2 synchronization components") L1SyncChecker := l2_sync_etrog.NewCheckSyncStatusToProcessBatch(res.zkEVMClient, res.state) + sync := &res + //syncTrustedStateEtrog := l2_sync_etrog.NewSyncTrustedBatchExecutorForEtrog(res.zkEVMClient, res.state, res.state, res, + // syncCommon.DefaultTimeProvider{}, L1SyncChecker, cfg.L2Synchronization) + executorSteps := l2_sync_etrog.NewSyncTrustedBatchExecutorForEtrog(res.state, *sync) + executor := l2_shared.NewProcessorTrustedBatchSync(executorSteps, syncCommon.DefaultTimeProvider{}, L1SyncChecker, cfg.L2Synchronization) + if cfg.L2Synchronization.CheckLastL2BlockHashOnCloseBatch { + log.Infof("Adding check of L2Block hash on close batch when sync from trusted node") + executor.AddPostChecker(l2_shared.NewPostClosedBatchCheckL2Block(res.state)) + } - syncTrustedStateEtrog := l2_sync_etrog.NewSyncTrustedBatchExecutorForEtrog(res.zkEVMClient, res.state, res.state, res, - syncCommon.DefaultTimeProvider{}, L1SyncChecker, cfg.L2Synchronization) - + syncTrustedStateEtrog := l2_shared.NewTrustedBatchesRetrieve(executor, zkEVMClient, res.state, *sync, *l2_shared.NewTrustedStateManager(syncCommon.DefaultTimeProvider{}, timeOfLiveBatchOnCache)) res.syncTrustedStateExecutor = l2_shared.NewSyncTrustedStateExecutorSelector(map[uint64]syncinterfaces.SyncTrustedStateExecutor{ uint64(state.FORKID_ETROG): syncTrustedStateEtrog, uint64(state.FORKID_ELDERBERRY): syncTrustedStateEtrog, From fe9b257fa632e97a90a10c1b778e9ff17725d47a Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Fri, 1 Mar 2024 11:35:42 +0100 Subject: [PATCH 43/51] update prover image to v5.0.3 (#3407) --- 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 a6a3329621..70a519a031 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:v5.0.0-RC8 + image: hermeznetwork/zkevm-prover:v5.0.3 depends_on: zkevm-state-db: condition: service_healthy diff --git a/test/docker-compose.yml b/test/docker-compose.yml index f9c8ef62bd..0768008245 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:v5.0.0-RC8 + image: hermeznetwork/zkevm-prover:v5.0.3 ports: - 50061:50061 # MT - 50071:50071 # Executor @@ -602,7 +602,7 @@ services: zkevm-permissionless-prover: container_name: zkevm-permissionless-prover - image: hermeznetwork/zkevm-prover:v5.0.0-RC8 + image: hermeznetwork/zkevm-prover:v5.0.3 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover From 1365a559bd57e2fc7f2d2cf69b0e17d6bdee7649 Mon Sep 17 00:00:00 2001 From: agnusmor <100322135+agnusmor@users.noreply.github.com> Date: Thu, 7 Mar 2024 15:32:34 +0100 Subject: [PATCH 44/51] keep empty RPC.SequencerNodeURI config parameter to get node URI from the SC (#3430) --- config/environments/cardona/node.config.toml | 2 +- config/environments/mainnet/node.config.toml | 2 +- config/environments/testnet/node.config.toml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/config/environments/cardona/node.config.toml b/config/environments/cardona/node.config.toml index 14d2fd580c..9c8eb34a84 100644 --- a/config/environments/cardona/node.config.toml +++ b/config/environments/cardona/node.config.toml @@ -45,7 +45,7 @@ Port = 8545 ReadTimeout = "60s" WriteTimeout = "60s" MaxRequestsPerIPAndSecond = 5000 -SequencerNodeURI = "https://rpc.devnet.zkevm-rpc.com" +SequencerNodeURI = "" EnableL2SuggestedGasPricePolling = false [RPC.WebSockets] Enabled = true diff --git a/config/environments/mainnet/node.config.toml b/config/environments/mainnet/node.config.toml index 67c6882670..64bcdf9d96 100644 --- a/config/environments/mainnet/node.config.toml +++ b/config/environments/mainnet/node.config.toml @@ -43,7 +43,7 @@ Port = 8545 ReadTimeout = "60s" WriteTimeout = "60s" MaxRequestsPerIPAndSecond = 5000 -SequencerNodeURI = "https://zkevm-rpc.com" +SequencerNodeURI = "" EnableL2SuggestedGasPricePolling = false [RPC.WebSockets] Enabled = true diff --git a/config/environments/testnet/node.config.toml b/config/environments/testnet/node.config.toml index eb8f9266a0..9c8eb34a84 100644 --- a/config/environments/testnet/node.config.toml +++ b/config/environments/testnet/node.config.toml @@ -45,7 +45,7 @@ Port = 8545 ReadTimeout = "60s" WriteTimeout = "60s" MaxRequestsPerIPAndSecond = 5000 -SequencerNodeURI = "https://rpc.public.zkevm-test.net/" +SequencerNodeURI = "" EnableL2SuggestedGasPricePolling = false [RPC.WebSockets] Enabled = true From 2261ccc3ad063e58a3fddfb81d9e33865832b05c Mon Sep 17 00:00:00 2001 From: Thiago Coimbra Lemos Date: Fri, 8 Mar 2024 13:38:18 -0300 Subject: [PATCH 45/51] add log0 debug trace e2e tests (#3422) * add log0 debug trace e2e tests * add log0 debug trace e2e tests --- test/contracts/auto/Log0.sol | 23 +++ test/contracts/bin/Log0/Log0.go | 266 ++++++++++++++++++++++++++++++ test/e2e/debug_calltracer_test.go | 3 + test/e2e/debug_shared.go | 70 ++++++++ test/e2e/debug_test.go | 3 + 5 files changed, 365 insertions(+) create mode 100644 test/contracts/auto/Log0.sol create mode 100644 test/contracts/bin/Log0/Log0.go diff --git a/test/contracts/auto/Log0.sol b/test/contracts/auto/Log0.sol new file mode 100644 index 0000000000..9f4a416284 --- /dev/null +++ b/test/contracts/auto/Log0.sol @@ -0,0 +1,23 @@ +// SPDX-License-Identifier: GPL-3.0 +pragma solidity >=0.7.0 <0.9.0; + +contract Log0 { + // opcode 0xa0 + function opLog0() public payable { + assembly { + log0(0, 32) + } + } + + function opLog00() public payable { + assembly { + log0(0, 0) + } + } + + function opLog01() public payable { + assembly { + log0(0, 28) + } + } +} \ No newline at end of file diff --git a/test/contracts/bin/Log0/Log0.go b/test/contracts/bin/Log0/Log0.go new file mode 100644 index 0000000000..78cbc26331 --- /dev/null +++ b/test/contracts/bin/Log0/Log0.go @@ -0,0 +1,266 @@ +// Code generated - DO NOT EDIT. +// This file is a generated binding and any manual changes will be lost. + +package Log0 + +import ( + "errors" + "math/big" + "strings" + + ethereum "github.com/ethereum/go-ethereum" + "github.com/ethereum/go-ethereum/accounts/abi" + "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/event" +) + +// Reference imports to suppress errors if they are not otherwise used. +var ( + _ = errors.New + _ = big.NewInt + _ = strings.NewReader + _ = ethereum.NotFound + _ = bind.Bind + _ = common.Big1 + _ = types.BloomLookup + _ = event.NewSubscription + _ = abi.ConvertType +) + +// Log0MetaData contains all meta data concerning the Log0 contract. +var Log0MetaData = &bind.MetaData{ + ABI: "[{\"inputs\":[],\"name\":\"opLog0\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"opLog00\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"},{\"inputs\":[],\"name\":\"opLog01\",\"outputs\":[],\"stateMutability\":\"payable\",\"type\":\"function\"}]", + Bin: "0x6080604052348015600f57600080fd5b5060938061001e6000396000f3fe60806040526004361060305760003560e01c80633e2d0b8514603557806357e4605514603d578063ecc5544a146043575b600080fd5b603b6049565b005b603b6050565b603b6056565b601c6000a0565b600080a0565b60206000a056fea26469706673582212209aba01a729d89e6da96ac8ca0b8f1940565356ed4f7849c9af7a95f5188d22d964736f6c634300080c0033", +} + +// Log0ABI is the input ABI used to generate the binding from. +// Deprecated: Use Log0MetaData.ABI instead. +var Log0ABI = Log0MetaData.ABI + +// Log0Bin is the compiled bytecode used for deploying new contracts. +// Deprecated: Use Log0MetaData.Bin instead. +var Log0Bin = Log0MetaData.Bin + +// DeployLog0 deploys a new Ethereum contract, binding an instance of Log0 to it. +func DeployLog0(auth *bind.TransactOpts, backend bind.ContractBackend) (common.Address, *types.Transaction, *Log0, error) { + parsed, err := Log0MetaData.GetAbi() + if err != nil { + return common.Address{}, nil, nil, err + } + if parsed == nil { + return common.Address{}, nil, nil, errors.New("GetABI returned nil") + } + + address, tx, contract, err := bind.DeployContract(auth, *parsed, common.FromHex(Log0Bin), backend) + if err != nil { + return common.Address{}, nil, nil, err + } + return address, tx, &Log0{Log0Caller: Log0Caller{contract: contract}, Log0Transactor: Log0Transactor{contract: contract}, Log0Filterer: Log0Filterer{contract: contract}}, nil +} + +// Log0 is an auto generated Go binding around an Ethereum contract. +type Log0 struct { + Log0Caller // Read-only binding to the contract + Log0Transactor // Write-only binding to the contract + Log0Filterer // Log filterer for contract events +} + +// Log0Caller is an auto generated read-only Go binding around an Ethereum contract. +type Log0Caller struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Log0Transactor is an auto generated write-only Go binding around an Ethereum contract. +type Log0Transactor struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Log0Filterer is an auto generated log filtering Go binding around an Ethereum contract events. +type Log0Filterer struct { + contract *bind.BoundContract // Generic contract wrapper for the low level calls +} + +// Log0Session is an auto generated Go binding around an Ethereum contract, +// with pre-set call and transact options. +type Log0Session struct { + Contract *Log0 // Generic contract binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// Log0CallerSession is an auto generated read-only Go binding around an Ethereum contract, +// with pre-set call options. +type Log0CallerSession struct { + Contract *Log0Caller // Generic contract caller binding to set the session for + CallOpts bind.CallOpts // Call options to use throughout this session +} + +// Log0TransactorSession is an auto generated write-only Go binding around an Ethereum contract, +// with pre-set transact options. +type Log0TransactorSession struct { + Contract *Log0Transactor // Generic contract transactor binding to set the session for + TransactOpts bind.TransactOpts // Transaction auth options to use throughout this session +} + +// Log0Raw is an auto generated low-level Go binding around an Ethereum contract. +type Log0Raw struct { + Contract *Log0 // Generic contract binding to access the raw methods on +} + +// Log0CallerRaw is an auto generated low-level read-only Go binding around an Ethereum contract. +type Log0CallerRaw struct { + Contract *Log0Caller // Generic read-only contract binding to access the raw methods on +} + +// Log0TransactorRaw is an auto generated low-level write-only Go binding around an Ethereum contract. +type Log0TransactorRaw struct { + Contract *Log0Transactor // Generic write-only contract binding to access the raw methods on +} + +// NewLog0 creates a new instance of Log0, bound to a specific deployed contract. +func NewLog0(address common.Address, backend bind.ContractBackend) (*Log0, error) { + contract, err := bindLog0(address, backend, backend, backend) + if err != nil { + return nil, err + } + return &Log0{Log0Caller: Log0Caller{contract: contract}, Log0Transactor: Log0Transactor{contract: contract}, Log0Filterer: Log0Filterer{contract: contract}}, nil +} + +// NewLog0Caller creates a new read-only instance of Log0, bound to a specific deployed contract. +func NewLog0Caller(address common.Address, caller bind.ContractCaller) (*Log0Caller, error) { + contract, err := bindLog0(address, caller, nil, nil) + if err != nil { + return nil, err + } + return &Log0Caller{contract: contract}, nil +} + +// NewLog0Transactor creates a new write-only instance of Log0, bound to a specific deployed contract. +func NewLog0Transactor(address common.Address, transactor bind.ContractTransactor) (*Log0Transactor, error) { + contract, err := bindLog0(address, nil, transactor, nil) + if err != nil { + return nil, err + } + return &Log0Transactor{contract: contract}, nil +} + +// NewLog0Filterer creates a new log filterer instance of Log0, bound to a specific deployed contract. +func NewLog0Filterer(address common.Address, filterer bind.ContractFilterer) (*Log0Filterer, error) { + contract, err := bindLog0(address, nil, nil, filterer) + if err != nil { + return nil, err + } + return &Log0Filterer{contract: contract}, nil +} + +// bindLog0 binds a generic wrapper to an already deployed contract. +func bindLog0(address common.Address, caller bind.ContractCaller, transactor bind.ContractTransactor, filterer bind.ContractFilterer) (*bind.BoundContract, error) { + parsed, err := Log0MetaData.GetAbi() + if err != nil { + return nil, err + } + return bind.NewBoundContract(address, *parsed, caller, transactor, filterer), nil +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Log0 *Log0Raw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Log0.Contract.Log0Caller.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Log0 *Log0Raw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Log0.Contract.Log0Transactor.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Log0 *Log0Raw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Log0.Contract.Log0Transactor.contract.Transact(opts, method, params...) +} + +// Call invokes the (constant) contract method with params as input values and +// sets the output to result. The result type might be a single field for simple +// returns, a slice of interfaces for anonymous returns and a struct for named +// returns. +func (_Log0 *Log0CallerRaw) Call(opts *bind.CallOpts, result *[]interface{}, method string, params ...interface{}) error { + return _Log0.Contract.contract.Call(opts, result, method, params...) +} + +// Transfer initiates a plain transaction to move funds to the contract, calling +// its default method if one is available. +func (_Log0 *Log0TransactorRaw) Transfer(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Log0.Contract.contract.Transfer(opts) +} + +// Transact invokes the (paid) contract method with params as input values. +func (_Log0 *Log0TransactorRaw) Transact(opts *bind.TransactOpts, method string, params ...interface{}) (*types.Transaction, error) { + return _Log0.Contract.contract.Transact(opts, method, params...) +} + +// OpLog0 is a paid mutator transaction binding the contract method 0xecc5544a. +// +// Solidity: function opLog0() payable returns() +func (_Log0 *Log0Transactor) OpLog0(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Log0.contract.Transact(opts, "opLog0") +} + +// OpLog0 is a paid mutator transaction binding the contract method 0xecc5544a. +// +// Solidity: function opLog0() payable returns() +func (_Log0 *Log0Session) OpLog0() (*types.Transaction, error) { + return _Log0.Contract.OpLog0(&_Log0.TransactOpts) +} + +// OpLog0 is a paid mutator transaction binding the contract method 0xecc5544a. +// +// Solidity: function opLog0() payable returns() +func (_Log0 *Log0TransactorSession) OpLog0() (*types.Transaction, error) { + return _Log0.Contract.OpLog0(&_Log0.TransactOpts) +} + +// OpLog00 is a paid mutator transaction binding the contract method 0x57e46055. +// +// Solidity: function opLog00() payable returns() +func (_Log0 *Log0Transactor) OpLog00(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Log0.contract.Transact(opts, "opLog00") +} + +// OpLog00 is a paid mutator transaction binding the contract method 0x57e46055. +// +// Solidity: function opLog00() payable returns() +func (_Log0 *Log0Session) OpLog00() (*types.Transaction, error) { + return _Log0.Contract.OpLog00(&_Log0.TransactOpts) +} + +// OpLog00 is a paid mutator transaction binding the contract method 0x57e46055. +// +// Solidity: function opLog00() payable returns() +func (_Log0 *Log0TransactorSession) OpLog00() (*types.Transaction, error) { + return _Log0.Contract.OpLog00(&_Log0.TransactOpts) +} + +// OpLog01 is a paid mutator transaction binding the contract method 0x3e2d0b85. +// +// Solidity: function opLog01() payable returns() +func (_Log0 *Log0Transactor) OpLog01(opts *bind.TransactOpts) (*types.Transaction, error) { + return _Log0.contract.Transact(opts, "opLog01") +} + +// OpLog01 is a paid mutator transaction binding the contract method 0x3e2d0b85. +// +// Solidity: function opLog01() payable returns() +func (_Log0 *Log0Session) OpLog01() (*types.Transaction, error) { + return _Log0.Contract.OpLog01(&_Log0.TransactOpts) +} + +// OpLog01 is a paid mutator transaction binding the contract method 0x3e2d0b85. +// +// Solidity: function opLog01() payable returns() +func (_Log0 *Log0TransactorSession) OpLog01() (*types.Transaction, error) { + return _Log0.Contract.OpLog01(&_Log0.TransactOpts) +} diff --git a/test/e2e/debug_calltracer_test.go b/test/e2e/debug_calltracer_test.go index 2108884f5c..f2a8d756fe 100644 --- a/test/e2e/debug_calltracer_test.go +++ b/test/e2e/debug_calltracer_test.go @@ -104,6 +104,9 @@ func TestDebugTraceTransactionCallTracer(t *testing.T) { {name: "memory", prepare: prepareMemory, createSignedTx: createMemorySignedTx}, {name: "bridge", prepare: prepareBridge, createSignedTx: createBridgeSignedTx}, {name: "deploy create 0", createSignedTx: createDeployCreate0SignedTx}, + {name: "log0 all zeros", prepare: prepareLog0, createSignedTx: createLog0AllZeros}, + {name: "log0 empty", prepare: prepareLog0, createSignedTx: createLog0Empty}, + {name: "log0 short", prepare: prepareLog0, createSignedTx: createLog0Short}, // failed transactions {name: "sc deployment reverted", createSignedTx: createScDeployRevertedSignedTx}, diff --git a/test/e2e/debug_shared.go b/test/e2e/debug_shared.go index 08a0367ffb..f0c78ed663 100644 --- a/test/e2e/debug_shared.go +++ b/test/e2e/debug_shared.go @@ -26,6 +26,7 @@ import ( "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Depth" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/ERC20" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/EmitLog" + "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Log0" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Memory" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/OpCallAux" "github.com/0xPolygonHermez/zkevm-node/test/contracts/bin/Revert2" @@ -883,3 +884,72 @@ func sendEthTransfersWithoutWaiting(t *testing.T, ctx context.Context, client *e log.Debugf("sending eth transfer: %v", signedTx.Hash().String()) } } + +func prepareLog0(t *testing.T, ctx context.Context, auth *bind.TransactOpts, client *ethclient.Client) (map[string]interface{}, error) { + _, tx, sc, err := Log0.DeployLog0(auth, client) + require.NoError(t, err) + + err = operations.WaitTxToBeMined(ctx, client, tx, operations.DefaultTimeoutTxToBeMined) + require.NoError(t, err) + + return map[string]interface{}{ + "sc": sc, + }, nil +} + +func createLog0AllZeros(t *testing.T, ctx context.Context, auth *bind.TransactOpts, client *ethclient.Client, customData map[string]interface{}) (*ethTypes.Transaction, error) { + scInterface := customData["sc"] + sc := scInterface.(*Log0.Log0) + + gasPrice, err := client.SuggestGasPrice(ctx) + require.NoError(t, err) + + opts := *auth + opts.NoSend = true + opts.Value = big.NewInt(0).SetUint64(txValue) + opts.GasPrice = gasPrice + opts.GasLimit = fixedTxGasLimit + + tx, err := sc.OpLog0(&opts) + require.NoError(t, err) + + return tx, nil +} + +func createLog0Empty(t *testing.T, ctx context.Context, auth *bind.TransactOpts, client *ethclient.Client, customData map[string]interface{}) (*ethTypes.Transaction, error) { + scInterface := customData["sc"] + sc := scInterface.(*Log0.Log0) + + gasPrice, err := client.SuggestGasPrice(ctx) + require.NoError(t, err) + + opts := *auth + opts.NoSend = true + opts.Value = big.NewInt(0).SetUint64(txValue) + opts.GasPrice = gasPrice + opts.GasLimit = fixedTxGasLimit + + tx, err := sc.OpLog00(&opts) + require.NoError(t, err) + + return tx, nil +} + +func createLog0Short(t *testing.T, ctx context.Context, auth *bind.TransactOpts, client *ethclient.Client, customData map[string]interface{}) (*ethTypes.Transaction, error) { + scInterface := customData["sc"] + sc := scInterface.(*Log0.Log0) + + gasPrice, err := client.SuggestGasPrice(ctx) + require.NoError(t, err) + + opts := *auth + opts.NoSend = true + opts.Value = big.NewInt(0).SetUint64(txValue) + opts.GasPrice = gasPrice + opts.GasLimit = fixedTxGasLimit + + tx, err := sc.OpLog01(&opts) + require.NoError(t, err) + + return tx, nil +} diff --git a/test/e2e/debug_test.go b/test/e2e/debug_test.go index a514136ad2..e32802eed0 100644 --- a/test/e2e/debug_test.go +++ b/test/e2e/debug_test.go @@ -318,6 +318,9 @@ func TestDebugTraceTransaction(t *testing.T) { {name: "memory", prepare: prepareMemory, createSignedTx: createMemorySignedTx}, {name: "bridge", prepare: prepareBridge, createSignedTx: createBridgeSignedTx}, {name: "deploy create 0", createSignedTx: createDeployCreate0SignedTx}, + {name: "log0 all zeros", prepare: prepareLog0, createSignedTx: createLog0AllZeros}, + {name: "log0 empty", prepare: prepareLog0, createSignedTx: createLog0Empty}, + {name: "log0 short", prepare: prepareLog0, createSignedTx: createLog0Short}, // failed transactions {name: "sc deployment reverted", createSignedTx: createScDeployRevertedSignedTx}, From 21491a84fed8433635904526394b7aaa982fdbc3 Mon Sep 17 00:00:00 2001 From: Thiago Coimbra Lemos Date: Fri, 8 Mar 2024 13:41:16 -0300 Subject: [PATCH 46/51] Elderberry blockhash adjustments (#3424) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * remove intermediate state root from receipts after Etrog * use receipt state returned by executor instead of checking the RomError * use receipt status from executor only after Etrog * fix gasLimit and cumulativeGasUsed for Elderberry txs (#3428) * keep im state root in db (#3427) * generate receipt refactor (#3436) * generate receipt refactor * update prover image * downgrade prover image --------- Co-authored-by: agnusmor <100322135+agnusmor@users.noreply.github.com> Co-authored-by: Toni Ramírez <58293609+ToniRamirezM@users.noreply.github.com> --- db/migrations/state/0017.sql | 9 ++++ jsonrpc/endpoints_eth_test.go | 2 +- jsonrpc/endpoints_zkevm_test.go | 2 +- jsonrpc/types/types.go | 8 ++- proto/src/proto/executor/v1/executor.proto | 2 + state/convertersV2.go | 1 + state/datastream.go | 6 +++ state/genesis.go | 2 +- state/helper.go | 36 ++++++++----- state/interfaces.go | 4 +- state/mocks/mock_storage.go | 42 ++++++++------- state/pgstatestorage/datastream.go | 5 +- state/pgstatestorage/l2block.go | 6 +-- state/pgstatestorage/pgstatestorage_test.go | 11 ++-- state/pgstatestorage/transaction.go | 16 +++--- state/runtime/executor/errors.go | 4 ++ state/runtime/executor/executor.pb.go | 53 +++++++++++-------- state/runtime/runtime.go | 2 + .../forkid_dragonfruit/dragonfruit_test.go | 3 +- .../forkid_independent/independent_test.go | 3 +- state/transaction.go | 26 ++++++--- state/types.go | 2 + 22 files changed, 156 insertions(+), 89 deletions(-) create mode 100644 db/migrations/state/0017.sql diff --git a/db/migrations/state/0017.sql b/db/migrations/state/0017.sql new file mode 100644 index 0000000000..1c06607dfe --- /dev/null +++ b/db/migrations/state/0017.sql @@ -0,0 +1,9 @@ +-- +migrate Up +ALTER TABLE state.receipt + ADD COLUMN IF NOT EXISTS im_state_root BYTEA; + +UPDATE state.receipt SET im_state_root = post_state WHERE block_num >= (SELECT MIN(block_num) FROM state.l2block WHERE batch_num >= (SELECT from_batch_num FROM state.fork_id WHERE fork_id = 7)); + +-- +migrate Down +ALTER TABLE state.receipt + DROP COLUMN IF EXISTS im_state_root; diff --git a/jsonrpc/endpoints_eth_test.go b/jsonrpc/endpoints_eth_test.go index 60067ab1b3..33f4b1ec9c 100644 --- a/jsonrpc/endpoints_eth_test.go +++ b/jsonrpc/endpoints_eth_test.go @@ -3311,7 +3311,7 @@ func TestGetTransactionReceipt(t *testing.T) { receipt.Bloom = ethTypes.CreateBloom(ethTypes.Receipts{receipt}) rpcReceipt := types.Receipt{ - Root: stateRoot, + Root: &stateRoot, CumulativeGasUsed: types.ArgUint64(receipt.CumulativeGasUsed), LogsBloom: receipt.Bloom, Logs: receipt.Logs, diff --git a/jsonrpc/endpoints_zkevm_test.go b/jsonrpc/endpoints_zkevm_test.go index 85db81328b..8c0090d1e2 100644 --- a/jsonrpc/endpoints_zkevm_test.go +++ b/jsonrpc/endpoints_zkevm_test.go @@ -2260,7 +2260,7 @@ func TestGetTransactionReceiptByL2Hash(t *testing.T) { receipt.Bloom = ethTypes.CreateBloom(ethTypes.Receipts{receipt}) rpcReceipt := types.Receipt{ - Root: stateRoot, + Root: &stateRoot, CumulativeGasUsed: types.ArgUint64(receipt.CumulativeGasUsed), LogsBloom: receipt.Bloom, Logs: receipt.Logs, diff --git a/jsonrpc/types/types.go b/jsonrpc/types/types.go index eec295f8ad..ec50389564 100644 --- a/jsonrpc/types/types.go +++ b/jsonrpc/types/types.go @@ -601,7 +601,7 @@ func NewTransaction( // Receipt structure type Receipt struct { - Root common.Hash `json:"root"` + Root *common.Hash `json:"root,omitempty"` CumulativeGasUsed ArgUint64 `json:"cumulativeGasUsed"` LogsBloom types.Bloom `json:"logsBloom"` Logs []*types.Log `json:"logs"` @@ -643,7 +643,6 @@ func NewReceipt(tx types.Transaction, r *types.Receipt, l2Hash *common.Hash) (Re return Receipt{}, err } receipt := Receipt{ - Root: common.BytesToHash(r.PostState), CumulativeGasUsed: ArgUint64(r.CumulativeGasUsed), LogsBloom: r.Bloom, Logs: logs, @@ -659,6 +658,11 @@ func NewReceipt(tx types.Transaction, r *types.Receipt, l2Hash *common.Hash) (Re Type: ArgUint64(r.Type), TxL2Hash: l2Hash, } + if common.BytesToHash(r.PostState).String() != state.ZeroHash.String() { + root := common.BytesToHash(r.PostState) + receipt.Root = &root + } + if r.EffectiveGasPrice != nil { egp := ArgBig(*r.EffectiveGasPrice) receipt.EffectiveGasPrice = &egp diff --git a/proto/src/proto/executor/v1/executor.proto b/proto/src/proto/executor/v1/executor.proto index e18008ba58..e79e52c7b0 100644 --- a/proto/src/proto/executor/v1/executor.proto +++ b/proto/src/proto/executor/v1/executor.proto @@ -872,4 +872,6 @@ 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_SM_MAIN_INVALID_TX_STATUS_ERROR indicates that a TX has an invalid status-error combination + EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR = 117; } diff --git a/state/convertersV2.go b/state/convertersV2.go index c68d33db48..b445bad973 100644 --- a/state/convertersV2.go +++ b/state/convertersV2.go @@ -127,6 +127,7 @@ func (s *State) convertToProcessTransactionResponseV2(responses []*executor.Proc result.ReturnValue = response.ReturnValue result.GasLeft = response.GasLeft result.GasUsed = response.GasUsed + result.CumulativeGasUsed = response.CumulativeGasUsed result.GasRefunded = response.GasRefunded result.RomError = executor.RomErr(response.Error) result.CreateAddress = common.HexToAddress(response.CreateAddress) diff --git a/state/datastream.go b/state/datastream.go index 9bcd7fac58..d50c7adecf 100644 --- a/state/datastream.go +++ b/state/datastream.go @@ -118,6 +118,7 @@ func (b DSL2BlockStart) Decode(data []byte) DSL2BlockStart { // DSL2Transaction represents a data stream L2 transaction type DSL2Transaction struct { L2BlockNumber uint64 // Not included in the encoded data + ImStateRoot common.Hash // Not included in the encoded data EffectiveGasPricePercentage uint8 // 1 byte IsValid uint8 // 1 byte StateRoot common.Hash // 32 bytes @@ -553,6 +554,9 @@ func GenerateDataStreamerFile(ctx context.Context, streamServer *datastreamer.St } for _, tx := range l2Block.Txs { + // < ETROG => IM State root is retrieved from the system SC (using cache is available) + // = ETROG => IM State root is retrieved from the receipt.post_state => Do nothing + // > ETROG => IM State root is retrieved from the receipt.im_state_root if l2Block.ForkID < FORKID_ETROG { // Populate intermediate state root with information from the system SC (or cache if available) if imStateRoots == nil || (*imStateRoots)[blockStart.L2BlockNumber] == nil { @@ -565,6 +569,8 @@ func GenerateDataStreamerFile(ctx context.Context, streamServer *datastreamer.St } else { tx.StateRoot = common.BytesToHash((*imStateRoots)[blockStart.L2BlockNumber]) } + } else if l2Block.ForkID > FORKID_ETROG { + tx.StateRoot = tx.ImStateRoot } _, err = streamServer.AddStreamEntry(EntryTypeL2Tx, tx.Encode()) diff --git a/state/genesis.go b/state/genesis.go index 41c2424c56..50c4b5a950 100644 --- a/state/genesis.go +++ b/state/genesis.go @@ -204,7 +204,7 @@ func (s *State) SetGenesis(ctx context.Context, block Block, genesis Genesis, m storeTxsEGPData := []StoreTxEGPData{} txsL2Hash := []common.Hash{} - err = s.AddL2Block(ctx, batch.BatchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, dbTx) + err = s.AddL2Block(ctx, batch.BatchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, []common.Hash{}, dbTx) if err != nil { return common.Hash{}, err } diff --git a/state/helper.go b/state/helper.go index 473725b33d..4d074292bb 100644 --- a/state/helper.go +++ b/state/helper.go @@ -279,19 +279,23 @@ func DecodeTx(encodedTx string) (*types.Transaction, error) { } // GenerateReceipt generates a receipt from a processed transaction -func GenerateReceipt(blockNumber *big.Int, processedTx *ProcessTransactionResponse, txIndex uint) *types.Receipt { +func GenerateReceipt(blockNumber *big.Int, processedTx *ProcessTransactionResponse, txIndex uint, forkID uint64) *types.Receipt { receipt := &types.Receipt{ - Type: uint8(processedTx.Type), - PostState: processedTx.StateRoot.Bytes(), - CumulativeGasUsed: processedTx.GasUsed, - BlockNumber: blockNumber, - GasUsed: processedTx.GasUsed, - TxHash: processedTx.Tx.Hash(), - TransactionIndex: txIndex, - ContractAddress: processedTx.CreateAddress, - Logs: processedTx.Logs, + Type: uint8(processedTx.Type), + BlockNumber: blockNumber, + GasUsed: processedTx.GasUsed, + TxHash: processedTx.Tx.Hash(), + TransactionIndex: txIndex, + ContractAddress: processedTx.CreateAddress, + Logs: processedTx.Logs, + } + if forkID <= FORKID_ETROG { + receipt.PostState = processedTx.StateRoot.Bytes() + receipt.CumulativeGasUsed = processedTx.GasUsed + } else { + receipt.PostState = ZeroHash.Bytes() + receipt.CumulativeGasUsed = processedTx.CumulativeGasUsed } - if processedTx.EffectiveGasPrice != "" { effectiveGasPrice, ok := big.NewInt(0).SetString(processedTx.EffectiveGasPrice, 0) if !ok { @@ -309,10 +313,14 @@ func GenerateReceipt(blockNumber *big.Int, processedTx *ProcessTransactionRespon for i := 0; i < len(receipt.Logs); i++ { receipt.Logs[i].TxHash = processedTx.Tx.Hash() } - if processedTx.RomError == nil { - receipt.Status = types.ReceiptStatusSuccessful + if forkID <= FORKID_ETROG { + if processedTx.RomError == nil { + receipt.Status = types.ReceiptStatusSuccessful + } else { + receipt.Status = types.ReceiptStatusFailed + } } else { - receipt.Status = types.ReceiptStatusFailed + receipt.Status = uint64(processedTx.Status) } return receipt diff --git a/state/interfaces.go b/state/interfaces.go index daa38906fd..17264098be 100644 --- a/state/interfaces.go +++ b/state/interfaces.go @@ -72,7 +72,7 @@ type storage interface { GetL2BlockTransactionCountByHash(ctx context.Context, blockHash common.Hash, dbTx pgx.Tx) (uint64, error) GetL2BlockTransactionCountByNumber(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (uint64, error) GetTransactionEGPLogByHash(ctx context.Context, transactionHash common.Hash, dbTx pgx.Tx) (*EffectiveGasPriceLog, error) - AddL2Block(ctx context.Context, batchNumber uint64, l2Block *L2Block, receipts []*types.Receipt, txsL2Hash []common.Hash, txsEGPData []StoreTxEGPData, dbTx pgx.Tx) error + AddL2Block(ctx context.Context, batchNumber uint64, l2Block *L2Block, receipts []*types.Receipt, txsL2Hash []common.Hash, txsEGPData []StoreTxEGPData, imStateRoots []common.Hash, dbTx pgx.Tx) error GetLastVirtualizedL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) GetLastConsolidatedL2BlockNumber(ctx context.Context, dbTx pgx.Tx) (uint64, error) GetLastVerifiedL2BlockNumberUntilL1Block(ctx context.Context, l1FinalizedBlockNumber uint64, dbTx pgx.Tx) (uint64, error) @@ -93,7 +93,7 @@ type storage interface { IsL2BlockConsolidated(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (bool, error) IsL2BlockVirtualized(ctx context.Context, blockNumber uint64, dbTx pgx.Tx) (bool, error) GetLogs(ctx context.Context, fromBlock uint64, toBlock uint64, addresses []common.Address, topics [][]common.Hash, blockHash *common.Hash, since *time.Time, dbTx pgx.Tx) ([]*types.Log, error) - AddReceipt(ctx context.Context, receipt *types.Receipt, dbTx pgx.Tx) error + AddReceipt(ctx context.Context, receipt *types.Receipt, imStateRoot common.Hash, dbTx pgx.Tx) error AddLog(ctx context.Context, l *types.Log, dbTx pgx.Tx) error GetExitRootByGlobalExitRoot(ctx context.Context, ger common.Hash, dbTx pgx.Tx) (*GlobalExitRoot, error) AddSequence(ctx context.Context, sequence Sequence, dbTx pgx.Tx) error diff --git a/state/mocks/mock_storage.go b/state/mocks/mock_storage.go index a2d06980c1..b07d5de4cc 100644 --- a/state/mocks/mock_storage.go +++ b/state/mocks/mock_storage.go @@ -418,17 +418,17 @@ func (_c *StorageMock_AddL1InfoRootToExitRoot_Call) RunAndReturn(run func(contex return _c } -// AddL2Block provides a mock function with given fields: ctx, batchNumber, l2Block, receipts, txsL2Hash, txsEGPData, dbTx -func (_m *StorageMock) AddL2Block(ctx context.Context, batchNumber uint64, l2Block *state.L2Block, receipts []*types.Receipt, txsL2Hash []common.Hash, txsEGPData []state.StoreTxEGPData, dbTx pgx.Tx) error { - ret := _m.Called(ctx, batchNumber, l2Block, receipts, txsL2Hash, txsEGPData, dbTx) +// AddL2Block provides a mock function with given fields: ctx, batchNumber, l2Block, receipts, txsL2Hash, txsEGPData, imStateRoots, dbTx +func (_m *StorageMock) AddL2Block(ctx context.Context, batchNumber uint64, l2Block *state.L2Block, receipts []*types.Receipt, txsL2Hash []common.Hash, txsEGPData []state.StoreTxEGPData, imStateRoots []common.Hash, dbTx pgx.Tx) error { + ret := _m.Called(ctx, batchNumber, l2Block, receipts, txsL2Hash, txsEGPData, imStateRoots, dbTx) if len(ret) == 0 { panic("no return value specified for AddL2Block") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, uint64, *state.L2Block, []*types.Receipt, []common.Hash, []state.StoreTxEGPData, pgx.Tx) error); ok { - r0 = rf(ctx, batchNumber, l2Block, receipts, txsL2Hash, txsEGPData, dbTx) + if rf, ok := ret.Get(0).(func(context.Context, uint64, *state.L2Block, []*types.Receipt, []common.Hash, []state.StoreTxEGPData, []common.Hash, pgx.Tx) error); ok { + r0 = rf(ctx, batchNumber, l2Block, receipts, txsL2Hash, txsEGPData, imStateRoots, dbTx) } else { r0 = ret.Error(0) } @@ -448,14 +448,15 @@ type StorageMock_AddL2Block_Call struct { // - receipts []*types.Receipt // - txsL2Hash []common.Hash // - txsEGPData []state.StoreTxEGPData +// - imStateRoots []common.Hash // - dbTx pgx.Tx -func (_e *StorageMock_Expecter) AddL2Block(ctx interface{}, batchNumber interface{}, l2Block interface{}, receipts interface{}, txsL2Hash interface{}, txsEGPData interface{}, dbTx interface{}) *StorageMock_AddL2Block_Call { - return &StorageMock_AddL2Block_Call{Call: _e.mock.On("AddL2Block", ctx, batchNumber, l2Block, receipts, txsL2Hash, txsEGPData, dbTx)} +func (_e *StorageMock_Expecter) AddL2Block(ctx interface{}, batchNumber interface{}, l2Block interface{}, receipts interface{}, txsL2Hash interface{}, txsEGPData interface{}, imStateRoots interface{}, dbTx interface{}) *StorageMock_AddL2Block_Call { + return &StorageMock_AddL2Block_Call{Call: _e.mock.On("AddL2Block", ctx, batchNumber, l2Block, receipts, txsL2Hash, txsEGPData, imStateRoots, dbTx)} } -func (_c *StorageMock_AddL2Block_Call) Run(run func(ctx context.Context, batchNumber uint64, l2Block *state.L2Block, receipts []*types.Receipt, txsL2Hash []common.Hash, txsEGPData []state.StoreTxEGPData, dbTx pgx.Tx)) *StorageMock_AddL2Block_Call { +func (_c *StorageMock_AddL2Block_Call) Run(run func(ctx context.Context, batchNumber uint64, l2Block *state.L2Block, receipts []*types.Receipt, txsL2Hash []common.Hash, txsEGPData []state.StoreTxEGPData, imStateRoots []common.Hash, dbTx pgx.Tx)) *StorageMock_AddL2Block_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(uint64), args[2].(*state.L2Block), args[3].([]*types.Receipt), args[4].([]common.Hash), args[5].([]state.StoreTxEGPData), args[6].(pgx.Tx)) + run(args[0].(context.Context), args[1].(uint64), args[2].(*state.L2Block), args[3].([]*types.Receipt), args[4].([]common.Hash), args[5].([]state.StoreTxEGPData), args[6].([]common.Hash), args[7].(pgx.Tx)) }) return _c } @@ -465,7 +466,7 @@ func (_c *StorageMock_AddL2Block_Call) Return(_a0 error) *StorageMock_AddL2Block return _c } -func (_c *StorageMock_AddL2Block_Call) RunAndReturn(run func(context.Context, uint64, *state.L2Block, []*types.Receipt, []common.Hash, []state.StoreTxEGPData, pgx.Tx) error) *StorageMock_AddL2Block_Call { +func (_c *StorageMock_AddL2Block_Call) RunAndReturn(run func(context.Context, uint64, *state.L2Block, []*types.Receipt, []common.Hash, []state.StoreTxEGPData, []common.Hash, pgx.Tx) error) *StorageMock_AddL2Block_Call { _c.Call.Return(run) return _c } @@ -518,17 +519,17 @@ func (_c *StorageMock_AddLog_Call) RunAndReturn(run func(context.Context, *types return _c } -// AddReceipt provides a mock function with given fields: ctx, receipt, dbTx -func (_m *StorageMock) AddReceipt(ctx context.Context, receipt *types.Receipt, dbTx pgx.Tx) error { - ret := _m.Called(ctx, receipt, dbTx) +// AddReceipt provides a mock function with given fields: ctx, receipt, imStateRoot, dbTx +func (_m *StorageMock) AddReceipt(ctx context.Context, receipt *types.Receipt, imStateRoot common.Hash, dbTx pgx.Tx) error { + ret := _m.Called(ctx, receipt, imStateRoot, dbTx) if len(ret) == 0 { panic("no return value specified for AddReceipt") } var r0 error - if rf, ok := ret.Get(0).(func(context.Context, *types.Receipt, pgx.Tx) error); ok { - r0 = rf(ctx, receipt, dbTx) + if rf, ok := ret.Get(0).(func(context.Context, *types.Receipt, common.Hash, pgx.Tx) error); ok { + r0 = rf(ctx, receipt, imStateRoot, dbTx) } else { r0 = ret.Error(0) } @@ -544,14 +545,15 @@ type StorageMock_AddReceipt_Call struct { // AddReceipt is a helper method to define mock.On call // - ctx context.Context // - receipt *types.Receipt +// - imStateRoot common.Hash // - dbTx pgx.Tx -func (_e *StorageMock_Expecter) AddReceipt(ctx interface{}, receipt interface{}, dbTx interface{}) *StorageMock_AddReceipt_Call { - return &StorageMock_AddReceipt_Call{Call: _e.mock.On("AddReceipt", ctx, receipt, dbTx)} +func (_e *StorageMock_Expecter) AddReceipt(ctx interface{}, receipt interface{}, imStateRoot interface{}, dbTx interface{}) *StorageMock_AddReceipt_Call { + return &StorageMock_AddReceipt_Call{Call: _e.mock.On("AddReceipt", ctx, receipt, imStateRoot, dbTx)} } -func (_c *StorageMock_AddReceipt_Call) Run(run func(ctx context.Context, receipt *types.Receipt, dbTx pgx.Tx)) *StorageMock_AddReceipt_Call { +func (_c *StorageMock_AddReceipt_Call) Run(run func(ctx context.Context, receipt *types.Receipt, imStateRoot common.Hash, dbTx pgx.Tx)) *StorageMock_AddReceipt_Call { _c.Call.Run(func(args mock.Arguments) { - run(args[0].(context.Context), args[1].(*types.Receipt), args[2].(pgx.Tx)) + run(args[0].(context.Context), args[1].(*types.Receipt), args[2].(common.Hash), args[3].(pgx.Tx)) }) return _c } @@ -561,7 +563,7 @@ func (_c *StorageMock_AddReceipt_Call) Return(_a0 error) *StorageMock_AddReceipt return _c } -func (_c *StorageMock_AddReceipt_Call) RunAndReturn(run func(context.Context, *types.Receipt, pgx.Tx) error) *StorageMock_AddReceipt_Call { +func (_c *StorageMock_AddReceipt_Call) RunAndReturn(run func(context.Context, *types.Receipt, common.Hash, pgx.Tx) error) *StorageMock_AddReceipt_Call { _c.Call.Return(run) return _c } diff --git a/state/pgstatestorage/datastream.go b/state/pgstatestorage/datastream.go index d94eb385d5..4b15000aeb 100644 --- a/state/pgstatestorage/datastream.go +++ b/state/pgstatestorage/datastream.go @@ -91,7 +91,7 @@ func scanL2Block(row pgx.Row) (*state.DSL2Block, error) { // GetDSL2Transactions returns the L2 transactions func (p *PostgresStorage) GetDSL2Transactions(ctx context.Context, firstL2Block, lastL2Block uint64, dbTx pgx.Tx) ([]*state.DSL2Transaction, error) { - const l2TxSQL = `SELECT l2_block_num, t.effective_percentage, t.encoded, r.post_state + const l2TxSQL = `SELECT l2_block_num, t.effective_percentage, t.encoded, r.post_state, r.im_state_root FROM state.transaction t, state.receipt r WHERE l2_block_num BETWEEN $1 AND $2 AND r.tx_hash = t.hash ORDER BY t.l2_block_num ASC, r.tx_index ASC` @@ -120,11 +120,13 @@ func scanDSL2Transaction(row pgx.Row) (*state.DSL2Transaction, error) { l2Transaction := state.DSL2Transaction{} encoded := []byte{} postState := []byte{} + imStateRoot := []byte{} if err := row.Scan( &l2Transaction.L2BlockNumber, &l2Transaction.EffectiveGasPricePercentage, &encoded, &postState, + &imStateRoot, ); err != nil { return nil, err } @@ -142,6 +144,7 @@ func scanDSL2Transaction(row pgx.Row) (*state.DSL2Transaction, error) { l2Transaction.EncodedLength = uint32(len(l2Transaction.Encoded)) l2Transaction.IsValid = 1 l2Transaction.StateRoot = common.BytesToHash(postState) + l2Transaction.ImStateRoot = common.BytesToHash(imStateRoot) return &l2Transaction, nil } diff --git a/state/pgstatestorage/l2block.go b/state/pgstatestorage/l2block.go index fac23ce6ce..8ea2870f3d 100644 --- a/state/pgstatestorage/l2block.go +++ b/state/pgstatestorage/l2block.go @@ -169,8 +169,8 @@ func (p *PostgresStorage) GetL2BlockTransactionCountByNumber(ctx context.Context } // AddL2Block adds a new L2 block to the State Store -func (p *PostgresStorage) AddL2Block(ctx context.Context, batchNumber uint64, l2Block *state.L2Block, receipts []*types.Receipt, txsL2Hash []common.Hash, txsEGPData []state.StoreTxEGPData, dbTx pgx.Tx) error { - //TODO: Optmize this function using only one SQL (with several values) to insert all the txs, receips and logs +func (p *PostgresStorage) AddL2Block(ctx context.Context, batchNumber uint64, l2Block *state.L2Block, receipts []*types.Receipt, txsL2Hash []common.Hash, txsEGPData []state.StoreTxEGPData, imStateRoots []common.Hash, dbTx pgx.Tx) error { + // TODO: Optimize this function using only one SQL (with several values) to insert all the txs, receipts and logs log.Debugf("[AddL2Block] adding L2 block %d", l2Block.NumberU64()) start := time.Now() @@ -255,7 +255,7 @@ func (p *PostgresStorage) AddL2Block(ctx context.Context, batchNumber uint64, l2 } if len(receipts) > 0 { - p.AddReceipts(ctx, receipts, dbTx) + p.AddReceipts(ctx, receipts, imStateRoots, dbTx) var logs []*types.Log for _, receipt := range receipts { diff --git a/state/pgstatestorage/pgstatestorage_test.go b/state/pgstatestorage/pgstatestorage_test.go index 8c0b553514..08a9fe8a7a 100644 --- a/state/pgstatestorage/pgstatestorage_test.go +++ b/state/pgstatestorage/pgstatestorage_test.go @@ -188,6 +188,7 @@ func TestGetBatchByL2BlockNumber(t *testing.T) { transactions := []*types.Transaction{tx} receipts := []*types.Receipt{receipt} + imStateRoots := []common.Hash{state.ZeroHash} // Create block to be able to calculate its hash st := trie.NewStackTrie(nil) @@ -202,7 +203,7 @@ func TestGetBatchByL2BlockNumber(t *testing.T) { txsL2Hash[i] = common.HexToHash(fmt.Sprintf("0x%d", i)) } - err = pgStateStorage.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, dbTx) + err = pgStateStorage.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, imStateRoots, dbTx) require.NoError(t, err) result, err := pgStateStorage.BatchNumberByL2BlockNumber(ctx, l2Block.Number().Uint64(), dbTx) require.NoError(t, err) @@ -724,7 +725,7 @@ func TestGetLastVerifiedL2BlockNumberUntilL1Block(t *testing.T) { txsL2Hash[i] = common.HexToHash(fmt.Sprintf("0x%d", i)) } - err = testState.AddL2Block(ctx, batchNumber, l2Block, []*types.Receipt{}, txsL2Hash, storeTxsEGPData, dbTx) + err = testState.AddL2Block(ctx, batchNumber, l2Block, []*types.Receipt{}, txsL2Hash, storeTxsEGPData, []common.Hash{}, dbTx) require.NoError(t, err) virtualBatch := state.VirtualBatch{BlockNumber: blockNumber, BatchNumber: batchNumber, Coinbase: addr, SequencerAddr: addr, TxHash: hash} @@ -923,6 +924,7 @@ func TestGetLogs(t *testing.T) { transactions := []*types.Transaction{tx} receipts := []*types.Receipt{receipt} + stateRoots := []common.Hash{state.ZeroHash} header := state.NewL2Header(&types.Header{ Number: big.NewInt(int64(i) + 1), @@ -948,7 +950,7 @@ func TestGetLogs(t *testing.T) { txsL2Hash[i] = common.HexToHash(fmt.Sprintf("0x%d", i)) } - err = testState.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, dbTx) + err = testState.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, stateRoots, dbTx) require.NoError(t, err) } @@ -1054,6 +1056,7 @@ func TestGetNativeBlockHashesInRange(t *testing.T) { transactions := []*types.Transaction{tx} receipts := []*types.Receipt{receipt} + stateRoots := []common.Hash{state.ZeroHash} header := state.NewL2Header(&types.Header{ Number: big.NewInt(int64(i) + 1), @@ -1079,7 +1082,7 @@ func TestGetNativeBlockHashesInRange(t *testing.T) { txsL2Hash[i] = common.HexToHash(fmt.Sprintf("0x%d", i)) } - err = testState.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, dbTx) + err = testState.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, stateRoots, dbTx) require.NoError(t, err) nativeBlockHashes = append(nativeBlockHashes, l2Block.Header().Root) diff --git a/state/pgstatestorage/transaction.go b/state/pgstatestorage/transaction.go index b372b6b13d..f25554d44e 100644 --- a/state/pgstatestorage/transaction.go +++ b/state/pgstatestorage/transaction.go @@ -515,7 +515,7 @@ func (p *PostgresStorage) GetTxsByBatchNumber(ctx context.Context, batchNumber u } // AddReceipt adds a new receipt to the State Store -func (p *PostgresStorage) AddReceipt(ctx context.Context, receipt *types.Receipt, dbTx pgx.Tx) error { +func (p *PostgresStorage) AddReceipt(ctx context.Context, receipt *types.Receipt, imStateRoot common.Hash, dbTx pgx.Tx) error { e := p.getExecQuerier(dbTx) var effectiveGasPrice *uint64 @@ -526,31 +526,31 @@ func (p *PostgresStorage) AddReceipt(ctx context.Context, receipt *types.Receipt } const addReceiptSQL = ` - INSERT INTO state.receipt (tx_hash, type, post_state, status, cumulative_gas_used, gas_used, effective_gas_price, block_num, tx_index, contract_address) - VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10)` - _, err := e.Exec(ctx, addReceiptSQL, receipt.TxHash.String(), receipt.Type, receipt.PostState, receipt.Status, receipt.CumulativeGasUsed, receipt.GasUsed, effectiveGasPrice, receipt.BlockNumber.Uint64(), receipt.TransactionIndex, receipt.ContractAddress.String()) + INSERT INTO state.receipt (tx_hash, type, post_state, status, cumulative_gas_used, gas_used, effective_gas_price, block_num, tx_index, contract_address, im_state_root) + VALUES ( $1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)` + _, err := e.Exec(ctx, addReceiptSQL, receipt.TxHash.String(), receipt.Type, receipt.PostState, receipt.Status, receipt.CumulativeGasUsed, receipt.GasUsed, effectiveGasPrice, receipt.BlockNumber.Uint64(), receipt.TransactionIndex, receipt.ContractAddress.String(), imStateRoot.Bytes()) return err } // AddReceipts adds a list of receipts to the State Store -func (p *PostgresStorage) AddReceipts(ctx context.Context, receipts []*types.Receipt, dbTx pgx.Tx) error { +func (p *PostgresStorage) AddReceipts(ctx context.Context, receipts []*types.Receipt, imStateRoots []common.Hash, dbTx pgx.Tx) error { if len(receipts) == 0 { return nil } receiptRows := [][]interface{}{} - for _, receipt := range receipts { + for i, receipt := range receipts { var egp uint64 if receipt.EffectiveGasPrice != nil { egp = receipt.EffectiveGasPrice.Uint64() } - receiptRow := []interface{}{receipt.TxHash.String(), receipt.Type, receipt.PostState, receipt.Status, receipt.CumulativeGasUsed, receipt.GasUsed, egp, receipt.BlockNumber.Uint64(), receipt.TransactionIndex, receipt.ContractAddress.String()} + receiptRow := []interface{}{receipt.TxHash.String(), receipt.Type, receipt.PostState, receipt.Status, receipt.CumulativeGasUsed, receipt.GasUsed, egp, receipt.BlockNumber.Uint64(), receipt.TransactionIndex, receipt.ContractAddress.String(), imStateRoots[i].Bytes()} receiptRows = append(receiptRows, receiptRow) } _, err := dbTx.CopyFrom(ctx, pgx.Identifier{"state", "receipt"}, - []string{"tx_hash", "type", "post_state", "status", "cumulative_gas_used", "gas_used", "effective_gas_price", "block_num", "tx_index", "contract_address"}, + []string{"tx_hash", "type", "post_state", "status", "cumulative_gas_used", "gas_used", "effective_gas_price", "block_num", "tx_index", "contract_address", "im_state_root"}, pgx.CopyFromRows(receiptRows)) return err diff --git a/state/runtime/executor/errors.go b/state/runtime/executor/errors.go index a2e8f2d1d5..a0ca5782d6 100644 --- a/state/runtime/executor/errors.go +++ b/state/runtime/executor/errors.go @@ -454,6 +454,8 @@ func ExecutorErr(errorCode ExecutorError) error { return runtime.ErrExecutorErrorInvalidDataStream case ExecutorError_EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE: return runtime.ErrExecutorErrorInvalidUpdateMerkleTree + case ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR: + return runtime.ErrExecutorErrorSMMainInvalidTxStatusError } return ErrExecutorUnknown } @@ -694,6 +696,8 @@ func ExecutorErrorCode(err error) ExecutorError { return ExecutorError_EXECUTOR_ERROR_INVALID_DATA_STREAM case runtime.ErrExecutorErrorInvalidUpdateMerkleTree: return ExecutorError_EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE + case runtime.ErrExecutorErrorSMMainInvalidTxStatusError: + return ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR } return ErrCodeExecutorUnknown diff --git a/state/runtime/executor/executor.pb.go b/state/runtime/executor/executor.pb.go index af7ad962b8..376c3c6252 100644 --- a/state/runtime/executor/executor.pb.go +++ b/state/runtime/executor/executor.pb.go @@ -438,6 +438,8 @@ const ( 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_SM_MAIN_INVALID_TX_STATUS_ERROR indicates that a TX has an invalid status-error combination + ExecutorError_EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR ExecutorError = 117 ) // Enum value maps for ExecutorError. @@ -560,6 +562,7 @@ var ( 114: "EXECUTOR_ERROR_INVALID_CBOR", 115: "EXECUTOR_ERROR_INVALID_DATA_STREAM", 116: "EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE", + 117: "EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR", } ExecutorError_value = map[string]int32{ "EXECUTOR_ERROR_UNSPECIFIED": 0, @@ -679,6 +682,7 @@ var ( "EXECUTOR_ERROR_INVALID_CBOR": 114, "EXECUTOR_ERROR_INVALID_DATA_STREAM": 115, "EXECUTOR_ERROR_INVALID_UPDATE_MERKLE_TREE": 116, + "EXECUTOR_ERROR_SM_MAIN_INVALID_TX_STATUS_ERROR": 117, } ) @@ -4932,7 +4936,7 @@ var file_executor_proto_rawDesc = []byte{ 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, 0xb9, 0x2b, 0x0a, 0x0d, 0x45, 0x78, 0x65, + 0x45, 0x53, 0x54, 0x41, 0x4d, 0x50, 0x10, 0x22, 0x2a, 0xed, 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, 0x1b, 0x0a, 0x17, 0x45, 0x58, @@ -5280,29 +5284,32 @@ var file_executor_proto_rawDesc = []byte{ 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, 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, + 0x45, 0x45, 0x10, 0x74, 0x12, 0x32, 0x0a, 0x2e, 0x45, 0x58, 0x45, 0x43, 0x55, 0x54, 0x4f, 0x52, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 0x5f, 0x53, 0x4d, 0x5f, 0x4d, 0x41, 0x49, 0x4e, 0x5f, 0x49, + 0x4e, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x5f, 0x54, 0x58, 0x5f, 0x53, 0x54, 0x41, 0x54, 0x55, 0x53, + 0x5f, 0x45, 0x52, 0x52, 0x4f, 0x52, 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, 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, + 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 f1c1bd80f3..2e1b9a744d 100644 --- a/state/runtime/runtime.go +++ b/state/runtime/runtime.go @@ -319,6 +319,8 @@ var ( ErrExecutorErrorInvalidDataStream = errors.New("invalid data stream") // ErrExecutorErrorInvalidUpdateMerkleTree indicates that the input parameter update merkle tree is invalid ErrExecutorErrorInvalidUpdateMerkleTree = errors.New("invalid update merkle tree") + // ErrExecutorErrorSMMainInvalidTxStatusError indicates that the TX has an invalid status-error combination + ErrExecutorErrorSMMainInvalidTxStatusError = errors.New("tx has an invalid status-error combination") // GRPC ERRORS // =========== diff --git a/state/test/forkid_dragonfruit/dragonfruit_test.go b/state/test/forkid_dragonfruit/dragonfruit_test.go index 64adbf042f..a7b1a5de80 100644 --- a/state/test/forkid_dragonfruit/dragonfruit_test.go +++ b/state/test/forkid_dragonfruit/dragonfruit_test.go @@ -1486,6 +1486,7 @@ func TestExecutorRevert(t *testing.T) { }) receipts := []*types.Receipt{receipt, receipt1} + imStateRoots := []common.Hash{common.BytesToHash(processBatchResponse.Responses[0].StateRoot), common.BytesToHash(processBatchResponse.Responses[1].StateRoot)} transactions := []*types.Transaction{signedTx0, signedTx1} @@ -1505,7 +1506,7 @@ func TestExecutorRevert(t *testing.T) { txsL2Hash[i] = common.HexToHash(fmt.Sprintf("0x%d", i)) } - err = testState.AddL2Block(ctx, 0, l2Block, receipts, txsL2Hash, storeTxsEGPData, dbTx) + err = testState.AddL2Block(ctx, 0, l2Block, receipts, txsL2Hash, storeTxsEGPData, imStateRoots, dbTx) require.NoError(t, err) l2Block, err = testState.GetL2BlockByHash(ctx, l2Block.Hash(), dbTx) require.NoError(t, err) diff --git a/state/test/forkid_independent/independent_test.go b/state/test/forkid_independent/independent_test.go index b24d0e3021..ef919d7ce3 100644 --- a/state/test/forkid_independent/independent_test.go +++ b/state/test/forkid_independent/independent_test.go @@ -643,6 +643,7 @@ func TestAddGetL2Block(t *testing.T) { transactions := []*types.Transaction{tx} receipts := []*types.Receipt{receipt} + imStateRoots := []common.Hash{state.ZeroHash} // Create block to be able to calculate its hash st := trie.NewStackTrie(nil) @@ -659,7 +660,7 @@ func TestAddGetL2Block(t *testing.T) { txsL2Hash[i] = common.HexToHash(fmt.Sprintf("0x%d", i)) } - err = testState.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, dbTx) + err = testState.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, imStateRoots, dbTx) require.NoError(t, err) result, err := testState.GetL2BlockByHash(ctx, l2Block.Hash(), dbTx) require.NoError(t, err) diff --git a/state/transaction.go b/state/transaction.go index 3af99b3f64..2847a5e428 100644 --- a/state/transaction.go +++ b/state/transaction.go @@ -117,6 +117,8 @@ func (s *State) StoreTransactions(ctx context.Context, batchNumber uint64, proce return ErrBatchAlreadyClosed } + forkID := s.GetForkIDByBatchNumber(batchNumber) + for _, processedBlock := range processedBlocks { processedTxs := processedBlock.TransactionResponses // check existing txs vs parameter txs @@ -167,11 +169,12 @@ func (s *State) StoreTransactions(ctx context.Context, batchNumber uint64, proce header.BlockInfoRoot = processedBlock.BlockInfoRoot transactions := []*types.Transaction{&processedTx.Tx} - receipt := GenerateReceipt(header.Number, processedTx, uint(i)) + receipt := GenerateReceipt(header.Number, processedTx, uint(i), forkID) if !CheckLogOrder(receipt.Logs) { return fmt.Errorf("error: logs received from executor are not in order") } receipts := []*types.Receipt{receipt} + imStateRoots := []common.Hash{processedTx.StateRoot} // Create l2Block to be able to calculate its hash st := trie.NewStackTrie(nil) @@ -187,7 +190,7 @@ func (s *State) StoreTransactions(ctx context.Context, batchNumber uint64, proce txsL2Hash := []common.Hash{processedTx.TxHashL2_V2} // Store L2 block and its transaction - if err := s.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, dbTx); err != nil { + if err := s.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, imStateRoots, dbTx); err != nil { return err } } @@ -209,8 +212,11 @@ func (s *State) StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *P return err } + forkID := s.GetForkIDByBatchNumber(batchNumber) + gasLimit := l2Block.GasLimit - if gasLimit > MaxL2BlockGasLimit { + // We check/set the maximum value of gasLimit for batches <= to ETROG fork. For batches >= to ELDERBERRY fork we use always the value returned by the executor + if forkID <= FORKID_ETROG && gasLimit > MaxL2BlockGasLimit { gasLimit = MaxL2BlockGasLimit } @@ -234,6 +240,8 @@ func (s *State) StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *P storeTxsEGPData := make([]StoreTxEGPData, 0, numTxs) receipts := make([]*types.Receipt, 0, numTxs) txsL2Hash := make([]common.Hash, 0, numTxs) + imStateRoots := make([]common.Hash, 0, numTxs) + var receipt *types.Receipt for i, txResponse := range l2Block.TransactionResponses { // if the transaction has an intrinsic invalid tx error it means @@ -256,8 +264,9 @@ func (s *State) StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *P storeTxsEGPData = append(storeTxsEGPData, storeTxEGPData) - receipt := GenerateReceipt(header.Number, txResponse, uint(i)) + receipt = GenerateReceipt(header.Number, txResponse, uint(i), forkID) receipts = append(receipts, receipt) + imStateRoots = append(imStateRoots, txResp.StateRoot) } // Create block to be able to calculate its hash @@ -270,7 +279,7 @@ func (s *State) StoreL2Block(ctx context.Context, batchNumber uint64, l2Block *P } // Store L2 block and its transactions - if err := s.AddL2Block(ctx, batchNumber, block, receipts, txsL2Hash, storeTxsEGPData, dbTx); err != nil { + if err := s.AddL2Block(ctx, batchNumber, block, receipts, txsL2Hash, storeTxsEGPData, imStateRoots, dbTx); err != nil { return err } @@ -642,6 +651,8 @@ func (s *State) StoreTransaction(ctx context.Context, batchNumber uint64, proces return nil, err } + forkID := s.GetForkIDByBatchNumber(batchNumber) + header := NewL2Header(&types.Header{ Number: new(big.Int).SetUint64(lastL2Block.Number().Uint64() + 1), ParentHash: lastL2Block.Hash(), @@ -655,8 +666,9 @@ func (s *State) StoreTransaction(ctx context.Context, batchNumber uint64, proces header.BlockInfoRoot = blockInfoRoot transactions := []*types.Transaction{&processedTx.Tx} - receipt := GenerateReceipt(header.Number, processedTx, 0) + receipt := GenerateReceipt(header.Number, processedTx, 0, forkID) receipts := []*types.Receipt{receipt} + imStateRoots := []common.Hash{processedTx.StateRoot} // Create l2Block to be able to calculate its hash st := trie.NewStackTrie(nil) @@ -669,7 +681,7 @@ func (s *State) StoreTransaction(ctx context.Context, batchNumber uint64, proces txsL2Hash := []common.Hash{processedTx.TxHashL2_V2} // Store L2 block and its transaction - if err := s.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, dbTx); err != nil { + if err := s.AddL2Block(ctx, batchNumber, l2Block, receipts, txsL2Hash, storeTxsEGPData, imStateRoots, dbTx); err != nil { return nil, err } diff --git a/state/types.go b/state/types.go index ea7a0ae289..6b76455a07 100644 --- a/state/types.go +++ b/state/types.go @@ -100,6 +100,8 @@ type ProcessTransactionResponse struct { GasLeft uint64 // GasUsed is the total gas used as result of execution or gas estimation GasUsed uint64 + // CumulativeGasUsed is the accumulated gas used (sum of tx GasUsed and CumulativeGasUsed of the previous tx in the L2 block) + CumulativeGasUsed uint64 // GasRefunded is the total gas refunded as result of execution GasRefunded uint64 // RomError represents any error encountered during the execution From 76cf00faaacceca02faafa6626f7377cd0205468 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Toni=20Ram=C3=ADrez?= <58293609+ToniRamirezM@users.noreply.github.com> Date: Fri, 8 Mar 2024 17:43:24 +0100 Subject: [PATCH 47/51] update prover to v5.0.6 (#3437) * remove intermediate state root from receipts after Etrog * use receipt state returned by executor instead of checking the RomError * use receipt status from executor only after Etrog * fix gasLimit and cumulativeGasUsed for Elderberry txs (#3428) * keep im state root in db (#3427) * generate receipt refactor (#3436) * generate receipt refactor * update prover image * downgrade prover image * update prover * adapt test * undo adapt test * upgrade prover --------- Co-authored-by: tclemos Co-authored-by: agnusmor <100322135+agnusmor@users.noreply.github.com> --- 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 70a519a031..102c693d11 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:v5.0.3 + image: hermeznetwork/zkevm-prover:v5.0.6 depends_on: zkevm-state-db: condition: service_healthy diff --git a/test/docker-compose.yml b/test/docker-compose.yml index 0768008245..74e91708fe 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:v5.0.3 + image: hermeznetwork/zkevm-prover:v5.0.6 ports: - 50061:50061 # MT - 50071:50071 # Executor @@ -602,7 +602,7 @@ services: zkevm-permissionless-prover: container_name: zkevm-permissionless-prover - image: hermeznetwork/zkevm-prover:v5.0.3 + image: hermeznetwork/zkevm-prover:v5.0.6 ports: # - 50058:50058 # Prover - 50059:50052 # Mock prover From b184e2b36c9f840d4f758c734c1161314f025b05 Mon Sep 17 00:00:00 2001 From: Thiago Coimbra Lemos Date: Mon, 11 Mar 2024 14:53:14 -0300 Subject: [PATCH 48/51] use empty byte array instead of all zeros for receipt poststate (#3449) --- jsonrpc/types/types.go | 2 +- state/helper.go | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/jsonrpc/types/types.go b/jsonrpc/types/types.go index ec50389564..b9c902cc1a 100644 --- a/jsonrpc/types/types.go +++ b/jsonrpc/types/types.go @@ -658,7 +658,7 @@ func NewReceipt(tx types.Transaction, r *types.Receipt, l2Hash *common.Hash) (Re Type: ArgUint64(r.Type), TxL2Hash: l2Hash, } - if common.BytesToHash(r.PostState).String() != state.ZeroHash.String() { + if len(r.PostState) > 0 { root := common.BytesToHash(r.PostState) receipt.Root = &root } diff --git a/state/helper.go b/state/helper.go index 4d074292bb..300ffcdc99 100644 --- a/state/helper.go +++ b/state/helper.go @@ -293,7 +293,7 @@ func GenerateReceipt(blockNumber *big.Int, processedTx *ProcessTransactionRespon receipt.PostState = processedTx.StateRoot.Bytes() receipt.CumulativeGasUsed = processedTx.GasUsed } else { - receipt.PostState = ZeroHash.Bytes() + receipt.PostState = []byte{} receipt.CumulativeGasUsed = processedTx.CumulativeGasUsed } if processedTx.EffectiveGasPrice != "" { From e809e0e61531b7aba398399216419db2207b3a92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Negovanovi=C4=87?= Date: Wed, 13 Mar 2024 07:07:59 +0100 Subject: [PATCH 49/51] Update diff --- docs/diff/diff.html | 29208 ++++++++++++++++++++++++++++++++++-------- 1 file changed, 23614 insertions(+), 5594 deletions(-) diff --git a/docs/diff/diff.html b/docs/diff/diff.html index bbc76c7d21..56a4623db4 100644 --- a/docs/diff/diff.html +++ b/docs/diff/diff.html @@ -2,7 +2,7 @@ - zkEVM node vs CDK validium node</br><h2>zkevm-node version: v0.6.0<h2/> + zkEVM node vs CDK validium node</br><h2>zkevm-node version: v0.6.2<h2/>