diff --git a/cmd/hack/hack.go b/cmd/hack/hack.go
index 397e50912918a2994472becdd0da35228ccb43ac..b4bc603154d50e0a65ccd78ebaf046404a15fe86 100644
--- a/cmd/hack/hack.go
+++ b/cmd/hack/hack.go
@@ -21,9 +21,7 @@ import (
 
 	"github.com/RoaringBitmap/roaring/roaring64"
 	"github.com/holiman/uint256"
-	"github.com/ledgerwatch/erigon/ethdb/cbor"
 	kv2 "github.com/ledgerwatch/erigon/ethdb/kv"
-	"github.com/ledgerwatch/erigon/migrations"
 	"github.com/wcharczuk/go-chart"
 	"github.com/wcharczuk/go-chart/util"
 
@@ -2070,7 +2068,7 @@ func scanTxs(chaindata string) error {
 	return nil
 }
 
-func scanReceipts(chaindata string) error {
+func scanReceipts(chaindata string, block uint64) error {
 	dbdb := kv2.MustOpen(chaindata).RwKV()
 	defer dbdb.Close()
 	txtx, err := dbdb.BeginRw(context.Background())
@@ -2085,70 +2083,13 @@ func scanReceipts(chaindata string) error {
 	} else {
 		return fmt.Errorf("no transaction")
 	}
-	genesisBlock, err := rawdb.ReadBlockByNumber(tx, 0)
-	if err != nil {
-		return err
-	}
-	chainConfig, cerr := rawdb.ReadChainConfig(tx, genesisBlock.Hash())
-	if cerr != nil {
-		return cerr
-	}
-	logInterval := 30 * time.Second
-	logEvery := time.NewTicker(logInterval)
-	defer logEvery.Stop()
-	var buf bytes.Buffer
 	var key [8]byte
 	var v []byte
-	var to uint64
-	if to, err = stages.GetStageProgress(tx, stages.Execution); err != nil {
+	binary.BigEndian.PutUint64(key[:], block)
+	if v, err = tx.GetOne(dbutils.BlockReceiptsPrefix, key[:]); err != nil {
 		return err
 	}
-	for blockNum := uint64(1); blockNum <= to; blockNum++ {
-		binary.BigEndian.PutUint64(key[:], blockNum)
-		if v, err = tx.GetOne(dbutils.BlockReceiptsPrefix, key[:]); err != nil {
-			return err
-		}
-		if v == nil {
-			continue
-		}
-		//fmt.Printf("blockNum = %d\n", blockNum)
-		select {
-		default:
-		case <-logEvery.C:
-			log.Info("Scanned receipts up to", "block", blockNum)
-		}
-		var receipts types.Receipts
-		var oldReceipts migrations.OldReceipts
-		if err = cbor.Unmarshal(&oldReceipts, bytes.NewReader(v)); err != nil {
-			continue
-		}
-
-		var blockHash common.Hash
-		if blockHash, err = rawdb.ReadCanonicalHash(tx, blockNum); err != nil {
-			return err
-		}
-		var body *types.Body
-		if chainConfig.IsBerlin(blockNum) {
-			body = rawdb.ReadBody(tx, blockHash, blockNum)
-		}
-		receipts = make(types.Receipts, len(oldReceipts))
-		for i, oldReceipt := range oldReceipts {
-			receipts[i] = new(types.Receipt)
-			receipts[i].PostState = oldReceipt.PostState
-			receipts[i].Status = oldReceipt.Status
-			receipts[i].CumulativeGasUsed = oldReceipt.CumulativeGasUsed
-			if body != nil {
-				receipts[i].Type = body.Transactions[i].Type()
-			}
-		}
-		buf.Reset()
-		if err = cbor.Marshal(&buf, receipts); err != nil {
-			return err
-		}
-		//if err = tx.Put(dbutils.BlockReceiptsPrefix, common.CopyBytes(key[:]), common.CopyBytes(buf.Bytes())); err != nil {
-		//	return err
-		//}
-	}
+	fmt.Printf("blockNum = %d, receipt %x\n", block, v)
 	return nil
 }
 
@@ -2356,7 +2297,7 @@ func main() {
 		err = scanTxs(*chaindata)
 
 	case "scanReceipts":
-		err = scanReceipts(*chaindata)
+		err = scanReceipts(*chaindata, uint64(*block))
 
 	case "testTxPool":
 		err = testTxPool()
diff --git a/cmd/rpcdaemon/commands/eth_receipts.go b/cmd/rpcdaemon/commands/eth_receipts.go
index fd116abbe05bd6b40a42dbcd25dd2db05a627930..30ee9f9189c626d72846383c05f8429a973b1c85 100644
--- a/cmd/rpcdaemon/commands/eth_receipts.go
+++ b/cmd/rpcdaemon/commands/eth_receipts.go
@@ -5,9 +5,10 @@ import (
 	"context"
 	"encoding/binary"
 	"fmt"
-	"github.com/holiman/uint256"
 	"math/big"
 
+	"github.com/holiman/uint256"
+
 	"github.com/RoaringBitmap/roaring"
 	"github.com/ledgerwatch/erigon/common"
 	"github.com/ledgerwatch/erigon/common/dbutils"
@@ -53,6 +54,7 @@ func getReceipts(ctx context.Context, tx ethdb.Tx, chainConfig *params.ChainConf
 		if err != nil {
 			return nil, err
 		}
+		receipt.BlockHash = block.Hash()
 		receipts = append(receipts, receipt)
 	}
 
diff --git a/cmd/rpctest/main.go b/cmd/rpctest/main.go
index e9e46bb0dc47c36afa9eaddd51a0bf3cae11d191..dcc16a57f36a0afc4933967301d1fe5b07182556 100644
--- a/cmd/rpctest/main.go
+++ b/cmd/rpctest/main.go
@@ -22,7 +22,6 @@ func main() {
 		erigonURL   string
 		blockFrom   uint64
 		blockTo     uint64
-		chaindata   string
 		recordFile  string
 	)
 	withErigonUrl := func(cmd *cobra.Command) {
@@ -198,27 +197,15 @@ func main() {
 	}
 	with(benchTraceFilterCmd, withGethUrl, withErigonUrl, withNeedCompare, withBlockNum, withRecord)
 
-	var proofsCmd = &cobra.Command{
-		Use:   "proofs",
+	var benchTxReceiptCmd = &cobra.Command{
+		Use:   "benchTxReceipt",
 		Short: "",
 		Long:  ``,
 		Run: func(cmd *cobra.Command, args []string) {
-			rpctest.Proofs(chaindata, gethURL, blockFrom)
+			rpctest.BenchTxReceipt(erigonURL, gethURL, needCompare, blockFrom, blockTo, recordFile)
 		},
 	}
-	proofsCmd.Flags().StringVar(&chaindata, "chaindata", "", "")
-	with(proofsCmd, withGethUrl, withBlockNum)
-
-	var fixStateCmd = &cobra.Command{
-		Use:   "fixstate",
-		Short: "",
-		Long:  ``,
-		Run: func(cmd *cobra.Command, args []string) {
-			rpctest.FixState(chaindata, gethURL)
-		},
-	}
-	fixStateCmd.Flags().StringVar(&chaindata, "chaindata", "", "")
-	with(fixStateCmd, withGethUrl)
+	with(benchTxReceiptCmd, withGethUrl, withErigonUrl, withNeedCompare, withBlockNum, withRecord)
 
 	var replayCmd = &cobra.Command{
 		Use:   "replay",
@@ -267,8 +254,7 @@ func main() {
 		bench13Cmd,
 		benchTraceBlockCmd,
 		benchTraceFilterCmd,
-		proofsCmd,
-		fixStateCmd,
+		benchTxReceiptCmd,
 		compareAccountRange,
 		replayCmd,
 	)
diff --git a/cmd/rpctest/rpctest/bench_txreceipts.go b/cmd/rpctest/rpctest/bench_txreceipts.go
new file mode 100644
index 0000000000000000000000000000000000000000..da47a90fd740f4c7baf511c6ef981a5e7ab9f4dc
--- /dev/null
+++ b/cmd/rpctest/rpctest/bench_txreceipts.go
@@ -0,0 +1,121 @@
+package rpctest
+
+import (
+	"bufio"
+	"fmt"
+	"net/http"
+	"os"
+	"time"
+)
+
+// benchTxReceipt compares response of Erigon with Geth
+// but also can be used for comparing RPCDaemon with Geth
+// parameters:
+// needCompare - if false - doesn't call Erigon and doesn't compare responses
+// 		use false value - to generate vegeta files, it's faster but we can generate vegeta files for Geth and Erigon
+func BenchTxReceipt(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++
+	var blockNumber EthBlockNumber
+	res = reqGen.Erigon("eth_blockNumber", reqGen.blockNumber(), &blockNumber)
+	if res.Err != nil {
+		fmt.Printf("Could not get block number: %v\n", res.Err)
+		return
+	}
+	if blockNumber.Error != nil {
+		fmt.Printf("Error getting block number: %d %s\n", blockNumber.Error.Code, blockNumber.Error.Message)
+		return
+	}
+	fmt.Printf("Last block: %d\n", blockNumber.Number)
+	for bn := blockFrom; bn <= blockTo; bn++ {
+		reqGen.reqID++
+		var b EthBlockByNumber
+		res = reqGen.Erigon("eth_getBlockByNumber", reqGen.getBlockByNumber(bn), &b)
+		if res.Err != nil {
+			fmt.Printf("Could not retrieve block (Erigon) %d: %v\n", bn, res.Err)
+			return
+		}
+
+		if b.Error != nil {
+			fmt.Printf("Error retrieving block (Erigon): %d %s\n", b.Error.Code, b.Error.Message)
+			return
+		}
+
+		if needCompare {
+			var bg EthBlockByNumber
+			res = reqGen.Geth("eth_getBlockByNumber", reqGen.getBlockByNumber(bn), &bg)
+			if res.Err != nil {
+				fmt.Printf("Could not retrieve block (geth) %d: %v\n", bn, res.Err)
+				return
+			}
+			if bg.Error != nil {
+				fmt.Printf("Error retrieving block (geth): %d %s\n", bg.Error.Code, bg.Error.Message)
+				return
+			}
+			if !compareBlocks(&b, &bg) {
+				fmt.Printf("Block difference for %d\n", bn)
+				return
+			}
+		}
+
+		for _, tx := range b.Result.Transactions {
+			reqGen.reqID++
+
+			request := reqGen.getTransactionReceipt(tx.Hash)
+			recording := rec != nil // This flag will be set to false if recording is not to be performed
+			res = reqGen.Erigon2("eth_getTransactionReceipt", request)
+			if res.Err != nil {
+				fmt.Printf("Could not eth getTransactionReceipt (Erigon) %d: %v\n", bn, res.Err)
+				return
+			}
+			if errVal := res.Result.Get("error"); errVal != nil {
+				fmt.Printf("Error eth getTransactionReceipt (Erigon): %d %s\n", errVal.GetInt("code"), errVal.GetStringBytes("message"))
+				return
+			}
+
+			if needCompare {
+				resg := reqGen.Geth2("eth_getTransactionReceipt", request)
+				if resg.Err != nil {
+					fmt.Printf("Could not eth getTransactionReceipt (geth) %d: %v\n", bn, resg.Err)
+					return
+				}
+				if errVal := resg.Result.Get("error"); errVal != nil {
+					fmt.Printf("Error eth getTransactionReceipt (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 getTransactionReceipt 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/rpctest/rpctest/fixState.go b/cmd/rpctest/rpctest/fixState.go
deleted file mode 100644
index 3000ecdb8b115aeefb8c6c34b6d0b03555235e7c..0000000000000000000000000000000000000000
--- a/cmd/rpctest/rpctest/fixState.go
+++ /dev/null
@@ -1,135 +0,0 @@
-package rpctest
-
-import (
-	"bytes"
-	"context"
-	"encoding/binary"
-	"fmt"
-	"net/http"
-	"time"
-
-	"github.com/ledgerwatch/erigon/common"
-	"github.com/ledgerwatch/erigon/common/dbutils"
-	"github.com/ledgerwatch/erigon/core/rawdb"
-	"github.com/ledgerwatch/erigon/core/state"
-	"github.com/ledgerwatch/erigon/core/types/accounts"
-	"github.com/ledgerwatch/erigon/ethdb"
-	"github.com/ledgerwatch/erigon/ethdb/kv"
-	"github.com/ledgerwatch/erigon/turbo/trie"
-)
-
-func FixState(chaindata string, url string) {
-	db := kv.MustOpen(chaindata).RwKV()
-	defer db.Close()
-	tx, err1 := db.BeginRw(context.Background())
-	if err1 != nil {
-		panic(err1)
-	}
-	defer tx.Rollback()
-	currentHeader := rawdb.ReadCurrentHeader(tx)
-	blockNum := currentHeader.Number.Uint64()
-	blockHash := currentHeader.Hash()
-	fmt.Printf("Block number: %d\n", blockNum)
-	fmt.Printf("Block root hash: %x\n", currentHeader.Root)
-	reqID := 0
-	roots := make(map[common.Address]*accounts.Account)
-	var client = &http.Client{
-		Timeout: time.Second * 600,
-	}
-
-	c, err := tx.Cursor(dbutils.PlainStateBucket)
-	if err != nil {
-		panic(err)
-	}
-	defer c.Close()
-	if err := ethdb.ForEach(c, func(k, v []byte) (bool, error) {
-		if len(k) == common.AddressLength {
-			var address common.Address
-			address.SetBytes(k)
-			if _, ok := roots[address]; !ok {
-				if account, err2 := state.NewPlainStateReader(tx).ReadAccountData(address); err2 != nil {
-					return false, err2
-				} else {
-					roots[address] = account
-				}
-			}
-		}
-
-		return true, nil
-	}); err != nil {
-		panic(err)
-	}
-	for address, account := range roots {
-		if account != nil && account.Root != trie.EmptyRoot {
-			contractPrefix := make([]byte, common.HashLength+common.IncarnationLength)
-			addrHash, _ := common.HashData(address.Bytes())
-			copy(contractPrefix, addrHash[:])
-			binary.BigEndian.PutUint64(contractPrefix[common.HashLength:], account.Incarnation)
-			rl := trie.NewRetainList(0)
-			loader := trie.NewFlatDBTrieLoader("checkRoots")
-			if err := loader.Reset(rl, nil, nil, false); err != nil {
-				panic(err)
-			}
-			root, err1 := loader.CalcTrieRoot(tx, contractPrefix, nil)
-			if err1 != nil || root != account.Root {
-				fmt.Printf("%x: error %v, got hash %x, expected hash %x\n", addrHash, err1, root, account.Root)
-				template := `{"jsonrpc":"2.0","method":"debug_storageRangeAt","params":["0x%x", %d,"0x%x","0x%x",%d],"id":%d}`
-				sm := make(map[common.Hash]storageEntry)
-				nextKey := &common.Hash{}
-				for nextKey != nil {
-					reqID++
-					var sr DebugStorageRange
-					if err := post(client, url, fmt.Sprintf(template, blockHash, 0, address, *nextKey, 1024, reqID), &sr); err != nil {
-						fmt.Printf("Could not get storageRange: %v\n", err)
-						return
-					}
-					if sr.Error != nil {
-						fmt.Printf("Error getting storageRange: %d %s\n", sr.Error.Code, sr.Error.Message)
-						break
-					} else {
-						nextKey = sr.Result.NextKey
-						for k, v := range sr.Result.Storage {
-							sm[k] = v
-						}
-					}
-				}
-				fmt.Printf("Retrieved %d storage items from geth archive node\n", len(sm))
-				for key, entry := range sm {
-					var cKey [common.HashLength + common.IncarnationLength + common.HashLength]byte
-					copy(cKey[:], addrHash[:])
-					binary.BigEndian.PutUint64(cKey[common.HashLength:], account.Incarnation)
-					copy(cKey[common.HashLength+common.IncarnationLength:], key[:])
-					dbValue, _ := tx.GetOne(dbutils.HashedStorageBucket, cKey[:])
-					value := bytes.TrimLeft(entry.Value[:], "\x00")
-					if !bytes.Equal(dbValue, value) {
-						fmt.Printf("Key: %x, value: %x, dbValue: %x\n", key, value, dbValue)
-						if err := tx.Put(dbutils.HashedStorageBucket, cKey[:], value); err != nil {
-							fmt.Printf("%v\n", err)
-						}
-					}
-				}
-				var cKey [common.HashLength + common.IncarnationLength + common.HashLength]byte
-				copy(cKey[:], addrHash[:])
-				binary.BigEndian.PutUint64(cKey[common.HashLength:], account.Incarnation)
-				c2, err := tx.Cursor(dbutils.HashedStorageBucket)
-				if err != nil {
-					panic(err)
-				}
-				if err := ethdb.Walk(c, cKey[:], 8*(common.HashLength+common.IncarnationLength), func(k, v []byte) (bool, error) {
-					var kh common.Hash
-					copy(kh[:], k[common.HashLength+common.IncarnationLength:])
-					if _, ok := sm[kh]; !ok {
-						fmt.Printf("Key: %x, dbValue: %x\n", kh, v)
-						if err := tx.Delete(dbutils.HashedStorageBucket, k, nil); err != nil {
-							fmt.Printf("%v\n", err)
-						}
-					}
-					return true, nil
-				}); err != nil {
-					panic(err)
-				}
-				c2.Close()
-			}
-		}
-	}
-}
diff --git a/cmd/rpctest/rpctest/proofs.go b/cmd/rpctest/rpctest/proofs.go
deleted file mode 100644
index dd7eeb0f00d527fac7736965c5731251516465b8..0000000000000000000000000000000000000000
--- a/cmd/rpctest/rpctest/proofs.go
+++ /dev/null
@@ -1,167 +0,0 @@
-package rpctest
-
-import (
-	"context"
-	"fmt"
-	"os"
-
-	"github.com/ledgerwatch/erigon/ethdb"
-	"github.com/ledgerwatch/erigon/ethdb/kv"
-	"github.com/ledgerwatch/erigon/turbo/trie"
-)
-
-func Proofs(chaindata string, url string, block uint64) {
-	fileName := "trie.txt"
-	db := kv.MustOpen(chaindata)
-	defer db.Close()
-	tx, err1 := db.Begin(context.Background(), ethdb.RW)
-	if err1 != nil {
-		panic(err1)
-	}
-	defer tx.Rollback()
-
-	var t *trie.Trie
-	if _, errf := os.Stat(fileName); errf != nil {
-		if os.IsNotExist(errf) {
-			// Resolve 6 top levels of the accounts trie
-			rl := trie.NewRetainList(6)
-			loader := trie.NewFlatDBTrieLoader("checkRoots")
-			if err := loader.Reset(rl, nil, nil, false); err != nil {
-				panic(err)
-			}
-			root, err := loader.CalcTrieRoot(tx.(ethdb.HasTx).Tx().(ethdb.RwTx), []byte{}, nil)
-			if err != nil {
-				panic(err)
-			}
-			fmt.Printf("Resolved with hash: %x\n", root)
-			f, err1 := os.Create(fileName)
-			if err1 == nil {
-				defer f.Close()
-				t.Print(f)
-			} else {
-				panic(err1)
-			}
-			fmt.Printf("Saved trie to file\n")
-		} else {
-			panic(errf)
-		}
-	} else {
-		f, err1 := os.Open(fileName)
-		if err1 == nil {
-			defer f.Close()
-			var err2 error
-			t, err2 = trie.Load(f)
-			if err2 != nil {
-				panic(err2)
-			}
-			fmt.Printf("Restored from file with hash: %x\n", t.Hash())
-		} else {
-			panic(err1)
-		}
-	}
-	/* TODO: migrate to usage cursors api - and to not use preimages
-	var client = &http.Client{
-		Timeout: time.Second * 600,
-	}
-	reqID := 0
-
-	level := 0
-	diffKeys := [][]byte{{}}
-	var newDiffKeys [][]byte
-	for len(diffKeys) > 0 && level < 6 {
-
-		fmt.Printf("================================================\n")
-		fmt.Printf("LEVEL %d, diffKeys: %d\n", level, len(diffKeys))
-		fmt.Printf("================================================\n")
-		for _, diffKey := range diffKeys {
-			// Find account with the suitable hash
-			var startKey common.Hash
-			for i, d := range diffKey {
-				if i%2 == 0 {
-					startKey[i/2] |= (d << 4)
-				} else {
-					startKey[i/2] |= d
-				}
-			}
-			var account common.Address
-			var found bool
-			err := tx.Walk(dbutils.PreimagePrefix, startKey[:], 4*len(diffKey), func(k, v []byte) (bool, error) {
-				if len(v) == common.AddressLength {
-					copy(account[:], v)
-					found = true
-					return false, nil
-				}
-				return true, nil
-			})
-			if err != nil {
-				fmt.Printf("Error when looking for suitable account for diffKey %x\n", diffKey)
-				return
-			}
-			if !found {
-				fmt.Printf("Could not find suitable account for diffKey %x\n", diffKey)
-				return
-			}
-			reqID++
-			template := `{"jsonrpc":"2.0","method":"eth_getProof","params":["0x%x",[],"0x%x"],"id":%d}`
-			var proof EthGetProof
-			if err = post(client, url, fmt.Sprintf(template, account, block, reqID), &proof); err != nil {
-				fmt.Printf("Could not get block number: %v\n", err)
-				return
-			}
-			if proof.Error != nil {
-				fmt.Printf("Error retrieving proof: %d %s\n", proof.Error.Code, proof.Error.Message)
-				return
-			}
-			if len(proof.Result.AccountProof) <= len(diffKey) {
-				fmt.Printf("RPC result needs to be at least %d levels deep\n", len(diffKey)+1)
-				return
-			}
-			p := proof.Result.AccountProof[len(diffKey)]
-			b := common.FromHex(p)
-			h := common.BytesToHash(crypto.Keccak256(b))
-			hE, err := t.HashOfHexKey(diffKey)
-			if err != nil {
-				fmt.Printf("Error computing partial hash for %x: %v\n", diffKey, err)
-				return
-			}
-			if h != hE {
-				fmt.Printf("key %x: %x %x adding nibbles: ", diffKey, h, hE)
-				var branch [17][]byte
-				err = rlp.DecodeBytes(b, &branch)
-				if err != nil {
-					fmt.Printf("Error decoding: %v\n", err)
-					fmt.Printf("%s\n", p)
-				}
-				// Expand keys further
-				for nibble := byte(0); nibble < 16; nibble++ {
-					newDiff := make([]byte, len(diffKey)+1)
-					copy(newDiff, diffKey)
-					newDiff[len(diffKey)] = nibble
-					var proofHash common.Hash
-					copy(proofHash[:], branch[nibble])
-					if proofHash != (common.Hash{}) || err != nil {
-						newHash, err := t.HashOfHexKey(newDiff)
-						if err != nil {
-							fmt.Printf("Error computing partial hash for %x: %v\n", newDiff, err)
-						}
-						if proofHash != newHash {
-							newDiffKeys = append(newDiffKeys, newDiff)
-							fmt.Printf("%x", nibble)
-						}
-					}
-				}
-				fmt.Printf("\n")
-			} else {
-				fmt.Printf("MATCH key %x: %x %x\n", diffKey, h, hE)
-			}
-		}
-		diffKeys = newDiffKeys
-		newDiffKeys = nil
-		level++
-	}
-	fmt.Printf("\n\nRESULT:\n")
-	for _, diffKey := range diffKeys {
-		fmt.Printf("%x\n", diffKey)
-	}
-	*/
-}