From 857ccf892e120407d1390fe97b7d296ad98e1100 Mon Sep 17 00:00:00 2001 From: StefanIliev545 Date: Wed, 7 Feb 2024 15:21:31 +0200 Subject: [PATCH] Fix for desync issue. --- go/enclave/components/batch_executor.go | 3 +++ go/enclave/evm/evm_facade.go | 14 ++++++++++++-- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/go/enclave/components/batch_executor.go b/go/enclave/components/batch_executor.go index 417dbe96ac..78a7b0d9bc 100644 --- a/go/enclave/components/batch_executor.go +++ b/go/enclave/components/batch_executor.go @@ -182,11 +182,14 @@ func (executor *batchExecutor) ComputeBatch(context *BatchExecutionContext, fail syntheticTransactions := append(xchainTxs, freeTransactions...) + // fromTxIndex - Here we start from the 0 index. This will be the same for a validator. successfulTxs, excludedTxs, txReceipts, err := executor.processTransactions(batch, 0, transactionsToProcess, stateDB, context.ChainConfig, false) if err != nil { return nil, fmt.Errorf("could not process transactions. Cause: %w", err) } + // fromTxIndex - Here we start from the len of the successful transactions; As long as we have the exact same successful transactions in a batch, + // we will start from the same place. ccSuccessfulTxs, _, ccReceipts, err := executor.processTransactions(batch, len(successfulTxs), syntheticTransactions, stateDB, context.ChainConfig, true) if err != nil { return nil, err diff --git a/go/enclave/evm/evm_facade.go b/go/enclave/evm/evm_facade.go index 1ca3bc0373..9fb06685e8 100644 --- a/go/enclave/evm/evm_facade.go +++ b/go/enclave/evm/evm_facade.go @@ -58,6 +58,14 @@ func ExecuteTransactions( } hash := header.Hash() + + // tCountRollback - every time a transaction errors out, rather than producing a receipt + // we push back the index in the "block" (batch) it will have. This means that errored out transactions + // will be shunted by their follow up successful transaction. + // This also means the mix digest can be the same for two transactions, but + // as the error one reverts and cant mutate the state in order to push back the counter + // this should not open up any attack vectors on the randomness. + tCountRollback := 0 for i, t := range txs { r, err := executeTransaction( s, @@ -68,11 +76,12 @@ func ExecuteTransactions( t, usedGas, vmCfg, - fromTxIndex+i, + (fromTxIndex+i)-tCountRollback, hash, header.Number.Uint64(), ) if err != nil { + tCountRollback++ result[t.Tx.Hash()] = err logger.Info("Failed to execute tx:", log.TxKey, t.Tx.Hash(), log.CtrErrKey, err) continue @@ -156,7 +165,8 @@ func executeTransaction( // Create a new context to be used in the EVM environment blockContext := gethcore.NewEVMBlockContext(header, bc, author) vmenv := vm.NewEVM(blockContext, vm.TxContext{BlobHashes: tx.Tx.BlobHashes()}, statedb, config, cfg) - receipt, err := applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx.Tx, usedGas, vmenv) + var receipt *types.Receipt + receipt, err = applyTransaction(msg, config, gp, statedb, header.Number, header.Hash(), tx.Tx, usedGas, vmenv) if err != nil { // If the transaction has l1 cost, then revert the funds exchange // as it will not be published on error (no receipt condition)