diff --git a/cmd/hack/hack.go b/cmd/hack/hack.go
index 10f7f0c523adfc691e7fe5d2522798c489eb42db..ee5921ff28fa916ac703908aa9f7a10edba8a606 100644
--- a/cmd/hack/hack.go
+++ b/cmd/hack/hack.go
@@ -21,7 +21,13 @@ import (
 
 	"github.com/RoaringBitmap/roaring/roaring64"
 	"github.com/holiman/uint256"
+	"github.com/ledgerwatch/erigon/consensus/ethash"
+	"github.com/ledgerwatch/erigon/consensus/misc"
+	"github.com/ledgerwatch/erigon/core"
+	"github.com/ledgerwatch/erigon/ethdb/cbor"
 	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
+	"github.com/ledgerwatch/erigon/migrations"
+	"github.com/ledgerwatch/erigon/params"
 	"github.com/wcharczuk/go-chart"
 	"github.com/wcharczuk/go-chart/util"
 
@@ -37,6 +43,7 @@ import (
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/core/types/accounts"
+	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/eth/stagedsync"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
 	"github.com/ledgerwatch/erigon/ethdb"
@@ -2071,26 +2078,121 @@ func scanTxs(chaindata string) error {
 func scanReceipts(chaindata string, block uint64) error {
 	dbdb := kv2.MustOpen(chaindata).RwKV()
 	defer dbdb.Close()
-	txtx, err := dbdb.BeginRw(context.Background())
+	tx, err := dbdb.BeginRw(context.Background())
 	if err != nil {
 		return err
 	}
-	defer txtx.Rollback()
-	var db ethdb.Database = kv2.WrapIntoTxDB(txtx)
-	var tx ethdb.Tx
-	if hasTx, ok := db.(ethdb.HasTx); ok {
-		tx = hasTx.Tx()
-	} else {
-		return fmt.Errorf("no transaction")
-	}
-	var key [8]byte
-	var v []byte
-	binary.BigEndian.PutUint64(key[:], block)
-	if v, err = tx.GetOne(dbutils.BlockReceiptsPrefix, key[:]); err != nil {
+	defer tx.Rollback()
+	genesisBlock, err := rawdb.ReadBlockByNumber(tx, 0)
+	if err != nil {
 		return err
 	}
-	fmt.Printf("blockNum = %d, receipt %x\n", block, v)
-	return nil
+	chainConfig, cerr := rawdb.ReadChainConfig(tx, genesisBlock.Hash())
+	if cerr != nil {
+		return cerr
+	}
+	vmConfig := vm.Config{}
+	noOpWriter := state.NewNoopWriter()
+	var buf bytes.Buffer
+	fixedCount := 0
+	logInterval := 30 * time.Second
+	logEvery := time.NewTicker(logInterval)
+	for blockNum := block; blockNum < block+100000; blockNum++ {
+		select {
+		default:
+		case <-logEvery.C:
+			log.Info("Commit", "block", blockNum, "fixed", fixedCount)
+			tx.Commit()
+			if tx, err = dbdb.BeginRw(context.Background()); err != nil {
+				return err
+			}
+		}
+		var hash common.Hash
+		if hash, err = rawdb.ReadCanonicalHash(tx, blockNum); err != nil {
+			return err
+		}
+		if hash == (common.Hash{}) {
+			break
+		}
+		var block *types.Block
+		var senders []common.Address
+		if block, senders, err = rawdb.ReadBlockWithSenders(tx, hash, blockNum); err != nil {
+			return err
+		}
+		receipts := rawdb.ReadReceipts(tx, block, senders)
+		for _, receipt := range receipts {
+			receipt.Bloom = types.CreateBloom(types.Receipts{receipt})
+		}
+		if chainConfig.IsByzantium(block.Number().Uint64()) {
+			receiptSha := types.DeriveSha(receipts)
+			if receiptSha == block.Header().ReceiptHash {
+				continue
+			}
+		}
+
+		dbstate := state.NewPlainKvState(tx, block.NumberU64()-1)
+		intraBlockState := state.New(dbstate)
+
+		getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(tx, hash, number) }
+		receipts1, err1 := runBlock(intraBlockState, noOpWriter, noOpWriter, chainConfig, getHeader, nil /* checkTEVM */, block, vmConfig)
+		if err1 != nil {
+			return err1
+		}
+		if chainConfig.IsByzantium(block.Number().Uint64()) {
+			receiptSha := types.DeriveSha(receipts1)
+			if receiptSha != block.Header().ReceiptHash {
+				fmt.Printf("(retrace) mismatched receipt headers for block %d: %x, %x\n", block.NumberU64(), receiptSha, block.Header().ReceiptHash)
+			} else {
+				// All good, we can fix receipt record
+				buf.Reset()
+				err := cbor.Marshal(&buf, receipts1)
+				if err != nil {
+					return fmt.Errorf("encode block receipts for block %d: %v", blockNum, err)
+				}
+				if err = tx.Put(dbutils.BlockReceiptsPrefix, dbutils.ReceiptsKey(blockNum), buf.Bytes()); err != nil {
+					return fmt.Errorf("writing receipts for block %d: %v", blockNum, err)
+				}
+				fixedCount++
+			}
+		}
+	}
+	return tx.Commit()
+}
+
+func runBlock(ibs *state.IntraBlockState, txnWriter state.StateWriter, blockWriter state.StateWriter,
+	chainConfig *params.ChainConfig, getHeader func(hash common.Hash, number uint64) *types.Header, checkTEVM func(common.Hash) (bool, error), block *types.Block, vmConfig vm.Config) (types.Receipts, error) {
+	header := block.Header()
+	vmConfig.TraceJumpDest = true
+	engine := ethash.NewFullFaker()
+	gp := new(core.GasPool).AddGas(block.GasLimit())
+	usedGas := new(uint64)
+	var receipts types.Receipts
+	if chainConfig.DAOForkSupport && chainConfig.DAOForkBlock != nil && chainConfig.DAOForkBlock.Cmp(block.Number()) == 0 {
+		misc.ApplyDAOHardFork(ibs)
+	}
+	for i, tx := range block.Transactions() {
+		ibs.Prepare(tx.Hash(), block.Hash(), i)
+		receipt, _, err := core.ApplyTransaction(chainConfig, getHeader, engine, nil, gp, ibs, txnWriter, header, tx, usedGas, vmConfig, checkTEVM)
+		if err != nil {
+			return nil, fmt.Errorf("could not apply tx %d [%x] failed: %v", i, tx.Hash(), err)
+		}
+		receipts = append(receipts, receipt)
+		//fmt.Printf("%d, cumulative gas: %d\n", i, receipt.CumulativeGasUsed)
+	}
+
+	if !vmConfig.ReadOnly {
+		// Finalize the block, applying any consensus engine specific extras (e.g. block rewards)
+		if _, err := engine.FinalizeAndAssemble(chainConfig, header, ibs, block.Transactions(), block.Uncles(), receipts, nil); err != nil {
+			return nil, fmt.Errorf("finalize of block %d failed: %v", block.NumberU64(), err)
+		}
+
+		ctx := chainConfig.WithEIPsFlags(context.Background(), header.Number.Uint64())
+		if err := ibs.CommitBlock(ctx, blockWriter); err != nil {
+			return nil, fmt.Errorf("committing block %d failed: %v", block.NumberU64(), err)
+		}
+	}
+
+	return receipts, nil
 }
 
 var txParseTests = []struct {
@@ -2139,6 +2241,43 @@ func testTxPool() error {
 	return nil
 }
 
+var receiptTests = []struct {
+	cborStr string
+}{
+	{cborStr: "98a08400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000084004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400000840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000008400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400000840040000184004000018400400001840040000084004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000008400400001840040000184004000018400400001840040000184004000018400400000840040000184004000018400400001840040000184004000008400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001840040000184004000018400400001"},
+	{cborStr: "98a08400f60119e8948400f6011a00028ffb8400f6011a0003777d8400f6011a000a19e18400f6011a000e662c8400f6011a000eb8348400f6011a000f8c3a8400f6011a001040638400f6011a0011374c8400f6011a0011b0d18400f6011a00140bba8400f6011a00145dc28400f6011a00197eab8400f6011a0019d0b38400f6011a001a69898400f6011a001b60728400f6011a001da1118400f6011a001e92a58400f6011a001f5c478400f6011a001fae4f8400f6011a002000578400f6011a0020525f8400f6011a0020a4678400f6011a0020f66f8400f6011a002148778400f6011a00219a7f8400f6011a0021ec878400f6011a00223e8f8400f6011a002290978400f6011a0022e29f8400f6011a00235c248400f6011a0023ae2c8400f6011a002400348400f6011a0024523c8400f6011a0024cbc18400f6011a00251dc98400f6011a00256fd18400f6011a0025c1d98400f6011a0027505d8400f6011a0027a2658400f6011a00282a038400f6011a002be66d8400f6011a003536528400f6011a0035885a8400f6011a0035da628400f6011a0038f4e88400f6011a003946f08400f6011a003b664f8400f6011a003e02188400f6001a003e54208400f6011a004101348400f6011a004417598400f6011a0046439c8400f6011a00470f098400f6011a00479e928400f6011a0047f09a8400f6011a004842a28400f6011a0048f91a8400f6011a00494b228400f6011a00499d2a8400f6011a004a34c88400f6011a004a86d08400f6011a004ad8d88400f6011a004b2ae08400f6011a004d40c38400f6011a004e37ac8400f6011a005220de8400f6011a006680b08400f6011a0068b65f8400f6011a006cada28400f6011a006e77bf8400f6011a007117398400f6011a0071b02a8400f6011a007b8b518400f6011a007c4c088400f6011a007c98b78400f6011a007ceabf8400f6011a0080e8bf8400f6001a008175678400f6011a0081c76f8400f6011a00867d0d8400f6011a0087312a8400f6011a00881e0e8400f6011a008ad2058400f6011a008b86bd8400f6011a008bd8c58400f6011a008c2acd8400f6011a008c7cd58400f6011a008ccedd8400f6011a008d84808400f6011a008dd6888400f6011a008e28908400f6011a008eb8bb8400f6011a00902b2d8400f6011a0091b4508400f6001a0092b8098400f6011a00930a118400f6011a00935c198400f6011a0093ae218400f6011a009400298400f6011a00991f568400f6011a009a97b58400f6011a009ae9bd8400f6011a009b9ed78400f6011a009f69cf8400f6011a00a1364d8400f6011a00a188558400f6011a00a355a28400f6011a00a614ca8400f6011a00a6f05d8400f6011a00a7af5e8400f6011a00aaa96f8400f6011a00acd7898400f6011a00ae6c558400f6011a00b2a59f8400f6011a00b63dc68400f6011a00b8d7bb8400f6001a00b9591b8400f6011a00b9d0528400f6011a00ba22918400f6011a00ba74998400f6001a00baefa68400f6011a00bb41ae8400f6011a00bb93b68400f6011a00bc68e28400f6011a00bcbaea8400f6011a00bd0cf28400f6011a00bd5efa8400f6011a00bdb1028400f6011a00be030a8400f6011a00c1caed8400f6011a00c21cf58400f6011a00c26efd8400f6011a00c2c1058400f6001a00c33c008400f6011a00c3a63b8400f6011a00c585798400f6011a00c70f258400f6011a00c7612d8400f6011a00c98d4c8400f6011a00cb71988400f6001a00cbec998400f6011a00cfe49f8400f6011a00d1c6868400f6011a00d3a86d8400f6011a00d4671a8400f6001a00d4e2f08400f6011a00d6aca68400f6011a00d6feae8400f6011a00d750b68400f6011a00d80d078400f6011a00d85f0f8400f6011a00d915308400f6011a00dbc9d08400f6011a00ddcb408400f6011a00dfad278400f6011a00dfff2f8400f6011a00e272e38400f6011a00e4333c8400f6011a00e4c2c5"},
+}
+
+func testReceipts() error {
+	for i, tt := range receiptTests {
+		var cborBytes []byte
+		var err error
+		if cborBytes, err = hex.DecodeString(tt.cborStr); err != nil {
+			return err
+		}
+		var receipts types.Receipts
+		if err := cbor.Unmarshal(&receipts, bytes.NewReader(cborBytes)); err != nil {
+			log.Error("receipt unmarshal failed", "err", err)
+			return nil
+		}
+		fmt.Printf("%d: Number of receipts: %d\n", i, len(receipts))
+		for j, receipt := range receipts {
+			fmt.Printf("%d) type: %d, postState: %x, status: %d, cumulative gas: %d\n", j, receipt.Type, receipt.PostState, receipt.Status, receipt.CumulativeGasUsed)
+		}
+		var oldReceipts migrations.OldReceipts
+		reader := bytes.NewReader(cborBytes)
+		if err = cbor.Unmarshal(&oldReceipts, reader); err != nil {
+			fmt.Printf("Error parsing as old: %v\n", err)
+		} else {
+			fmt.Printf("Unread portion: %d\n", reader.Len())
+			for j, receipt := range oldReceipts {
+				fmt.Printf("old-%d) postState: %x, status: %d, cumulative gas: %d\n", j, receipt.PostState, receipt.Status, receipt.CumulativeGasUsed)
+			}
+		}
+	}
+	return nil
+}
+
 func main() {
 	flag.Parse()
 
@@ -2301,6 +2440,9 @@ func main() {
 
 	case "testTxPool":
 		err = testTxPool()
+
+	case "testReceipts":
+		err = testReceipts()
 	}
 
 	if err != nil {
diff --git a/cmd/rpcdaemon/commands/tracing.go b/cmd/rpcdaemon/commands/tracing.go
index 7bc99bee546a97cdb5fda913dd21ee8d6e857aa3..5d4634b86d284013f2f90a5d7ede210855b79e53 100644
--- a/cmd/rpcdaemon/commands/tracing.go
+++ b/cmd/rpcdaemon/commands/tracing.go
@@ -11,7 +11,6 @@ import (
 	"github.com/ledgerwatch/erigon/core/state"
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/eth/tracers"
-	"github.com/ledgerwatch/erigon/ethdb"
 	"github.com/ledgerwatch/erigon/internal/ethapi"
 	"github.com/ledgerwatch/erigon/rpc"
 	"github.com/ledgerwatch/erigon/turbo/rpchelper"
@@ -50,8 +49,7 @@ func (api *PrivateDebugAPIImpl) TraceTransaction(ctx context.Context, hash commo
 	getHeader := func(hash common.Hash, number uint64) *types.Header {
 		return rawdb.ReadHeader(tx, hash, number)
 	}
-	checkTEVM := ethdb.GetCheckTEVM(tx)
-	msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, checkTEVM, ethash.NewFaker(), tx, blockHash, txIndex)
+	msg, blockCtx, txCtx, ibs, _, err := transactions.ComputeTxEnv(ctx, block, chainConfig, getHeader, nil /* checkTEVM */, ethash.NewFaker(), tx, blockHash, txIndex)
 	if err != nil {
 		stream.WriteNil()
 		return err
diff --git a/cmd/rpctest/main.go b/cmd/rpctest/main.go
index dcc16a57f36a0afc4933967301d1fe5b07182556..97c4f4e0d5e14e501bd8c3752d7ddaaf6cfe0db5 100644
--- a/cmd/rpctest/main.go
+++ b/cmd/rpctest/main.go
@@ -134,18 +134,15 @@ func main() {
 	}
 	with(bench9Cmd, withErigonUrl, withGethUrl, withNeedCompare)
 
-	var bench10Cmd = &cobra.Command{
-		Use:   "bench10",
+	var benchTraceTransactionCmd = &cobra.Command{
+		Use:   "benchTraceTransaction",
 		Short: "",
 		Long:  ``,
 		Run: func(cmd *cobra.Command, args []string) {
-			err := rpctest.Bench10(erigonURL, gethURL, blockFrom, blockTo, recordFile)
-			if err != nil {
-				log.Error("bench 10 err", "err", err)
-			}
+			rpctest.BenchTraceTransaction(erigonURL, gethURL, needCompare, blockFrom, blockTo, recordFile)
 		},
 	}
-	with(bench10Cmd, withGethUrl, withErigonUrl, withBlockNum, withRecord)
+	with(benchTraceTransactionCmd, withGethUrl, withErigonUrl, withNeedCompare, withBlockNum, withRecord)
 
 	var bench11Cmd = &cobra.Command{
 		Use:   "bench11",
@@ -248,7 +245,7 @@ func main() {
 		bench7Cmd,
 		bench8Cmd,
 		bench9Cmd,
-		bench10Cmd,
+		benchTraceTransactionCmd,
 		bench11Cmd,
 		bench12Cmd,
 		bench13Cmd,
diff --git a/cmd/rpctest/rpctest/bench10.go b/cmd/rpctest/rpctest/bench10.go
deleted file mode 100644
index 991e87f2c0d57869b03eb82f2134c7e8f6432433..0000000000000000000000000000000000000000
--- a/cmd/rpctest/rpctest/bench10.go
+++ /dev/null
@@ -1,63 +0,0 @@
-package rpctest
-
-import (
-	"fmt"
-	"net/http"
-	"time"
-)
-
-func Bench10(erigonUrl, gethUrl string, blockFrom uint64, blockTo uint64, recordFile string) error {
-	setRoutes(erigonUrl, gethUrl)
-	var client = &http.Client{
-		Timeout: time.Second * 600,
-	}
-
-	var res CallResult
-	reqGen := &RequestGenerator{
-		client: client,
-	}
-
-	reqGen.reqID++
-
-	for bn := blockFrom; bn < blockTo; bn++ {
-		var b EthBlockByNumber
-		res = reqGen.Erigon("eth_getBlockByNumber", reqGen.getBlockByNumber(bn), &b)
-		if res.Err != nil {
-			return fmt.Errorf("retrieve block (Erigon) %d: %v", blockFrom, res.Err)
-		}
-		if b.Error != nil {
-			return fmt.Errorf("retrieving block (Erigon): %d %s", b.Error.Code, b.Error.Message)
-		}
-		for _, tx := range b.Result.Transactions {
-			reqGen.reqID++
-
-			var trace EthTxTrace
-			res = reqGen.Erigon("debug_traceTransaction", reqGen.traceTransaction(tx.Hash), &trace)
-			if res.Err != nil {
-				fmt.Printf("Could not trace transaction (Erigon) %s: %v\n", tx.Hash, res.Err)
-				print(client, routes[Erigon], reqGen.traceTransaction(tx.Hash))
-			}
-
-			if trace.Error != nil {
-				fmt.Printf("Error tracing transaction (Erigon): %d %s\n", trace.Error.Code, trace.Error.Message)
-			}
-
-			var traceg EthTxTrace
-			res = reqGen.Geth("debug_traceTransaction", reqGen.traceTransaction(tx.Hash), &traceg)
-			if res.Err != nil {
-				print(client, routes[Geth], reqGen.traceTransaction(tx.Hash))
-				return fmt.Errorf("trace transaction (geth) %s: %v", tx.Hash, res.Err)
-			}
-			if traceg.Error != nil {
-				return fmt.Errorf("tracing transaction (geth): %d %s", traceg.Error.Code, traceg.Error.Message)
-			}
-			if res.Err == nil && trace.Error == nil {
-				if !compareTraces(&trace, &traceg) {
-					return fmt.Errorf("different traces block %d, tx %s", blockFrom, tx.Hash)
-				}
-			}
-			reqGen.reqID++
-		}
-	}
-	return nil
-}
diff --git a/cmd/rpctest/rpctest/bench_tracetransaction.go b/cmd/rpctest/rpctest/bench_tracetransaction.go
new file mode 100644
index 0000000000000000000000000000000000000000..0703911f7e3f7a814602c7426f31dc283165ee93
--- /dev/null
+++ b/cmd/rpctest/rpctest/bench_tracetransaction.go
@@ -0,0 +1,87 @@
+package rpctest
+
+import (
+	"bufio"
+	"fmt"
+	"net/http"
+	"os"
+	"time"
+)
+
+func BenchTraceTransaction(erigonUrl, gethUrl string, needCompare bool, blockFrom uint64, blockTo uint64, recordFile string) {
+	setRoutes(erigonUrl, gethUrl)
+	var client = &http.Client{
+		Timeout: time.Second * 600,
+	}
+
+	var rec *bufio.Writer
+	if recordFile != "" {
+		f, err := os.Create(recordFile)
+		if err != nil {
+			fmt.Printf("Cannot create file %s for recording: %v\n", recordFile, err)
+			return
+		}
+		defer f.Close()
+		rec = bufio.NewWriter(f)
+		defer rec.Flush()
+	}
+
+	var res CallResult
+	reqGen := &RequestGenerator{
+		client: client,
+	}
+
+	reqGen.reqID++
+
+	for bn := blockFrom; bn < blockTo; bn++ {
+		var b EthBlockByNumber
+		res = reqGen.Erigon("eth_getBlockByNumber", reqGen.getBlockByNumber(bn), &b)
+		if res.Err != nil {
+			fmt.Printf("retrieve block (Erigon) %d: %v", blockFrom, res.Err)
+			return
+		}
+		if b.Error != nil {
+			fmt.Printf("retrieving block (Erigon): %d %s", b.Error.Code, b.Error.Message)
+			return
+		}
+		for _, tx := range b.Result.Transactions {
+			reqGen.reqID++
+
+			request := reqGen.traceTransaction(tx.Hash)
+			recording := rec != nil // This flag will be set to false if recording is not to be performed
+			res = reqGen.Erigon2("debug_traceTransaction", request)
+
+			if res.Err != nil {
+				fmt.Printf("Could not trace transaction (Erigon) %s: %v\n", tx.Hash, res.Err)
+				return
+			}
+			if errVal := res.Result.Get("error"); errVal != nil {
+				fmt.Printf("Error tracing transaction (Erigon): %d %s\n", errVal.GetInt("code"), errVal.GetStringBytes("message"))
+				return
+			}
+
+			if needCompare {
+				resg := reqGen.Geth2("debug_traceTransaction", request)
+				if resg.Err != nil {
+					fmt.Printf("Could not trace transaction (geth) %s: %v\n", tx.Hash, res.Err)
+					return
+				}
+				if errVal := resg.Result.Get("error"); errVal != nil {
+					fmt.Printf("Error tracing transaction (geth): %d %s\n", errVal.GetInt("code"), errVal.GetStringBytes("message"))
+					return
+				}
+				if resg.Err == nil && resg.Result.Get("error") == nil {
+					if err := compareResults(res.Result, resg.Result); err != nil {
+						fmt.Printf("Different traceTransaction block %d, tx %s: %v\n", bn, tx.Hash, err)
+						fmt.Printf("\n\nTG response=================================\n%s\n", res.Response)
+						fmt.Printf("\n\nG response=================================\n%s\n", resg.Response)
+						return
+					}
+				}
+			}
+			if recording {
+				fmt.Fprintf(rec, "%s\n%s\n\n", request, res.Response)
+			}
+		}
+	}
+}
diff --git a/cmd/state/commands/check_change_sets.go b/cmd/state/commands/check_change_sets.go
index bd2bac4b15b0c784c0d4b3f73a40e47568b840bb..229fd99317f7b60818f750f8ae11d0a7d131080d 100644
--- a/cmd/state/commands/check_change_sets.go
+++ b/cmd/state/commands/check_change_sets.go
@@ -19,7 +19,6 @@ import (
 	"github.com/ledgerwatch/erigon/core/types"
 	"github.com/ledgerwatch/erigon/core/vm"
 	"github.com/ledgerwatch/erigon/eth/stagedsync/stages"
-	"github.com/ledgerwatch/erigon/ethdb"
 	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
 	"github.com/ledgerwatch/erigon/log"
 	"github.com/spf13/cobra"
@@ -137,8 +136,7 @@ func CheckChangeSets(genesis *core.Genesis, blockNum uint64, chaindata string, h
 		}
 
 		getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(rwtx, hash, number) }
-		checkTEVM := ethdb.GetCheckTEVM(rwtx)
-		receipts, err1 := runBlock(intraBlockState, noOpWriter, blockWriter, chainConfig, getHeader, checkTEVM, block, vmConfig)
+		receipts, err1 := runBlock(intraBlockState, noOpWriter, blockWriter, chainConfig, getHeader, nil /* checkTEVM */, block, vmConfig)
 		if err1 != nil {
 			return err1
 		}
diff --git a/cmd/state/commands/opcode_tracer.go b/cmd/state/commands/opcode_tracer.go
index 484b14afca196aae1b6694f9619ed602e2da797d..6c121ad435d8ed0803c82aa11caacd4ac0ce5cfe 100644
--- a/cmd/state/commands/opcode_tracer.go
+++ b/cmd/state/commands/opcode_tracer.go
@@ -393,10 +393,10 @@ func OpcodeTracer(genesis *core.Genesis, blockNum uint64, chaindata string, numB
 
 	ot := NewOpcodeTracer(blockNum, saveOpcodes, saveBblocks)
 
-	chainDb := kv.MustOpen(chaindata)
+	chainDb := kv.MustOpen(chaindata).RwKV()
 	defer chainDb.Close()
 	historyDb := chainDb
-	historyTx, err1 := historyDb.Begin(context.Background(), ethdb.RO)
+	historyTx, err1 := historyDb.BeginRo(context.Background())
 	if err1 != nil {
 		return err1
 	}
@@ -526,7 +526,7 @@ func OpcodeTracer(genesis *core.Genesis, blockNum uint64, chaindata string, numB
 	blockNumLastReport := blockNum
 	for !interrupt {
 		var block *types.Block
-		if err := chainDb.RwKV().View(context.Background(), func(tx ethdb.Tx) (err error) {
+		if err := chainDb.View(context.Background(), func(tx ethdb.Tx) (err error) {
 			block, err = rawdb.ReadBlockByNumber(tx, blockNum)
 			return err
 		}); err != nil {
@@ -544,13 +544,12 @@ func OpcodeTracer(genesis *core.Genesis, blockNum uint64, chaindata string, numB
 			ot.fsumWriter = bufio.NewWriter(fsum)
 		}
 
-		dbstate := state.NewPlainDBState(historyTx, block.NumberU64()-1)
+		dbstate := state.NewPlainKvState(historyTx, block.NumberU64()-1)
 		intraBlockState := state.New(dbstate)
 		intraBlockState.SetTracer(ot)
 
-		getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(chainDb, hash, number) }
-		checkTEVM := ethdb.GetCheckTEVM(chainDb)
-		receipts, err1 := runBlock(intraBlockState, noOpWriter, noOpWriter, chainConfig, getHeader, checkTEVM, block, vmConfig)
+		getHeader := func(hash common.Hash, number uint64) *types.Header { return rawdb.ReadHeader(historyTx, hash, number) }
+		receipts, err1 := runBlock(intraBlockState, noOpWriter, noOpWriter, chainConfig, getHeader, nil /* checkTEVM */, block, vmConfig)
 		if err1 != nil {
 			return err1
 		}
diff --git a/turbo/transactions/tracing.go b/turbo/transactions/tracing.go
index 1ccc0da5979e56ac71afee46f58d64963c824cf7..de13b22c4d69922929c23b0bee6a112fb57debe4 100644
--- a/turbo/transactions/tracing.go
+++ b/turbo/transactions/tracing.go
@@ -5,6 +5,7 @@ import (
 	"errors"
 	"fmt"
 	"math/big"
+	"sort"
 	"time"
 
 	"github.com/holiman/uint256"
@@ -157,8 +158,13 @@ func TraceTx(
 		stream.WriteObjectField("failed")
 		stream.WriteBool(result.Failed())
 		stream.WriteMore()
+		// If the result contains a revert reason, return it.
+		returnVal := fmt.Sprintf("%x", result.Return())
+		if len(result.Revert()) > 0 {
+			returnVal = fmt.Sprintf("%x", result.Revert())
+		}
 		stream.WriteObjectField("returnValue")
-		stream.WriteString(fmt.Sprintf("%x", result.Return()))
+		stream.WriteString(returnVal)
 		stream.WriteObjectEnd()
 	} else {
 		if r, err1 := tracer.(*tracers.Tracer).GetResult(); err1 == nil {
@@ -181,10 +187,11 @@ type JsonStreamLogger struct {
 	stream       *jsoniter.Stream
 	firstCapture bool
 
-	storage map[common.Address]vm.Storage
-	logs    []vm.StructLog
-	output  []byte //nolint
-	err     error  //nolint
+	locations common.Hashes // For sorting
+	storage   map[common.Address]vm.Storage
+	logs      []vm.StructLog
+	output    []byte //nolint
+	err       error  //nolint
 }
 
 // NewStructLogger returns a new logger
@@ -299,14 +306,24 @@ func (l *JsonStreamLogger) CaptureState(env *vm.EVM, pc uint64, op vm.OpCode, ga
 		l.stream.WriteObjectField("storage")
 		l.stream.WriteObjectStart()
 		first := true
-		for i, storageValue := range l.storage[contract.Address()] {
+		// Sort storage by locations for easier comparison with geth
+		if l.locations != nil {
+			l.locations = l.locations[:0]
+		}
+		s := l.storage[contract.Address()]
+		for loc := range s {
+			l.locations = append(l.locations, loc)
+		}
+		sort.Sort(l.locations)
+		for _, loc := range l.locations {
+			value := s[loc]
 			if first {
 				first = false
 			} else {
 				l.stream.WriteMore()
 			}
-			l.stream.WriteObjectField(fmt.Sprintf("%x", i))
-			l.stream.WriteString(fmt.Sprintf("%x", storageValue))
+			l.stream.WriteObjectField(fmt.Sprintf("%x", loc))
+			l.stream.WriteString(fmt.Sprintf("%x", value))
 		}
 		l.stream.WriteObjectEnd()
 	}